最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • vue 自定义事件、自定义指令

    正文概述 掘金(昭光)   2020-12-22   232

    一个vue 工程,通常都会有对应的全局方法,通过全局引入的方式,更省事。

    引用官方:在 Vue2.0 中,代码复用和抽象的主要形式是组件。然而,有的情况下,你仍然需要对普通 DOM 元素进行底层操作,这时候就会用到自定义指令。

    • 新建一个directives 来放置自定义指令
    • 新建一个comPlugin.js 来实现对应全局方法的实现

    案例:

    import WaterMarker from './directives/waterMarker'
    import Copy from './directives/copy'
    import Throttle from './directives/throttle'
    
    let ComPlugin = {}
    ComPlugin.install = function (Vue, options) {
      // 全局方法或属性
      Vue.globalMethod = function () {}
    
      // 全局自定义指令
      Vue.directive('WaterMarker', { ...WaterMarker })
      Vue.directive('Copy', { ...Copy })
      Vue.directive('Throttle', { ...Throttle })
    
      //   全局注入mixins
      Vue.mixin({
        methods: {
          aa() {},
        },
      })
      // 实例方法
      Vue.prototype.$myMethod = function () {}
    }
    
    export default ComPlugin
    

    waterMarker.js 代码

    let toolMarker = (function () {
      let _can = document.createElement('canvas')
      let _div = document.createElement('div')
      _div.id = 'waterMarker'
      document.body.appendChild(_can)
      _can.width = 300
      _can.height = 360
      _can.style.display = 'none'
      let _cans = _can.getContext('2d')
      _cans.font = '26px Microsoft Yahei'
      _cans.rotate((-20 * Math.PI) / 180)
    
      function drawWaterMarker(str, textColor) {
        _cans.fillStyle = textColor || 'rgba(180, 180, 180, 0.2)'
        //   清空画板
        _cans.clearRect(0, 0, _can.width, _can.height)
        _cans.fillText(str, _can.width / 10, _can.height / 2)
        _div.style = `
                  pointer-events: none;
                  top: 70px;
                  left: 0px;
                  position: fixed;
                  z-index: 998;
                  width: 100%;
                  height: 100%;
                  background-image: url(${_can.toDataURL('image/png')})
              `
        document.body.appendChild(_div)
      }
      function updatedWaterMarker(textVal, textColor) {
        if (_cans && _div) {
          _cans.fillStyle = textColor || 'rgba(180, 180, 180, 0.2)'
          //   清空画板
          _cans.clearRect(0, 0, _can.width, _can.height)
          _cans.fillText(textVal, _can.width / 10, _can.height / 6)
          _div.style.backgroundImage = `url(${_can.toDataURL('image/png')})`
        }
      }
      function cleanWaterMarker() {
        _div && _div.parentNode.removeChild(_div)
        _can && _can.parentNode.removeChild(_can)
      }
      return {
        drawWaterMarker,
        updatedWaterMarker,
        cleanWaterMarker,
      }
    })()
    
    const lkWaterMarker = {
      bind: function (el, { value }) {
        toolMarker.drawWaterMarker(value.text, value.textColor || '', el)
      },
      update: function (el, binding) {
        let { text } = binding.oldValue
        if (binding.oldValue && text && text !== binding.value.text) {
          //   更新waterMarker 文字
          toolMarker.updatedWaterMarker(binding.value.text, binding.value.textColor || '', el)
        }
      },
      unbind: function () {
        toolMarker.cleanWaterMarker && toolMarker.cleanWaterMarker()
      },
    }
    
    export default lkWaterMarker
    
    

    copy.js

    const Copy = {
      bind(el, { value }) {
        el.$value = value
        el.handler = () => {
          if (!el.$value) {
            console.warn('内容为空')
            return
          }
          const _textareaDom = document.createElement('textarea')
          // 将该 _textareaDom 设为 readonly 防止 iOS 下自动唤起键盘
          _textareaDom.readOnly = 'readonly'
          _textareaDom.style.position = 'absolute'
          _textareaDom.style.left = '-999px'
          // 将要 copy 的值赋给 textarea 标签的 value 属性
          _textareaDom.value = el.$value
          // 将 _textareaDom 插入到 body 中
          document.body.appendChild(_textareaDom)
          // 选中值并复制
          _textareaDom.select()
          const result = document.execCommand('Copy')
          if (result) {
            console.log('复制成功') // 可根据项目UI仔细设计
          }
          document.body.removeChild(_textareaDom)
        }
        el.addEventListener('click', el.handler)
      },
      componentUpdated(el, { value }) {
        el.$value = value
      },
      unbind(el) {
        el.removeEventListener('click', el.handler)
      },
    }
    
    export default Copy
    

    throttle.js

    const lkThrottle = {
      inserted(el, binding) {
        let _inpParams = binding.value
        if (!el) {
          return false
        }
        el.time = 1500
        if (Object.prototype.toString.call(_inpParams) === '[object Function]') {
          el.callback = _inpParams
        } else {
          const { fn, _time } = binding.value
          el.callback = fn
          el.time = _time
        }
        el.addEventListener('click', () => {
          const _nowTime = new Date().getTime()
          if (!el.preTime || _nowTime - el.preTime > el.time) {
            el.preTime = _nowTime
            el.callback && el.callback(el)
          }
        })
      },
      unbind() {},
    }
    
    export default lkThrottle
    
    

    app.js 处使用

    import ComPlugin from 'xxx/comPlugin.js'
    Vue.use(ComPlugin)
    

    自定义指令参数详解:

    指令定义函数的几个钩子函数:

    • bind: 只调用一次,指令第一次绑定到元素时调用,可以定义一个在绑定时执行一次的初始化动作。
    • inserted: 被绑定元素插入父节点时调用(父节点存在即可调用,不必存在于 document 中)。
    • update: 被绑定元素所在的模板更新时调用,而不论绑定值是否变化。通过比较更新前后的绑定值。
    • componentUpdated: 被绑定元素所在模板完成一次更新周期时调用。
    • unbind: 只调用一次, 指令与元素解绑时调用。

    指令钩子函数会被传入以下参数:

    • el:指令所绑定的元素,可以用来直接操作 DOM。
    • binding:一个对象,包含以下 property:
      • name:指令名,不包括 v- 前缀。
      • value:指令的绑定值,例如:v-my-directive="1 + 1" 中,绑定值为 2。
      • oldValue:指令绑定的前一个值,仅在 update 和 componentUpdated 钩子中可用。无论值是否改变都可用。
      • expression:字符串形式的指令表达式。例如 v-my-directive="1 + 1" 中,表达式为 "1 + 1"。
      • arg:传给指令的参数,可选。例如 v-my-directive:foo 中,参数为 "foo"。
      • modifiers:一个包含修饰符的对象。例如:v-my-directive.foo.bar 中,修饰符对象为 { foo: true, bar: true }。
    • vnode:Vue 编译生成的虚拟节点。移步 VNode API 来了解更多详情。
    • oldVnode:上一个虚拟节点,仅在 update 和 componentUpdated 钩子中可用。

    其他自定义指令


    起源地 » vue 自定义事件、自定义指令

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元