【优化】vue+装饰器

244 阅读1分钟

1、问题出现

vue项目里面需要埋点(主要是点击按钮),直接写在方法里面不直观,而且修改了方法本身代码。所以就考虑使用装饰器来完成,这个方式同样可以用在打印日志等附加功能上。

【本文只涉及装饰器使用在vue实例的方法上】

2、装饰器使用

  • 1、没有附加参数
// 1、定义附加的功能
const log = (target, name, descriptor) => {
  const oldValue = descriptor.value
  descriptor.value = function(...args) {
    console.log('方法执行前执行的操作~')
    oldValue.apply(target, args)
    console.log('方法执行后执行的操作~')
  }
  return descriptor
}
// 2、使用
methods: {
    @log
    handleClick () {
      console.log('handleClick....')
    },
}

1

  • 2、有附加参数
// 1、定义附加的功能
const log = (str) => {
  return (target, name, descriptor)=>{
    const oldValue = descriptor.value
    descriptor.value = function(...args) { //这里不能用剪头函数,否则this指向错误 
      console.log(`处理传进来的参数:${str}`)      
      console.log('方法执行前执行的操作~')
      oldValue.apply(target, args)
      console.log('方法执行后执行的操作~')
    }
    return descriptor
  }
}
// 2、使用
methods: {
    @log('我只是用来测试的')
    handleClick () {
      console.log('handleClick....')
    },
}

2

3、装饰器-埋点

其实有了上面的demo,埋点处理就依葫芦画瓢了。

// 1、main.js
import track form '@/utils/track.js'
track.init()
Vue.prototype.$track = track  //绑定到vue原型上,Track处理数据上传到神策

// 2、util.js
const clickTrck = (str) => {
  return (target, name, descriptor)=>{
    const oldValue = descriptor.value
    descriptor.value = function(...args) {    
      this.$track.clickEvent(str) // clickEvent是track.js内部封装的多种埋点类型之一
      oldValue.apply(target, args)
    }
    return descriptor
  }
}
// 3、vue文件里使用
methods: {
    @clickTrck('点击xxxxx星标')
    clickStar () {
      // ... 内部逻辑
    },
     @clickTrck('上传xxxxx问卷答案')
    submitAnswer () {
      // ... 内部逻辑
    },
}

4、效果

  • 很明显的差别是:现在一看就知道哪个方法添加了埋点,而且埋点的内容一目了然,提高了代码的阅读性,且不更改方法本身的源码。
  • 而且如果需要多次埋点,可以同时使用多个埋点(其实就跟加了多个装饰器一样的效果)。