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

简介

除了核心功能默认内置的指令 (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这两个常用的钩子函数触发条件下执行。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,258评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,335评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,225评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,126评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,140评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,098评论 1 295
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,018评论 3 417
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,857评论 0 273
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,298评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,518评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,678评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,400评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,993评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,638评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,801评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,661评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,558评论 2 352

推荐阅读更多精彩内容