欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

自定義input組件如何實現(xiàn)拖拽文件上傳

 更新時間:2023年03月28日 15:23:02   作者:zhlCool  
這篇文章主要介紹了自定義input組件如何實現(xiàn)拖拽文件上傳問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教

自定義input組件實現(xiàn)拖拽文件上傳

vue部分

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

邏輯部分

頁面加載時監(jiān)聽拖拽事件,監(jiān)聽后將文件放置下發(fā)fileList參數(shù)列表中

  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; // 所有的文件的數(shù)量,給非Chrome瀏覽器使用的變量
 
    // 檢測是否已經(jīng)把所有的文件都遍歷過了
    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 : '']"
      :style="widthStyle"
      :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
    },
    // 表單禁用關聯(lián)
    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>

最后實現(xiàn)的效果

可支持手動拖拽上傳 

多圖上傳組件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 style="width: 750px;height: 380px">
    <!--內容部分  -->
    <el-form-item><!---->
        <div style="display: flex;justify-content: center">
          <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" style="margin-top: 10px;display: flex;flex-wrap: wrap;">
            <div class="item" v-for="(item,index) in images" :key="index">
              <img :src="item.url" alt="" :key="index" style=" width: 45%;height: 100%" 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"
                  style=" width: 55%;height: 100%;margin-left: 10px">
              </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部分

1.變量數(shù)據(jù)區(qū)域

代碼如下(示例):

<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: [],  //頁面顯示的數(shù)組
      // 防止重復提交
      loading: true,
    }
  },

2.方法區(qū)域

代碼如下(示例):

methods: {
	//刪除方法
    handleRemove(file) {
      console.log(file)
      // 1.獲取將要刪除的圖片的臨時路徑
      const filePath = file.url
      // 2.從數(shù)組中,找到這個圖片對應的索引值
      const i = this.imgs.findIndex((x) => x.url === filePath)
      // 3.調用數(shù)組的 splice 方法,把圖片信息對象,從 pics 數(shù)組中移除
      this.imgs.splice(i, 1)
      console.log(this.imgs)
    },
    //預覽方法
    handlePreview(file) {
      console.log(file);
      this.dialogImageUrl = file.url;
      this.dialogImgVisible = true;
    },
    //限制上傳文件個數(shù)
    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 = [];
    }

  }
}

組件使用

1.在你需要用到的界面vue里導入組件

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

2.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" style="margin-top: 10px;display: flex;flex-wrap: wrap;">
                  <div class="item" v-for="(itemPhoto,indexPhoto) in dialogForm.images" :key="indexPhoto">
                    <div class="item-left" style="position: relative">
                      <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"
                        style=" width: 55%;height: 100%;margin-left: 10px">
                    </el-input>
                  </div>
                </div>
              </el-form-item>
            </el-col>

3.方法部分

    getManyImg(imgs) {
      this.dialogForm.images.push(imgs);
      console.log(this.dialogForm.images)
    },
        handleRemove(file) {
      console.log(file)
      // 1.獲取將要刪除的圖片的臨時路徑
      const filePath = file.url
      // 2.從數(shù)組中,找到這個圖片對應的索引值
      const i = this.dialogForm.images.findIndex((x) => x.url === filePath)
      // 3.調用數(shù)組的 splice 方法,把圖片信息對象,從 pics 數(shù)組中移除
      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 剪裁圖片實現(xiàn)-->
  <el-dialog title="圖片剪裁" :visible.sync="dialogChangeVisible" append-to-body>
    <div class="cropper-content">
      <div class="cropper" style="text-align:center">
        <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 style="width: 750px;height: 380px">
    <!--內容部分  -->
    <el-form-item><!---->
        <div style="display: flex;justify-content: center">
          <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" style="margin-top: 10px;display: flex;flex-wrap: wrap;">
            <div class="item" v-for="(item,index) in images" :key="index">
              <img :src="item.url" alt="" :key="index" style=" width: 45%;height: 100%" 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"
                  style=" width: 55%;height: 100%;margin-left: 10px">
              </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: [],  //頁面顯示的數(shù)組
      // 防止重復提交
      loading: true,
    }
  },
  methods: {
    handleRemove(file) {
      console.log(file)
      // 1.獲取將要刪除的圖片的臨時路徑
      const filePath = file.url
      // 2.從數(shù)組中,找到這個圖片對應的索引值
      const i = this.imgs.findIndex((x) => x.url === filePath)
      // 3.調用數(shù)組的 splice 方法,把圖片信息對象,從 pics 數(shù)組中移除
      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>

效果展示

總結

以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。

相關文章

  • vue使用watch 觀察路由變化,重新獲取內容

    vue使用watch 觀察路由變化,重新獲取內容

    本篇文章主要介紹了vue使用watch 觀察路由變化,重新獲取內容 ,具有一定的參考價值,感興趣的小伙伴們可以參考一下。
    2017-03-03
  • Vue組件封裝方案實現(xiàn)淺析

    Vue組件封裝方案實現(xiàn)淺析

    這篇文章主要介紹了Vue組件封裝方案實現(xiàn),我們將從分析組件封裝的優(yōu)勢開始,然后依次介紹 vue.js 的基本概念,以及如何創(chuàng)建、封裝和使用自定義組件
    2023-03-03
  • Vue2中配置Cesium全過程

    Vue2中配置Cesium全過程

    這篇文章主要介紹了Vue2中配置Cesium全過程,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-05-05
  • 詳解vue中axios請求的封裝

    詳解vue中axios請求的封裝

    這篇文章主要介紹了vue中axios請求的封裝,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2019-04-04
  • vue-cli 使用axios的操作方法及整合axios的多種方法

    vue-cli 使用axios的操作方法及整合axios的多種方法

    這篇文章主要介紹了vue-cli 使用axios的操作方法及整合axios的多種方法,vue-cli整合axios的多種方法,小編一一給大家列出來了,大家根據(jù)自身需要選擇,需要的朋友可以參考下
    2018-09-09
  • Vue使用v-viewer插件實現(xiàn)圖片預覽和縮放和旋轉等功能(推薦)

    Vue使用v-viewer插件實現(xiàn)圖片預覽和縮放和旋轉等功能(推薦)

    v-viewer是一個基于viewerjs封裝的vue圖片預覽組件,有預覽縮放拉伸旋轉切換拖拽等功能,支持配置化,這篇文章主要介紹了Vue使用v-viewer插件實現(xiàn)圖片預覽和縮放和旋轉等功能,需要的朋友可以參考下
    2023-02-02
  • 如何在 Vue 表單中處理圖片

    如何在 Vue 表單中處理圖片

    這篇文章主要介紹了如何在 Vue 表單中處理圖片,幫助大家更好的理解和使用vue框架,感興趣的朋友可以了解下
    2021-01-01
  • TypeScript在vue中的使用解讀

    TypeScript在vue中的使用解讀

    這篇文章主要介紹了TypeScript在vue中的使用方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-02-02
  • Vue前端打包的詳細流程

    Vue前端打包的詳細流程

    這篇文章主要介紹了Vue前端打包的詳細流程,下面文章圍繞Vue前端打包的相關資料展開詳細內容,需要的小伙伴可以參考一下,希望對大家有所幫助
    2021-11-11
  • 解決vue admin element noCache設置無效的問題

    解決vue admin element noCache設置無效的問題

    今天小編就為大家分享一篇解決vue admin element noCache設置無效的問題,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2019-11-11

最新評論