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....')
},
}

- 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....')
},
}

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