指令
想要了解自定义指令,那肯定得先明白什么是指令。
指令的本质:语法糖,标志位。在编译阶段 render 函数里,会把指令编译成 JavaScript 代码。
常见的Vue内置指令有:
- v-on 即 @。v-on:click=”function“, 缩写为@click=”function“
- v-if
- v-for
- v-html
- ……
所以指令就是跟我们的元素标签绑定在一起的某些事件,当我们dom组件在一定条件下就会触发相对应的指令。
自定义指令
先看看Vue官方的说法:
除了核心功能默认内置的指令 (v-model 和 v-show),Vue 也允许注册自定义指令。注意,在 Vue2.0 中,代码复用和抽象的主要形式是组件。然而,有的情况下,你仍然需要对普通 DOM 元素进行底层操作,这时候就会用到自定义指令
指令的自定义即我们按照Vue制定的规则去编写一套可以对dom进行操作的功能函数,然后就能与其他Vue的内置指令一样具有一定的功能效果。指令相当于简化了我们对dom的操作,可以快速进行dom的事件处理,当然我们应该尽量减少使用一些容易消耗浏览器资源的指令。
关于注册自定义指令
全局注册
// 注册一个全局自定义指令 `v-focus`
Vue.directive('focus', {// 当被绑定的元素插入到 DOM 中时……inserted: function (el) {// 聚焦元素el.focus()}
})
局部注册
directives: {focus: {// 指令的定义inserted: function (el) {el.focus()}}
}
自定义指令的钩子函数
bind:只调用一次,指令第一次绑定到元素时调用。在这里可以进行一次性的初始化设置。
inserted:被绑定元素插入父节点时调用 (仅保证父节点存在,但不一定已被插入文档中)。
update:所在组件的 VNode 更新时调用,但是可能发生在其子 VNode 更新之前。指令的值可能发生了改变,也可能没有。但是你可以通过比较更新前后的值来忽略不必要的模板更新 (详细的钩子函数参数见下)。
componentUpdated:指令所在组件的 VNode 及其子 VNode 全部更新后调用。
unbind:只调用一次,指令与元素解绑时调用。
封装自定义指令
通过以上的描述,相信大多数人大概对自定义指令以及指令都有了一定的理解,已经可以开始编写一些简单不重复的指令。但是面对一些复杂而且可能需要经常使用到的自定义指令,这个时候我们最好还是把代码进行一层封装,这样可以方便我们后续的修改和有层次的代码编写。
1.首先可以选择在根目录下新建文件夹directive
2.创建自定义指令的文件夹
3.文件夹下的index.js文件,例如实现一键复制文本内容,用于鼠标右键粘贴。
const copy = {bind(el, { value }) {el.$value = valueel.handler = () => {if (!el.$value) {// 值为空的时候,给出提示。可根据项目UI仔细设计console.log('无复制内容')return}// 动态创建 textarea 标签const textarea = document.createElement('textarea')// 将该 textarea 设为 readonly 防止 iOS 下自动唤起键盘,同时将 textarea 移出可视区域textarea.readOnly = 'readonly'textarea.style.position = 'absolute'textarea.style.left = '-9999px'// 将要 copy 的值赋给 textarea 标签的 value 属性textarea.value = el.$value// 将 textarea 插入到 body 中document.body.appendChild(textarea)// 选中值并复制textarea.select()const result = document.execCommand('Copy')if (result) {console.log('复制成功') // 可根据项目UI仔细设计}document.body.removeChild(textarea)}// 绑定点击事件,就是所谓的一键 copy 啦el.addEventListener('click', el.handler)},// 当传进来的值更新的时候触发componentUpdated(el, { value }) {el.$value = value},// 指令与元素解绑的时候,移除事件绑定unbind(el) {el.removeEventListener('click', el.handler)},
}
export default copy
4.directive下需要有一个总管全局directive的文件,便于我们进行全局注册时的操作。
directive/index.js
import copy from './copy'// 自定义指令
const directives = {copy,
}export default {install(Vue) {Object.keys(directives).forEach((key) => {Vue.directive(key, directives[key])})},
5.全局进行遍历注册,main.js.Vue.use函数会调用我们写好的install,相当于运行我们install里面的代码
import Vue from 'vue'
import Directives from '@/directive'
Vue.use(Directives)