自定义指令 - directive

除了核心功能默认内置的指令,Vue也允许开发者注册自定义指令。有的情况下,对普通DOM元素进行底层操作,这时候就会用到自定义指令绑定到元素上执行相关操作。

自定义指令分为:全局指令和局部指令,当全局指令和局部指令同名时以局部指令为准

全局与局部有的区别?

全局的适用于整个项目的(常用)

局部的适用于当前组件的

请注意:不管在定义全局还是局部自定义指令时,所提及的指令名均是不带v-前缀的名称。

自定义指令常用钩子函数有:

bind:在指令第一次绑定到元素时调用(在该环节中是获取不到父节点的,父节点是null),序号:1

inserted:被绑定元素插入父节点时调用(在该环节中是可以获取到父节点的),序号:2

update:数据更新时调用(该环节会重复触发),序号:3

全局自定义指令定义

全局自定义指令(后续的知识点也是的)不能写在Vue实例中(或者某个组件中)。

// 无参类似(v-once/v-cloak)
Vue.directive('指令名',{
	钩子函数名: function(el[,....]){
    	// el参数是挂载到的元素的DOM对象
        // 业务逻辑
    }
}

// 传参(v-text/v-html/v-model)
Vue.directive('指令名',{
	钩子函数名: function(el,binding[,....]){
        // binding是参数
    	let param = binding.value
        // 业务逻辑
    },
}

全局自定义指令实例

<div id="app">
    <div v-red>{{msg}}</div>
    <!-- 传值 -->
    <div v-color="greenyellow">{{msg}}</div>
    <!-- 直接传字符串 -->
    <div v-color="'grey'">{{msg}}</div>
</div>
<script src="./js/vue.js"></script>
<script>
    // 全局指令,v-red
    Vue.directive("red", {
        bind: function (el) {
            // 尝试获取父节点
            console.log(el.parentNode);  // null
            console.log(el);  //
            // 变红
            el.style.color = "red";
        },
        inserted: function (el) {
            // 尝试获取父节点
            console.log(el.parentNode);
            console.log(el);
            el.style.color = "red";
        },
        update: function (el) {
            console.log(el.parentNode);
            console.log(el);
            el.style.color = "blue";
        },
    });
    Vue.directive("color", {
        inserted: function (el, binding) {
            // console.log(binding);
            el.style.color = binding.value;
        },
    });
    new Vue({
        el: "#app",
        data: {
            msg: "你好啊",
            greenyellow: "greenyellow",
        },
    });
</script>

局部自定义指令定义

可以在new Vue的时候添加directives以注册局部自定义指令,局部自定义指令只能在当前组件中使用

directives: {
    指令名: {
        // 指令的定义
        钩子函数名: function (el,binding) {
        // 业务逻辑
        }
    }
}

局部自定义指令实例

<div id="app">
    <div v-red>{{msg}}</div>
    <!-- 传值 -->
    <div v-color="greenyellow">{{msg}}</div>
    <!-- 直接传字符串 -->
    <div v-color="'grey'">{{msg}}</div>
</div>
<script src="./js/vue.js"></script>
<script>
    new Vue({
        el: "#app",
        data: {
            msg: "你好啊",
            greenyellow: "greenyellow",
        },
        directives: {
            // 局部自定义指令函数
            red: {
                bind: function (el) {
                    // 尝试获取父节点
                    console.log(el.parentNode);
                    console.log(el);
                    // 变红
                    el.style.color = "red";
                },
                inserted: function (el) {
                    // 尝试获取父节点
                    console.log(el.parentNode);
                    console.log(el);
                    el.style.color = "red";
                },
                update: function (el) {
                    console.log(el.parentNode);
                    console.log(el);
                    el.style.color = "blue";
                },
            },
        },
    });
</script>

一沙一世界,一花一天堂。君掌盛无边,刹那成永恒。