美文网首页
Vue编写一个一键 Copy的功能(包括自定义指令和插件的方式)

Vue编写一个一键 Copy的功能(包括自定义指令和插件的方式)

作者: Hellolad | 来源:发表于2019-09-26 08:44 被阅读0次

    除了核心功能默认内置的指令 (v-modelv-show),Vue 也允许注册自定义指令。

    1. 三个重要的钩子函数:

    • bind:只调用一次,指令第一次绑定到元素时调用。在这里可以进行一次性的初始化设置。
    • componentUpdated:指令所在组件的 VNode 及其子 VNode 全部更新后调用。
    • unbind:只调用一次,指令与元素解绑时调用。

    2. 钩子函数的重要参数(只列出比较重要的):

    • el:指令所绑定的元素,可以用来直接操作 DOM 。
    • binding:一个对象,包含以下属性:
      • value:指令的绑定值,例如:v-my-directive="1 + 1" 中,绑定值为 2
      • arg:传给指令的参数,可选。例如 v-my-directive:foo 中,参数为 "foo"

    3. 创建一个文件copy.js

    export default {
      bind: function (el, binding, vnode, oldVnode) {
        el.$value = ""
    
        el.handle = function() {
          const fakeElement = document.createElement('textarea')
          fakeElement.readOnly = 'readonly'
          fakeElement.style.position = 'absolute'
          fakeElement.style.left = '-999px'
          fakeElement.value = el.$value
          document.body.appendChild(fakeElement)
          fakeElement.select()
          const result = document.execCommand('copy')
          
          if (result) {
            if (binding.arg === 'success' && typeof binding.value === 'function') {
              binding.value()
            }
          } else {
            if (binding.arg === 'fail' && typeof binding.value === 'function') {
              binding.value()
            }
          }
    
          document.body.removeChild(fakeElement)
        }
        
        el.addEventListener('click', el.handle)
        
      },
    
      componentUpdated: function (el, binding, vnode, oldVnode) {
        if (typeof binding.value !== 'function') {
          el.$value = binding.value
        }
      },
    
      unbind: function (el, binding, vnode, oldVnode) {
        el.removeEventListener('click', el.handle)
      }
    }
    

    使用方法:

    <el-input size="small" v-model="inputVale" placeholder="请输入内容"></el-input>
    <el-button
      size="small"
      type="primary"
      v-copy="inputVale"
      v-copy:success="handleSuccess"
      v-copy:fail="handleFail"
    >复制内容</el-button>
    
    import VCopy from '@/directives/copy'
    
    export default {
      name: "v-copy",
      data() {
        return {
          inputVale: ""
        };
      },
    
      methods: {
        handleSuccess() {
          console.log("handleSuccess 复制成功");
          this.$message.success('复制成功')
        },
        handleFail() {
          console.log("handleFail 复制失败")
          this.$message.error('复制失败')
        }
      },
    
      directives: {
        copy: VCopy
      }
    };
    

    4. 也可以使用插件的方式:

    const CopyPlugin = {}
    CopyPlugin.install = function (Vue, options) {
    
      Vue.directive('copy', {
        bind: function (el, binding, vnode, oldVnode) {
          el.$value = ""
      
          el.handle = function() {
            const fakeElement = document.createElement('textarea')
            fakeElement.readOnly = 'readonly'
            fakeElement.style.position = 'absolute'
            fakeElement.style.left = '-999px'
            fakeElement.value = el.$value
            document.body.appendChild(fakeElement)
            fakeElement.select()
            const result = document.execCommand('copy')
            
            if (result) {
              if (binding.arg === 'success' && typeof binding.value === 'function') {
                binding.value()
              }
            } else {
              if (binding.arg === 'fail' && typeof binding.value === 'function') {
                binding.value()
              }
            }
      
            document.body.removeChild(fakeElement)
          }
          
          el.addEventListener('click', el.handle)
        },
      
        componentUpdated: function (el, binding, vnode, oldVnode) {
          if (typeof binding.value !== 'function') {
            el.$value = binding.value
          }
        },
      
        unbind: function (el, binding, vnode, oldVnode) {
          el.removeEventListener('click', el.handle)
        }
      })
    
      Vue.prototype.$copyfunc = function(value, callback) {
        const fakeElement = document.createElement('textarea')
        fakeElement.readOnly = 'redonly'
        fakeElement.style.position = 'absolute'
        fakeElement.style.left = '-9999px'
        fakeElement.value = value
        document.body.appendChild(fakeElement)
        fakeElement.select()
        const result = document.execCommand('copy') 
        document.body.removeChild(fakeElement)
        if (result) {
          callback('success')
        } else {
          callback('fail')
        }
      }
    
    }
    
    export default CopyPlugin
    

    使用方法:

    <el-input size="small" v-model="inputVale" placeholder="请输入内容"></el-input>
    <el-button
      size="small"
      type="primary"
      @click="handleCopy"
    >复制内容</el-button>
    
    handleCopy() {
      this.$copyfunc(this.inputVale, (str) => {
        if (str === 'success') {
          this.$message.success('复制成功')
        } else {
          this.$message.error('复制失败')
        }
      })
    }
    

    相关文章

      网友评论

          本文标题:Vue编写一个一键 Copy的功能(包括自定义指令和插件的方式)

          本文链接:https://www.haomeiwen.com/subject/cuvructx.html