elementUI上传组件改造--扫码上传

1、需求

接到客户方的需求:web端如果要上传图片,通常得,

1、手机拍照

2、拷贝到电脑

3、电脑再点击上传(手机的安全性,不熟悉的话,十分麻烦)

客户需要直接在手机上直接上传到系统,十分合理,非常有价值的功能

 

2、分析

1、跨终端(打通pc和移动端的壁垒)

2、不影响原有功能(不改动原来代码,否则,可能会导致业务逻辑改变,会需要测试同事重新测试,需避免)

3、手机上传后,怎么pc端如何监听,并做反馈操作(主动触发即可)

 

3、实现

1、跨终端

依照现有的JWT,可以通过url携带token的方式,携带token到h5端,那么,这个时候就可以上传图片了

2、pc端生成二维码

qrcode.js 可以生成二维码,把扫码上传的项目部署了,pc端用该地址拼接token,即可生成携带token的二维码了

3、不影响原有功能

这个功能需要对原有上传组件的二次封装,我们使用的是elementUI,采用的是上传组件,一如我上一篇文章所说,需要进行二次封装,由于是组件,在组件上,还能进行各种自定义的封装,例如动态加一个class,例如,添加一个原生click事件,开发完全自主,所以,得用上render,利用完全js实现无痛轻松过度

 

代码:

 

<script>
import { Upload } from 'element-ui'
import QRCode from 'qrcode'
import { getFileUploadCode, getFileUrlByCode } from '@/const/fileLibraryApi.js'
import { hasIn } from 'lodash'
export default {
  name: 'MyUpload',
  components: { mUpload: Upload },
  data () {
    return {
      qrcodeImg: '',
      backVisible: false,
      qrcodeLoading: false,
      code: ''
    }
  },
  methods: {
    qrcodeBtn () {
      this.backVisible = true
      this.qrcodeLoading = true
      let originUrl = window.location.origin.includes('.com') ? window.location.origin : 'https://xxx.com'
      this.$axios({
        url: getFileUploadCode,
        method: 'post'
      }).then(res => {
        let code = hasIn(res, ['data', 'payload']) ? res.data.payload : ''
        if (!code) {
          this.$message({ type: 'warning', message: '获取状态码失败,请联系管理员!' })
          return
        }
        this.code = code
        QRCode.toDataURL(`${originUrl}/xx-h5/#/file?token=${this.$store.state.token}&code=${code}`)
          .then(url => {
            this.qrcodeImg = url
            this.qrcodeLoading = false
          })
          .catch(() => {
            this.$message({ type: 'error', message: '生成二维码失败,建议使用本地上传!' })
          })
      })
    },
    // 取消提示
    cancleConfirm () {
      this.$confirm('还未检测到通过二维码上传的文件,是否取消二维码上传?', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(() => {
        this.backVisible = false
      }).catch(() => {
        this.qrcodeLoading = false
      })
    },
    backClick () {
      this.qrcodeLoading = true
      this.$axios({
        url: getFileUrlByCode,
        method: 'post',
        data: { code: this.code }
      }).then(res => {
        let imgUrl = hasIn(res, ['data', 'payload']) ? res.data.payload : ''
        if (!imgUrl) {
          this.cancleConfirm()
          return
        }
        let mProps = this.$attrs['m-props']
        mProps.urlObj[mProps.urlStr] = imgUrl
        this.backVisible = false
      }).catch(() => {
        this.backVisible = false
        this.$message({ type: 'warning', message: '获取上传图片失败,建议使用本地上传!' })
      })
    }
  },
  render (h) {
    const attrsMethods = slots => {
      let values = Object.values(slots)
      let sList = []
      values.forEach(vnodes => {
        sList.push(vnodes)
      })
      return sList
    }
    const qrcodeShow = (h) => {
      return this.backVisible ? h(
        'div',
        {
          class: { 'back-mask': true },
          on: {
            'click': this.backClick
          }
        },
        this.qrcodeImg ? [h(
          'el-image',
          {
            'class': { 'back-qrcode-img': true },
            directives: [{ name: 'loading', value: this.qrcodeLoading }],
            props: { fit: 'fitType', src: this.qrcodeImg }
          }
        )] : []
      ) : []
    }
    return h('div', { class: { 'qrcode_upload_box': true } }, [
      h(
        'm-upload',
        {
          props: this.$attrs,
          on: this.$listeners,
          ref: 'mUpload'
        },
        attrsMethods(this.$slots)
      ),
      h('el-button', {
        class: { 'qrcode_box': true },
        props: {
          icon: 'el-icon-mobile-phone',
          circle: true,
          disabled: this.$attrs.disabled
        },
        attrs: { title: '手机上传二维码' },
        on: {
          click: this.qrcodeBtn
        }
      }),
      qrcodeShow(h)
    ])
  }
}
</script>
<style lang="less" scoped>
.qrcode_upload_box {
  position: relative;
  width: 100%;
  height: 100%;
  .qrcode_box {
    position: absolute;
    top: 0;
    right: 0;
    transform: translate(50%, 50%);
    z-index: 99;
  }
  .back-mask {
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    background-color: rgba(0, 0, 0, 0.7);
    z-index: 100;
    display: flex;
    align-items: center;
    justify-content: center;
    .back-qrcode-img {
      width: 250px;
      height: 250px;
    }
  }
}
</style>

 

 

以上是完整功能代码,包括了:如何判断是哪个控件的上传?是否重复上传了?上传后怎么在pc端渲染出来?前两个问题需要后端提供支持,最后一个问题,实际上利用了内存地址的方式

posted @ 2019-12-17 12:05  白木兰  阅读(1277)  评论(0编辑  收藏  举报