一、Directives指令
内置指令
- v-if v-for v-show v-html等
自定义指令
- 声明全局指令:
Vue.directive('x',directiveOptions)- 例
Vue.directive('x', {
inserted: function(el) {
el.addEventListener('click', () => { console.log('x') })
}
}) //自定一个v-x指令,当元素出现在页面时,执行console.log函数
- 局部声明
- 单个组件的构造选项中加入,只能在当前组件中使用
directives:{
x:{
inserted(el){
el.addEventListener("click",()=>{console.log('x')})
}
}
}
directiveOptions的五个属性
- bind (el,info,vnode,oldVnode)-类似created
- inserted - 类似mounted
- updated - 类似updated
- componentUpdated - 不常用
- unbind - 类似destroyed
举例
- 自制v-on2指令模仿 v-on (简化版)
- 指令
v-on2:click='hi' methods:{ hi(){....}}- 构造选项
- 指令
directives:{
'on2':{
inserted(el,info){ //接收两个参数
console.log(info) //打印出info,
el.addEventListener(info.arg,info.value) //info.args就是事件 //info.value就是事件触发后的方法
},
unbind(el,info){ //将事件监听清理
console.log(info)
el.addEventListener(info.arg,info.value)
}
}
}
小结
指令的作用
- 主要用于DOM操作
- Vue实例/组件用于数据绑定、事件监听、DOM更新
- Vue指令主要目的就是原生DOm操作
- 减少重复
- 如果某个DOM操作经常使用,就可以封装为指令
- 如果某个DOM操作复杂,也可以封装为指令
二、mixins 混入/复制
类比
- directives的作用是减少DOm操作的重复
- mixins的作用是减少data、methods、钩子的重复
场景描述
- 多个子组件实现相同的功能
- 常规操作是在子组件
export default{}中写入相同的data,methods,钩子等,造成代码的重复 - mixin:将这些重复的功能放入某个js文件的对象中
- 子组件直接引入这个对象并在构造选项中声明mixin的对象就可以了
示例:以下代码为抽象说明
常规操作:各个子组件重复相同的选项
子组件相同功能
export default{
data(){},
methods:{},
各种钩子...
}
- mixins作
//新建log.js文件
const log={重复的选项:data,methods,钩子...}
export default log
//各个组件
import log from 'log.js文件路径'
export default{
mixins:[log]
}
- 补充:mixins会智能合并组件中的内容
extends 继承
- 类似mixins,应用场景与上个场景类似 新建MyVue.js
import Vue from 'vue'
const MyVue=Vue.extends({
公共的选项
data
method等
})
export default MyVue
各组件中
import MyVue from 'MyVue.js的url'
export default{
extends:MyVue
}
provide和inject (提供和注入)
场景
- 父组件app.vue中有数据number
- 子组件child.vue要改变父组件中的number,但前提是只能改变自己的数据
- 因此需使用provide和inject
父组件
<template>
<div>
{{number}} //父组件中的number
<child-button /> //子组件按钮
</div>
</template>
<script>
export default{
provide(){
return { number: this.number,//将number提供给子组件
changeNumber:this.changeNumber //将修改number函数提供给子组件
}
},
methods:{
changeNumber(){修改number操作} //修改number
}
data(){
return {number:'oldNumber'} //被修改的数据
},
}
</script>
子组件
<template>
<div>
<button @click='changeNumber'>ChangeNumber</button>
</div>
</template>
<script>
export default{
inject:['number','changeNumber'] //把父组件提供的number和函数注入
}
</script>
- 补充说明:
- number虽然提供给了子组件,但是子组件不能自己提供方法来修改,因为子组件拿到的是oldNUmber字符串,是复制品,修改之后并不能作用于父组件
- 因此,父组件提供改变number的方法,子组件得到引用,触发方法改变number的值
- 强行改number的方法
- 由于是复制品,想办法拿到引用,而不是复制品
- 父组件data中直接return
number:{value:'oldNumber'} - 这样子组件拿到的是对象的引用(即地址),在子组件中顺着地址修改对象值,父组件中也会顺着地址找到对象,此时的值就变了
- 示意图
- 此方法不建议使用,因为涉及到太多变量,容易混乱
小结
- provide和inject的作用是大范围的data和method等共用