vue3+Element Plus 图片上传组件,支持微信粘贴上传图片

文档结构

完整代码

App.vue文件

<script setup>
import Home from '@/components/ImageUpload.vue'
import { ref } from 'vue';
let show=ref(false)
</script>

<template>
    <button @click="show=!show">显示</button>
<Home v-model:display="show"></Home>
</template>
说明:

   ImageUpload 组件引入收需要传入一个 display 参数,用于控制组件的显示隐藏

ImageUpload.vue文件

<script>
import { ref, computed, watch } from 'vue'
// import { UploadFilled } from '@element-plus/icons-vue'
// import {upImg} from '@/api/ImagesUpload'

export default {
  props: {
    display: Boolean
  },

  setup(props, context) {

    //图片base64
    let imgBase64 = ref('')

    //上传图片
    function uploadImage(file) {
      const isImage = file.type.startsWith('image/')
      if (!isImage) {
        ElMessage({
          message: '只可以上传图片',
          type: 'warning',
        })
        return isImage
      }
      convertToBase64(file, async (base64String) => {
        //发送请求
        putImg(base64String)
      })
      return false
    }

    //转化图片为base64
    function convertToBase64(file, callback) {
      const reader = new FileReader()
      reader.onload = (event) => {
        callback(event.target.result)
      }
      reader.readAsDataURL(file)
    }

    //监听剪切板函数
    function handlePaste(event) {
      const items = (event.clipboardData || window.clipboardData).items;
      let file = null;

      if (!items || items.length === 0) {
        ElMessage({
          message: '当前浏览器不支持本地',
          type: 'error',
        })
        return;
      }

      // 搜索剪切板items
      for (let i = 0; i < items.length; i++) {
        if (items[i].type.indexOf("image") !== -1) {
          file = items[i].getAsFile();
          break;
        }
      }
      if (!file) {
        ElMessage({
          message: '粘贴内容非图片',
          type: 'warning',
        })
        return;
      }
      convertToBase64(file, (base64Str) => {
        putImg(base64Str)
      })
    }

    //发送请求
    function putImg(base64Str) {
      imgBase64.value = base64Str
      const loading = ElLoading.service({
        lock: true,
        text: 'Loading',
        background: 'rgba(0, 0, 0, 0.7)',
      })
      //发送请求(此方法应该自己定义)
      upImg({
        image_base64: base64Str
      })
        .then((res) => {
          // 处理异常情况
          if (!res.success) {
            ElMessage({
              message: res.error_message,
              type: 'error',
            })
            return
          }
          //成功响应
          loading.close()
        })
        .catch((error) => {
          // 处理错误
          ElMessage({
            message: '识别失败,请重新上传',
            type: 'error',
          })
          console.error(error)
          loading.close()
        })
    }

    //初始化
    function init() {
      imgBase64.value = ''
    }

    watch(() => props.display, (val, oldVal) => {
      if (val) {
        document.addEventListener('paste', handlePaste)
      } else {
        document.removeEventListener('paste', handlePaste)
        init()
      }
    })

    return {
      uploadImage,
      imgBase64,
    }
  },

  computed: {
    //是否显示组件
    showBox: {
      get() {
        return this.display
      },
      set(value) {
        console.log(value);
        // this.$emit('update:display', value)
      }
    }
  },

}

</script>

<template>
  <el-dialog v-model="showBox" align-center title="上传图片-智能识图" width="50%">
    <!--上传组件-->
    <el-upload :before-upload="uploadImage" action="#" class="upload-demo" drag multiple>
      <el-icon class="el-icon--upload">
        <img style="width: 80%;object-fit: cover;"  src="https://tse4-mm.cn.bing.net/th/id/OIP-C.X-5ho42VHJwTZg1ixPxo4wAAAA?w=211&h=180&c=7&r=0&o=5&dpr=1.5&pid=1.7" alt="">
      </el-icon>
      <div class="el-upload__text">
        拖拽文件到此处,或者
        <em>点击上传</em>
        <p style="font-size: 13px">支持微信截图后在此处粘贴( Ctrl + v)</p>
      </div>
      <template #tip>
        <div class="el-upload__tip">
          <!--          jpg/png files with a size less than 500kb-->
        </div>
      </template>
    </el-upload>
  </el-dialog>
</template>

<style scoped></style>

代码分析:

      imgBase64

用来保存选择图片的base64,方便回显或者其他操作

     showbox 使用计算属性,当组件被关闭的时候走 set函数,此时可以触发方法携带一些参数给父级组件;

computed: {
    //是否显示组件
    showBox: {
      get() {
        return this.display
      },
      set(value) {
        console.log(value);
        // this.$emit('update:display', value)
      }
    }
  },
      uploadImage函数

在 el-upload 组件上传前获取上传的文件,判断是不是图片,如果是调用 convertToBase64 方法转换图片为 baes64 并在回调函数中请求接口

       

 //上传图片
    function uploadImage(file) {
      const isImage = file.type.startsWith('image/')
      if (!isImage) {
        ElMessage({
          message: '只可以上传图片',
          type: 'warning',
        })
        return isImage
      }
      convertToBase64(file, async (base64String) => {
        //发送请求
        putImg(base64String)
      })
      return false
    }
       convertToBase64函数

需要传入 el 上传组件的 file 和回调函数,图片转化成 base64 后,调用传入的方法

    //转化图片为base64
    function convertToBase64(file, callback) {
      const reader = new FileReader()
      reader.onload = (event) => {
        callback(event.target.result)
      }
      reader.readAsDataURL(file)
    }
      handlePaste函数

监听剪切板,判断粘贴内容是不是图片并获取最近的一张截图,如果是图片调用 convertToBase64函数 并请求接口

      putImg函数 请求接口,在发送请求前才会更新当前保存的图片

    function putImg(base64Str) {
      imgBase64.value = base64Str
      const loading = ElLoading.service({
        lock: true,
        text: 'Loading',
        background: 'rgba(0, 0, 0, 0.7)',
      })
      //发送请求(此方法应该自己定义)
      upImg({
        image_base64: base64Str
      })
        .then((res) => {
          // 处理异常情况
          if (!res.success) {
            ElMessage({
              message: res.error_message,
              type: 'error',
            })
            return
          }
          //成功响应
          loading.close()
        })
        .catch((error) => {
          // 处理错误
          ElMessage({
            message: '识别失败,请重新上传',
            type: 'error',
          })
          console.error(error)
          loading.close()
        })
    }
      init函数

初始化,清空当前保存的图片

 function init() {
      imgBase64.value = ''
    }
      watch

监听 props.display ,当 display 为 true 的时候,也就是上传组件显示的时候,网页开始监听剪贴操作,反之为 false 的时候,组件关闭的同时,取消监听,并初始化

     

   watch(() => props.display, (val, oldVal) => {
      if (val) {
        document.addEventListener('paste', handlePaste)
      } else {
        document.removeEventListener('paste', handlePaste)
        init()
      }
    })

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
Vue3 + Element Plus 提供了一种简单的方法来实现文件上传。你可以使用 Element Plus 的 Upload 组件来实现这个功能。首先,你需要在你的 Vue3 项目中安装 Element Plus,并在 main.js 中引入 Element Plus 的样式和语言包。然后,在你的组件中,使用 setup 语法糖来定义响应式数据和方法。你可以使用 ref 函数来创建一个响应式的变量来存储上传的文件。然后,使用 Upload 组件来实现文件上传功能。你可以通过设置 action 属性来指定上传文件的接口地址,通过设置 onSuccess 属性来处理上传成功后的回调函数。在回调函数中,你可以通过参数获取到上传成功后的文件信息。最后,将 Upload 组件放置在你的模板中,即可实现文件上传功能。 以下是一个示例代码: ```html <template> <div> <el-upload action="/upload" :on-success="handleSuccess" > <el-button type="primary">点击上传</el-button> </el-upload> </div> </template> <script> import { ref } from 'vue'; export default { setup() { const file = ref(null); const handleSuccess = (response, file) => { // 处理上传成功后的逻辑 console.log('上传成功', response, file); }; return { file, handleSuccess, }; }, }; </script> ``` 在这个示例中,我们使用了 ref 函数来创建一个响应式的变量 file 来存储上传的文件。在 handleSuccess 方法中,我们可以处理上传成功后的逻辑。你可以根据实际需求来修改这个方法。 请注意,你需要根据你的实际情况来设置 action 属性的值,以及处理上传成功后的逻辑。这只是一个简单的示例,你可以根据你的需求进行修改和扩展。 希望这个回答对你有帮助! #### 引用[.reference_title] - *1* *2* *3* [【 Vue3 + Vite + setup语法糖 + Pinia + VueRouter + Element Plus 第一篇】(持续更新中)](https://blog.csdn.net/Web_chicken/article/details/128551075)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值