Skip to content

自定义指令

自定义指令底层和内置指令实际就是操作真实的DOM元素,实现功能操作。

1. 语法

  • 局部指令
js
new Vue({                                      new Vue({   
    directives:{指令名配置对象}                   directives(){ }
})                                             })
  • 全局指令
js
Vue.directive(:{指令名:配置对象})     Vue.directive(:{指令名,回调函数})

2. 常用的三个回调函数

配置对象中有三个常用的回调函数:

  • bind:指令与元素绑定时调用,里面的this指向window
  • inserted: 指令所在元素被插入页面时被调用,里面的this指向window
  • update: 指令所在模版结构被重新解析时调用,里面的this指向window

备注

  • 指令定义时不加v- , 但使用时要加v-
  • 指令名如果是多个单词,要使用kebab-case命名方式,不要用cameCase命令。

值得一提的是使用v-其实本身就说明vue遵守了kebab-case命名

html
<!--需求1: 定义v-big指令,和v-text功能类似,但会把绑定的数值放大10倍-->
<!--需求1: 定义v-fbind指令,和v-bind功能类似,但可以让其所绑定的input元素默认获取焦点。-->
<div id="editor">
    <div v-text="n"></div>
    <div v-big="n"></div>
    <button v-on:click="n++">n+1</button>
    <hr/>
    <input v-fbind:value="n">
</div>
js
Vue.config.productionTip = false
const vm = new Vue({
    el: "#editor",
    data() {
        return {
            n: 1
        }
    },
    directives: {
        // big何时被调用? 1.指令与元素成功绑定时(一上来)2.指令所在的模版重新被解析时
        big(element, binding) {  // element指令所在的元素, binding绑定的相关信息对象
            console.log(element instanceof HTMLElement)
            element.innerHTML = binding.value * 10
        },
        /**
         * 这里的focus不奏效,是因为指令与元素成功绑定时是在内存中虚拟DOM绑定的,而不是挂载到页面之后,
         * focus只对在页面上真实DOM才有效; 而在第二次调用时input元素已经在页面上了,所以起作用了
         *  */ 
        // fbind(element, binding){
        //     element.value = binding.value
        //     element.focus()
        // }  不奏效
        // 使用自定义指令第二种方式
        fbind: {
            // 指令与元素成功绑定时(一上来)
            bind(element, binding){
                element.value = binding.value
            },
            // 指令所在元素插入页面时
            inserted(element, binding){
                element.focus()
            },
            // 指令所在的模版重新被解析时
            update(element, binding){
                element.value = binding.value
            }
        }
    }
})