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

2021-05-16  本文已影响0人  张中华

简介

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

钩子函数

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

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

使用方式

自定义指令可以全局注册也可以局部注册。全局注册就是挂载到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这两个常用的钩子函数触发条件下执行。

上一篇下一篇

猜你喜欢

热点阅读