文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

自定义input组件怎么实现拖拽文件上传

2023-07-05 17:21

关注

这篇“自定义input组件怎么实现拖拽文件上传”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“自定义input组件怎么实现拖拽文件上传”文章吧。

自定义input组件实现拖拽文件上传

vue部分

<tag-input id="uploadTag" ref="uploadTag" v-model="fileNameList" size="small" @input="removeFile"></tag-input>

逻辑部分

页面加载时监听拖拽事件,监听后将文件放置下发fileList参数列表中

  mounted() {    setTimeout(() => {      this.$nextTick(() => {        if (this.$refs.uploadTag) {          let dropEle = this.$refs.uploadTag.$el           // 禁止拖拽文件后打开文件          dropEle.addEventListener('drop', e => {            e.preventDefault();            e.stopPropagation();          }, false)           dropEle.addEventListener('dragover', e => {            e.preventDefault();            e.stopPropagation();          }, false)           dropEle.addEventListener('dragleave', e => {            e.preventDefault();            e.stopPropagation();          }, false)           // 处理拖拽文件的逻辑          dropEle.addEventListener('drop', e => this.watchFileUpload(e))        }      })    }, 1000)  }
  // 拖拽上传  private watchFileUpload(e) {    e.preventDefault();    e.stopPropagation();     var df = e.dataTransfer;    var dropFiles = []; // 拖拽的文件,会放到这里    var dealFileCnt = 0; // 读取文件是个异步的过程,需要记录处理了多少个文件了    var allFileLen = df.files.length; // 所有的文件的数量,给非Chrome浏览器使用的变量     // 检测是否已经把所有的文件都遍历过了    function checkDropFinish() {      dealFileCnt++;    }     if (df.items !== undefined) {      // Chrome拖拽文件逻辑      for (var i = 0; i < df.items.length; i++) {        var item = df.items[i];        if (item.kind === "file" && item.webkitGetAsEntry().isFile) {          var file = item.getAsFile();          dropFiles.push(file);        }      }    } else {      // 非Chrome拖拽文件逻辑      for (var i = 0; i < allFileLen; i++) {        var dropFile = df.files[i];        if (dropFile.type) {          dropFiles.push(dropFile);          checkDropFinish();        } else {          try {            var fileReader = new FileReader();            fileReader.readAsDataURL(dropFile.slice(0, 3));             fileReader.addEventListener('load', function (e) {              console.log(e, 'load');              dropFiles.push(dropFile);              checkDropFinish();            }, false);             fileReader.addEventListener('error', function (e) {              console.log(e, 'error,不可以上传文件夹');              checkDropFinish();            }, false);           } catch (e) {            console.log(e, 'catch error,不可以上传文件夹');            checkDropFinish();          }        }      }    }    dropFiles.forEach(item => {      this.fileList.push(item)    })    this.fileNameList = this.fileList.map(item => {      if (item.name) {        return item.name      }      if (item.fileName) {        return item.fileName      }    });  }

删除当前文件

  // 附件删除 下拉框  private removeFile(nameList, name) {    // 记录删除的附件信息    this.fileList.splice(this.fileList.findIndex(item => item.fileName === name || item.name === name), 1)    this.fileNameList = this.fileList.map(item => item.name || item.fileName);  }

封装的tag-input组件

<template>  <div    class="yh-input-tag input-tag-wrapper"    ref="InputTag"    @click="foucusTagInput"  >    <el-tag      v-for="(tag, idx) in innerTags"      :key="tag"      :size="size"      :closable="!readonly"      :disable-transitions="false"      @close="remove(tag, idx)"      >{{ tag }}</el-tag    >    <input      :readonly="readonly || readonlyIpt"      class="tag-input"      :class="[size ? 'yh-input-tag--' + size : '']"      :      :placeholder="isplaceholder"      v-model="newTag"      @keydown.delete.stop="removeLastTag"      @keydown="addNew"      @blur="blurTagInput"    />  </div></template> <script> export default {  name: 'InputTag',  props: {    value: {      type: Array,      default: () => []    },    addTagOnKeys: {      type: Array,      default: () => [13, 188, 9]    },    readonly: {      type: Boolean,      default: false    },    // 输入框只读    readonlyIpt: {      type: Boolean,      default: false    },    size: String,    placeholder: {      type: String,      default: '请输入'    }  },  inject: {    elForm: {      default: ''    },    elFormItem: {      default: ''    }  },  data () {    return {      newTag: '',      innerTags: [...this.value],      currentTag: null,      widthStyle: {        minWidth: '10px'      }    }  },  computed: {    isplaceholder () {      let str = ''      if(this.value?.length > 0) {        this.$nextTick(() => {          if (this.$refs.yhInputTag) {            this.$refs.InputTag.style.padding = '0'          }        })        str = ''      } else {        this.$nextTick(() => {          if (this.$refs.yhInputTag) {            this.$refs.InputTag.style.padding = '0 15px'          }        })        str = this.placeholder      }      return str    },    // 表单禁用关联    inputDisabled() {      return this.disabled || (this.elForm || {}).disabled;    }  },  watch: {    value: {      handler(newVal, oldVal) {        if (this.elForm && oldVal !== undefined && newVal !== oldVal) {          this.elForm.validateField(this.elFormItem.prop)        }        if (newVal) {          this.innerTags = [...newVal]        }      },      deep: true,      immediate: true    }  },  methods: {    foucusTagInput () {      if (this.readonly || this.readonlyIpt || !this.$el.querySelector('.tag-input')) {        return      } else {        this.$el.querySelector('.tag-input').focus()        this.widthStyle = {          minWidth: '10px'        }      }    },    blurTagInput (e) {      this.addNew(e)      this.widthStyle = {        width: '0px'      }    },    addNew (e) {      if (e && (!this.addTagOnKeys.includes(e.keyCode)) && (e.type !== 'blur')) {        return      }      if (e) {        e.stopPropagation()        e.preventDefault()      }      let addSuucess = false      if (this.newTag.includes(',')) {        this.newTag.split(',').forEach(item => {        if (this.addTag(item.trim())) {            addSuucess = true          }        })      } else {        if (this.addTag(this.newTag.trim())) {          addSuucess = true        }      }      if (addSuucess) {        this.tagChange()        this.newTag = ''      }    },    addTag (tag) {      tag = tag.trim()      if (tag && !this.innerTags.includes(tag)) {        this.innerTags.push(tag)        return true      }      return false    },    remove (tag, index) {      this.innerTags.splice(index, 1)      this.currentTag = tag      this.tagChange()    },    removeLastTag () {      if (this.newTag) {        return      }      this.innerTags.pop()      this.tagChange()    },    tagChange () {      this.$forceUpdate()      this.$emit('input', JSON.parse(JSON.stringify(this.innerTags)), this.currentTag)    }  }}</script> <style scoped>.input-tag-wrapper {  position: relative;  font-size: 14px;  background-color: #fff;  background-image: none;  border-radius: 4px;  border: 1px solid #DCDFE6;  box-sizing: border-box;  color: #575757;  display: inline-block;  cursor: text;  outline: none;  padding: 0 15px;  transition: border-color .2s cubic-bezier(.645,.045,.355,1);  width: 100%;  line-height: normal;  &:hover{    border-color: #C5C6C7;  }  &:focus{    border-color: #d32f2f;  }  .el-tag{    box-sizing: border-box;    border-color: transparent;    margin: 2px 0 2px 6px;    background-color: #f0f2f5;    display: inline-flex;    max-width: 100%;    align-items: center;  }} .tag-input {  background: transparent;  border: 0;  font-size: 14px;  outline: none;  padding-left: 0;  height: 26px;  &::placeholder {    color: #C8C9CA;  }}.yh-input-tag--mini{  height: 26px;  line-height: 26px;  .tag {    height: 16px;  }} .yh-input-tag--small{  height: 30px;  line-height: 30px;  .tag {    height: 20px;  }} .yh-input-tag--medium{  height: 34px;  line-height: 34px;  .tag {    height: 24px;  }} // 表单标签选择器必填样式.el-form-item.is-error .input-tag-wrapper,.el-form-item.is-error .input-tag-wrapper:focus {  border-color: #bc1126 !important;}</style>

最后实现的效果

自定义input组件怎么实现拖拽文件上传

可支持手动拖拽上传 

多图上传组件vue

组件template部分

多图上传按钮+多图上传弹窗+图片上的预览删除图标

<template><div>    <div class="many">      <el-form-item>        <div class="upload-item">          <el-button type="primary" @click="uploadFile">多图上传</el-button>        </div>      </el-form-item>    </div>  <el-dialog title="图片预览" :visible.sync="dialogImgVisible" width="50%">    <img :src="dialogImageUrl" alt="" class="previewImg" />  </el-dialog>  <!--多图上传弹窗界面--><el-dialog :title="'上传'" :visible.sync="dialogFormVisible" custom-class="pub_dialog" >  <el-form >    <!--内容部分  -->    <el-form-item><!---->        <div >          <label>选择文件:</label>          <div>            <div class="desc">支持 jpg, png 图片格式,且不超过500kb</div>            <el-upload                :action="UPLOAD_URL"                :headers="authorToken"                :auto-upload="true"                accept="image/jpg,image/png,image/jpeg"                :on-success="handleSuccess"                :before-upload="handleBeforeUpload"                :show-file-list="false"                multiple                :limit="10"                :on-exceed="handleExceed"                :file-list="fileList">              <el-button size="small" type="primary">上传图片</el-button>            </el-upload>          </div>        </div>          <div class="fileList" >            <div class="item" v-for="(item,index) in images" :key="index">              <img :src="item.url" alt="" :key="index"  class = "imgList">              <div class="scissor-icon">                <i class="el-icon-scissors" @click="changeFile(item)"></i>              </div>              <div class="delete-icon">                <i class="el-icon-delete" @click="handleRemove(item)"></i>              </div>              <div class="search-icon">                <i class="el-icon-search" @click="handlePreview(item)"></i>              </div>              <el-input                  type="textarea"                  :autosize="{ minRows: 7, maxRows: 7}"                  placeholder="请输入图片描述"                  v-model="item.manyDescription"                  :key="index"                  >              </el-input>            </div>          </div>    </el-form-item>  </el-form>  <div slot="footer" class="dialog-footer">    <el-button @click="dialogFormVisible = false">取 消</el-button>    <el-button type="primary" @click="closeDialog">确 定</el-button>  </div></el-dialog></div></template>

组件script部分

变量数据区域

代码如下(示例):

<script>export default {  name: "UploadMany",  data() {    return {      textarea:'',      dialogImageUrl: '',      dialogImgVisible: false,      dialogVisible: false,      fileList: [],      imgs: [],      images: [],      UPLOAD_URL: "/v1/admin/common/upload",//这里填写你的后端上传接口地址      authorToken: {        Authorization: 'Bearer ' + sessionStorage.getItem("token"),        siteId:sessionStorage.getItem("siteId")      },      param: {        token: ''      },      fileNum: 0,      num: 0,      dialogFormVisible: false,//添加表单弹出框是否显示      dialogChangeVisible: false,      picsList: [],  //页面显示的数组      // 防止重复提交      loading: true,    }  },

方法区域

代码如下(示例):

methods: {//删除方法    handleRemove(file) {      console.log(file)      // 1.获取将要删除的图片的临时路径      const filePath = file.url      // 2.从数组中,找到这个图片对应的索引值      const i = this.imgs.findIndex((x) => x.url === filePath)      // 3.调用数组的 splice 方法,把图片信息对象,从 pics 数组中移除      this.imgs.splice(i, 1)      console.log(this.imgs)    },    //预览方法    handlePreview(file) {      console.log(file);      this.dialogImageUrl = file.url;      this.dialogImgVisible = true;    },    //限制上传文件个数    handleExceed(files, fileList) {      this.$message.warning(`当前限制选择 10 个文件,本次选择了 ${files.length} 个文件,共选择了 ${files.length + fileList.length} 个文件`);    },    //上传成功后    handleSuccess(response, fileList) {      console.log(response);      console.log(fileList)      this.loading = false      if(response.code === 200){        this.imgs.push({name: response.data.resourceName, url: response.data.resourceUrl, manyDescription: '', manyResourceId: response.data.id})        this.num++;        if(this.num == this.fileNum){          for(let i = 0; i < this.num ; i++){            this.$emit('getManyImg', this.imgs[i])          }          this.num = 0;          this.fileNum = 0;          this.images = this.imgs;          this.imgs = [];        }      }else{        this.$message.error('上传失败');      }    },        handleBeforeUpload(file) {      // 这里做可以做文件校验操作      const isImg = /^image\/\w+$/i.test(file.type)      if (!isImg && this.fileType == 'image/*') {        this.$message.error('只能上传 JPG、PNG、GIF 格式!')        return false      }      this.fileNum++;    },    uploadFile(){      this.dialogFormVisible = true;      this.loading = false;    },        closeDialog(){      this.dialogFormVisible = false;      this.imgs = [];      this.images = [];    }  }}

组件使用

在你需要用到的界面vue里导入组件

import UploadMany from '@/components/upload/UploadMany';import {getToken} from '@/utils/auth';export default {  name: "TestEditor",  components: {    UploadMany,  },

template部分使用组件

            <el-col :span="24">              <el-form-item prop="manyImg" label="多图上传:" :label-width="imgWidth" class="form">                <upload-many v-model="dialogForm.manyImg" @getManyImg="getManyImg" ></upload-many>                <div class="fileList" >                  <div class="item" v-for="(itemPhoto,indexPhoto) in dialogForm.images" :key="indexPhoto">                    <div class="item-left" >                      <img :src="itemPhoto.url" alt="" :key="indexPhoto" class = "imgList">                     <div class="item-bottom">                       <div class="search-icon">                         <i class="el-icon-search" @click="handlePreview(itemPhoto)"></i>                       </div>                       <div class="delete-icon">                         <i class="el-icon-delete" @click="handleRemove(itemPhoto)"></i>                       </div>                     </div>                    </div>                    <el-input                        type="textarea"                        :autosize="{ minRows: 7, maxRows: 7}"                        placeholder="请输入图片描述"                        v-model="itemPhoto.manyDescription"                        >                    </el-input>                  </div>                </div>              </el-form-item>            </el-col>

方法部分

    getManyImg(imgs) {      this.dialogForm.images.push(imgs);      console.log(this.dialogForm.images)    },        handleRemove(file) {      console.log(file)      // 1.获取将要删除的图片的临时路径      const filePath = file.url      // 2.从数组中,找到这个图片对应的索引值      const i = this.dialogForm.images.findIndex((x) => x.url === filePath)      // 3.调用数组的 splice 方法,把图片信息对象,从 pics 数组中移除      this.dialogForm.images.splice(i, 1)    },    //预览图片    handlePreview(file) {      console.log(file);      this.dialogImageUrl = file.url;      this.dialogImgVisible = true;    },

组件完整代码(含裁剪组件,不需要请手动删除)

<template><div>    <div class="many">      <el-form-item>        <div class="upload-item">          <el-button type="primary" @click="uploadFile">多图上传</el-button>        </div>      </el-form-item>    </div>  <!--裁剪弹窗-->  <!-- vueCropper 剪裁图片实现-->  <el-dialog title="图片剪裁" :visible.sync="dialogChangeVisible" append-to-body>    <div class="cropper-content">      <div class="cropper" >        <vueCropper            ref="cropper"            :img="option.img"            :outputSize="option.size"            :outputType="option.outputType"            :info="true"            :full="option.full"            :canMove="option.canMove"            :canMoveBox="option.canMoveBox"            :original="option.original"            :autoCrop="option.autoCrop"            :fixed="option.fixed"            :fixedNumber="option.fixedNumber"            :centerBox="option.centerBox"            :infoTrue="option.infoTrue"            :fixedBox="option.fixedBox"        ></vueCropper>      </div>    </div>    <div slot="footer" class="dialog-footer">      <el-button @click="dialogChangeVisible = false">取 消</el-button>      <el-button type="primary" @click="finish" :loading="loading">确认</el-button>    </div>  </el-dialog>  <el-dialog title="图片预览" :visible.sync="dialogImgVisible" width="50%">    <img :src="dialogImageUrl" alt="" class="previewImg" />  </el-dialog>  <!--多图上传弹窗界面--><el-dialog :title="'上传'" :visible.sync="dialogFormVisible" custom-class="pub_dialog" >  <el-form >    <!--内容部分  -->    <el-form-item><!---->        <div >          <label>选择文件:</label>          <div>            <div class="desc">支持 jpg, png 图片格式,且不超过500kb</div>            <el-upload                :action="UPLOAD_URL"                :headers="authorToken"                :auto-upload="true"                accept="image/jpg,image/png,image/jpeg"                :on-success="handleSuccess"                :before-upload="handleBeforeUpload"                :show-file-list="false"                multiple                :limit="10"                :on-exceed="handleExceed"                :file-list="fileList">              <el-button size="small" type="primary">上传图片</el-button>            </el-upload>          </div>        </div>          <div class="fileList" >            <div class="item" v-for="(item,index) in images" :key="index">              <img :src="item.url" alt="" :key="index"  class = "imgList">              <div class="scissor-icon">                <i class="el-icon-scissors" @click="changeFile(item)"></i>              </div><!--                <div class="refresh-icon">--><!--                  <i class="el-icon-refresh" @click="handleRemove()"></i>--><!--                </div>-->              <div class="delete-icon">                <i class="el-icon-delete" @click="handleRemove(item)"></i>              </div>              <div class="search-icon">                <i class="el-icon-search" @click="handlePreview(item)"></i>              </div>              <el-input                  type="textarea"                  :autosize="{ minRows: 7, maxRows: 7}"                  placeholder="请输入图片描述"                  v-model="item.manyDescription"                  :key="index"                  >              </el-input>            </div>          </div>    </el-form-item>  </el-form>  <div slot="footer" class="dialog-footer">    <el-button @click="dialogFormVisible = false">取 消</el-button>    <el-button type="primary" @click="closeDialog">确 定</el-button>  </div></el-dialog></div></template><script>import VueCropper from 'vue-cropper'import Vue from "vue";Vue.use(VueCropper)export default {  name: "UploadMany",  data() {    return {      textarea:'',      dialogImageUrl: '',      dialogImgVisible: false,      dialogVisible: false,      fileList: [],      imgs: [],      images: [],      UPLOAD_URL: "/v1/admin/common/upload",      authorToken: {        Authorization: 'Bearer ' + sessionStorage.getItem("token"),        siteId:sessionStorage.getItem("siteId")      },      param: {        token: ''      },      fileNum: 0,      num: 0,      dialogFormVisible: false,//添加表单弹出框是否显示      dialogChangeVisible: false,      // 裁剪组件的基础配置option      option: {        img: '', // 裁剪图片的地址        info: true, // 裁剪框的大小信息        outputSize: 0.8, // 裁剪生成图片的质量        outputType: 'jpeg', // 裁剪生成图片的格式        canScale: false, // 图片是否允许滚轮缩放        autoCrop: true, // 是否默认生成截图框        // autoCropWidth: 300, // 默认生成截图框宽度        // autoCropHeight: 200, // 默认生成截图框高度        fixedBox: true, // 固定截图框大小 不允许改变        fixed: true, // 是否开启截图框宽高固定比例        fixedNumber: [7, 5], // 截图框的宽高比例        full: true, // 是否输出原图比例的截图        canMoveBox: false, // 截图框能否拖动        original: false, // 上传图片按照原始比例渲染        centerBox: false, // 截图框是否被限制在图片里面        infoTrue: true // true 为展示真实输出图片宽高 false 展示看到的截图框宽高      },      picsList: [],  //页面显示的数组      // 防止重复提交      loading: true,    }  },  methods: {    handleRemove(file) {      console.log(file)      // 1.获取将要删除的图片的临时路径      const filePath = file.url      // 2.从数组中,找到这个图片对应的索引值      const i = this.imgs.findIndex((x) => x.url === filePath)      // 3.调用数组的 splice 方法,把图片信息对象,从 pics 数组中移除      this.imgs.splice(i, 1)      console.log(this.imgs)    },    handlePreview(file) {      console.log(file);      this.dialogImageUrl = file.url;      this.dialogImgVisible = true;    },    handleExceed(files, fileList) {      this.$message.warning(`当前限制选择 10 个文件,本次选择了 ${files.length} 个文件,共选择了 ${files.length + fileList.length} 个文件`);    },    handleSuccess(response, fileList) {      console.log(response);      console.log(fileList)      this.loading = false      if(response.code === 200){        this.imgs.push({name: response.data.resourceName, url: response.data.resourceUrl, manyDescription: '', manyResourceId: response.data.id})        this.num++;        if(this.num == this.fileNum){          for(let i = 0; i < this.num ; i++){            this.$emit('getManyImg', this.imgs[i])          }          this.num = 0;          this.fileNum = 0;          this.images = this.imgs;          this.imgs = [];        }      }else{        this.$message.error('上传失败');      }    },    // 裁剪按钮   限制图片大小    changeFile(file) {      console.log(file)      this.option.img = file.url      console.log(this.option.img)      this.dialogChangeVisible = true    },    // 点击裁剪    finish() {      this.$refs.cropper.getCropBlob((data) => {        console.log(data)        console.log(data.size)        this.$data.dialogChangeVisible = false        this.axios.post("/v1/admin/common/upload",data).then((res) => {          let code = res.data.code;          if (code == 200) {            this.$data.dialogFormVisible = false            this.$message.success("上传成功");          }        }).catch((error) => {          console.log(error);        });      })    },    handleBeforeUpload(file) {      // 这里做可以做文件校验操作      const isImg = /^image\/\w+$/i.test(file.type)      if (!isImg && this.fileType == 'image/*') {        this.$message.error('只能上传 JPG、PNG、GIF 格式!')        return false      }      this.fileNum++;    },    uploadFile(){      this.dialogFormVisible = true;      this.loading = false;    },    closeDialog(){      this.dialogFormVisible = false;      this.imgs = [];      this.images = [];    }  }}</script><style lang="scss" scoped>.el-dialog{  width: 50%;}.item {  width: 300px;  height: 140px;  position: relative;  display: flex;  margin: 10px;  .delete-icon {    display: none;  }  .refresh-icon {    display: none;  }  .search-icon {    display: none;  }  .scissor-icon {    display: none;  }  &:hover {    .scissor-icon {      display: block;      position: absolute;      width: 35px;      height: 40px;      line-height: 40px;      left: 100px;      top: 100px;      background: rgba(59, 60, 61, 0.5);      // box-sizing: content-box;      z-index: 999;      cursor: pointer;      text-align: center;      i {        margin: 8px 10px 0 0;        display: block;        font-size: 24px;        color: white;      }    }    .delete-icon {      display: block;      position: absolute;      width: 35px;      height: 40px;      left: 0px;      top: 100px;      background: rgba(59, 60, 61, 0.5);      // box-sizing: content-box;      z-index: 999;      cursor: pointer;      text-align: center;      i {        margin: 8px 10px 0 10px;        display: block;        font-size: 24px;        color: white;      }    }    .refresh-icon {      display: block;      position: absolute;      width: 35px;      height: 40px;      left: 35px;      top: 100px;      background: rgba(59, 60, 61, 0.5);      // box-sizing: content-box;      z-index: 999;      cursor: pointer;      text-align: center;      i {        margin: 8px 10px 0 0;        display: block;        font-size: 24px;        color: white;      }    }    .search-icon {      display: block;      position: absolute;      width: 65px;      height: 40px;      left: 35px;      top: 100px;      background: rgba(59, 60, 61, 0.5);      // box-sizing: content-box;      z-index: 999;      cursor: pointer;      text-align: center;      i {        margin: 8px 10px 0 10px;        display: block;        font-size: 24px;        color: white;      }    }  }}.imgList {  border: 1px dashed #d9d9d9;  border-radius: 5px;  box-sizing: border-box;  width: 180px;  height: 180px;  margin-top: 0px;&:hover {   border: 1px dashed #409eff; }}// 截图.cropper-content {  .cropper {    width: auto;    height: 300px;  }}.previewImg {  width: 50%;  height: 100%}</style>

效果展示

自定义input组件怎么实现拖拽文件上传

以上就是关于“自定义input组件怎么实现拖拽文件上传”这篇文章的内容,相信大家都有了一定的了解,希望小编分享的内容对大家有帮助,若想了解更多相关的知识内容,请关注编程网行业资讯频道。

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     807人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     351人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     314人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     433人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     221人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯