美文网首页
《图解Vue3.0》- 第6节 模板语法 - 自定义指令

《图解Vue3.0》- 第6节 模板语法 - 自定义指令

作者: 张中华 | 来源:发表于2021-05-16 08:07 被阅读0次

    简介

    除了核心功能默认内置的指令 (v-model 和 v-show),Vue 也允许注册自定义指令。注意,在 Vue2.0 中,代码复用和抽象的主要形式是组件。然而,有的情况下,你仍然需要对普通 DOM 元素进行底层操作,这时候就会用到自定义指令。
    API地址:https://vue3js.cn/docs/zh/api/application-api.html#directive

    钩子函数

    一个指令定义对象可以提供如下几个钩子函数 (均为可选):

    • beforeMount:当指令第一次绑定到元素并且在挂载父组件之前调用。在这里你可以做一次性的初始化设置。
    • mounted:在挂载绑定元素的父组件时调用。
    • beforeUpdate:在更新包含组件的 VNode 之前调用。
    • updated:在包含组件的 VNode 及其子组件的 VNode 更新后调用。
    • beforeUnmount:在卸载绑定元素的父组件之前调用
    • unmounted:当指令与元素解除绑定且父组件已卸载时,只调用一次。

    基本和vue组件的生命周期类似,只是没有create的阶段,直接进入挂载阶段,生命周期如下

    • beforeCreate
    • created
    • beforeMount
    • mounted
    • beforeUpdate
    • updated
    • beforeUnmount(vue2.0是beforeDestroy)
    • unmounted(vue2.0是destroyed)

    使用方式

    自定义指令可以全局注册也可以局部注册。全局注册就是挂载到createApp()的结果上,局部注册就是在组件内提供了directives属性,在这里面进行注册。

    写一个input的自动聚焦的示例,代码如下:

    局部注册

    <template>
      <div>
        <input v-focus />
      </div>
    </template>
    
    <script>
    export default {
      directives: {
        focus: {
          // 指令的定义
          mounted(el) {
            el.focus()
          }
        }
      }
    }
    </script>
    

    全局注冊

    注意这里的挂载顺序,最后写app.mount(),不然会报错。
    main.js

    import { createApp } from 'vue'
    import App from './App.vue'
    
    const app = createApp(App);
    
    // 定义v-focus指令
    app.directive('focus', {
        mounted(el) {
            el.focus();
        }
    });
    
    app.mount('#app');
    

    example.vue

    <template>
      <div>
        <input v-focus />
      </div>
    </template>
    

    指令参数

    指令的参数可以是动态的。例如,在 v-mydirective:[argument]="value" 中,argument 参数可以根据组件实例数据进行更新!这使得自定义指令可以在应用中被灵活使用。
    如果指令参数有多个,也可以传一个对象。

    就拿刚刚的v-focus示例来说,如果我们需要将其边框的宽度或颜色修改掉,该如何做呢?

    示例

    main.js

    import { createApp } from 'vue'
    import App from './App.vue'
    
    const app = createApp(App);
    
    // 定义v-focus指令
    app.directive('focus', {
        mounted(el, binding) {
            el.focus();
    
    
            if (typeof binding.value !== 'object') {
                el.style.borderColor = binding.value;
            } else {
                el.style.borderColor = binding.value.color;
                el.style.borderWidth = binding.value.borderWidth;
            }
            
        }
    });
    
    app.mount('#app');
    

    App.vue

    <template>
      <div>
        <input v-focus="yellowColor" />
        <input v-focus:[color]="blueColor" />
        <input v-focus="{ color: 'red', borderWidth: '18px' }" /> 
      </div>
    </template>
    
    <script>
    import { defineComponent } from '@vue/composition-api'
    
    export default defineComponent({
      data() {
        return {
          color: 'color',
          yellowColor: 'yellow',
          blueColor: 'blue'
        };
      }
    })
    </script>
    <style scoped>
    input { margin: 20px; display: block; }
    </style>
    

    由于这里focus只能对一个input起作用,所以反应在了最后一个input上面。

    函数简写

    在很多时候,你可能想在 mounted 和 updated 时触发相同行为,而不关心其它的钩子。比如这样写:

    // 定义v-focus指令
    app.directive('focus',(el, binding)=> {
        el.focus();
        if (typeof binding.value !== 'object') {
            el.style.borderColor = binding.value;
        } else {
            el.style.borderColor = binding.value.color;
            el.style.borderWidth = binding.value.borderWidth;
        }
    });
    

    也就是app.directive提供了两种入参方式,一种是第二参数写成对象,里面包含各个生命周期的钩子函数,另外一个简写就是第二个参数直接写成函数,只在mounted和updated这两个常用的钩子函数触发条件下执行。

    相关文章

      网友评论

          本文标题:《图解Vue3.0》- 第6节 模板语法 - 自定义指令

          本文链接:https://www.haomeiwen.com/subject/dgcodltx.html