# vue 可复用性和组合
# 混入 mixins
# 利用mixins实现页面的自动埋点
获取用户在某个页面的停留时间
// mixins
const computingTime = {
created() {
this._start = Date.now()
},
beforeDestroy() {
const img = new Image('xxxx')
img.setAttribute('src',`https://www.debugs.cn?time=${Date.now - this._start}`)
}
}
// 使用
const Detail = {
mixins: [computingTime]
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
- 组件数据优先
- 同名钩子函数将合并为一个数组,因此都将被调用。混入对象的钩子将在组件自身钩子之前调用。
- methods、components 和 directives,合并成一个对象,key重复的时候采用组件自己的值
- Vue.mixin()可以全局混入
# 自定义指令
vue.directive(name,options|function)
可以自定义指令
options可以配置
- bind: 只调用一次,只调用一次,指令第一次绑定到元素时调用。在这里可以进行一次性的初始化设置。
- inserted: 被绑定元素插入父节点时调用 (仅保证父节点存在,但不一定已被插入文档中)。
- update: 所在组件的 VNode 更新时调用,但是可能发生在其子 VNode 更新之前。指令的值可能发生了改变,也可能没有
- componentUpdated: 指令所在组件的 VNode 及其子 VNode 全部更新后调用
- unbind: 只调用一次,指令与元素解绑时调用。
钩子参数
- el:指令所绑定的元素,可以用来直接操作 DOM。
- binding:一个对象,包含以下 property:
- name:指令名,不包括 v- 前缀。
- value:指令的绑定值
- oldValue:指令绑定的前一个值,仅在 update 和 componentUpdated 钩子中可用。无论值是否改变都可用。
- expression:字符串形式的指令表达式。例如 v-demo:foo.a.b="message + Math.random()"中,表达式为 "message + Math.random()"。
- arg:传给指令的参数,可选。例如 v-demo:foo.a.b="message + Math.random()"中,参数为 "foo"。
- modifiers:一个包含修饰符的对象。例如:v-demo:foo.a.b="message + Math.random()" 中,修饰符对象为 { a: true, b: true }。
- vnode:Vue 编译生成的虚拟节点。移步 VNode API 来了解更多详情。
- oldVnode:上一个虚拟节点,仅在 update 和 componentUpdated 钩子中可用。
<div id="hook-arguments-example" v-demo:foo.a.b="message + Math.random()" @click="message=Math.random()"></div>
<script>
Vue.directive('focus', {
// 当被绑定的元素插入到 DOM 中时……
bind(el,binding,vnode,oldVnode){
var s = JSON.stringify
el.innerHTML =
'arg: ' + s(binding.arg) + '<br>' +
'expression: ' + s(binding.expression) + '<br>' +
'modifiers: ' + s(binding.modifiers) + '<br>' +
'name: ' + s(binding.name) + '<br>' +
'oldArg: ' + s(binding.oldArg) + '<br>' +
'oldValue: ' + s(binding.oldValue) + '<br>' +
'rawName: ' + s(binding.rawName) + '<br>' +
'value: ' + s(binding.value) + '<br>'
// 打印如下
// arg: "foo"
// expression: "message + Math.random()"
// modifiers: {"a":true,"b":true}
// name: "demo"
// oldArg: undefined
// oldValue: undefined
// rawName: "v-demo:foo.a.b"
// value: "hello!0.9805303492940918"
},
inserted(el,binding,vnode,oldVnode){
},
update(el,binding,vnode,oldVnode){
},
componentUpdated(el,binding,vnode,oldVnode) {
},
unbind(el,binding,vnode,oldVnode){
}
})
new Vue({
el:'#app',
data(){
return {
message: 'hello!'
}
}
})
</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
# 渲染函数 & JSX
# 插件
- 为Vue添加全局属性或方法
- 添加全局指令,过滤器
- 添加全局组合,比如 vue-router添加的 route-link router-view
- 添加Vue实例的方法,通过把方法添加到Vue.prototype原型属性上
# 插件开发
Vue的插件应该暴露一个install方法,改方法接受2个参数,第一个是Vue构造器,第二个是参数选项
MyPlugin.install = function (Vue, options) {
// 1. 添加全局方法或 property
Vue.myGlobalMethod = function () {
// 逻辑...
}
// 2. 添加全局资源
Vue.directive('my-directive', {
bind (el, binding, vnode, oldVnode) {
// 逻辑...
}
...
})
// 3. 注入组件选项
Vue.mixin({
created: function () {
// 逻辑...
}
...
})
// 4. 添加实例方法
Vue.prototype.$myMethod = function (methodOptions) {
// 逻辑...
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27