Skip to content

指令有什么用?如何自定义一个指令?

什么是指令?

Vue中提供了一套为数据驱动视图更为方便的操作,这些操作被成为指令系统

我们看到的v-开头的行内属性,都是指令,不同的指令可以完成或者实现不同的功能

比如我们常见的v-ifv-forv-model等都属于内置指令

如何自定义指令

注册一个自定义指令有局部注册全局注册

局部注册

vue
<!--/在`directive`中定义-->
<script>
    export default {
        directives: {
            focus: {
                inserted: function(el) {
                    el.focus(); //页面完成加载之后自动让输入框获取焦点的小功能
                }
            }
        }
    }
</script>
vue
<!--在 <script setup> 中,任何以 v 开头的驼峰式命名的变量都可以被用作一个自定义指令-->
<script setup lang="ts">
    // 在模板中启用 v-focus
    const vFocus = {
        mounted: (el: HTMLElement) => el.focus()
    }
</script>

全局注册

js
import Vue from 'vue'

Vue.directive('focus', {
    inserted: function (el) {
        el.focus()
    }
})
js
import Vue from 'vue'

Vue.directive('focus', (el) => {
    // 会在 `bind` 和 `update` 时都调用
    el.focus()
})
ts
const app = createApp({})

app.directive('focus', {
    mounted: (el: HTMLElement) => {
        el.focus()
    }
})
ts
const app = createApp({})

app.directive('focus', (el: HTMLElement) => {
    // 会在 `mounted` 和 `updated` 时都调用
    el.focus()
})

使用方式

vue

<template>
    <form>
        <!--绑定v-focus指令-->
        <input v-focus value=""/>
    </form>
</template>

Vue2和Vue3的区别

函数钩子

Vue2Vue3作用区别
created在元素的 attribute 或事件监听器被应用之前调用vue2没有该钩子函数
bindbeforeMount只调用一次,指令绑定到元素后调用。
在这里可以进行一次性的初始化设置
命名不同,功能一致
insertedmounted元素插入父元素后调用命名不同,功能一致
beforeUpdate在元素本身被更新之前调用vue2没有该钩子函数
update当元素更新,但子元素尚未更新时,将调用此钩子vue3没有该钩子函数
componentUpdatedupdated元素和所有子元素全部更新后调用命名不同,功能一致
beforeUnmount在元素被卸载之前调用vue2没有该钩子函数
unbindunmounted只调用一次,指令与元素解绑时调用命名不同,功能一致

函数钩子参数

Vue2Vue3作用区别
el指令所绑定的元素,可以用来直接操作 DOM
binding一个对象,包含以下属性
Vue2Vue3作用区别
name指令名,不包括v-前缀 Vue2 中没有
value指令的绑定值。
例如:v-my-directive="1 + 1" 中,绑定值为 2
oldValue指令绑定的前一个值,无论值是否改变都可用 Vue2 中仅在 updatecomponentUpdated 中可用,
Vue3 中仅在 beforeUpdateupdated 中可用
expression 字符串形式的指令表达式。
例如 v-my-directive="1 + 1" 中,表达式为 "1 + 1"
Vue3 中没有
arg传给指令的参数,可选。
例如 v-my-directive:foo 中,参数为 "foo"
modifiers 一个包含修饰符的对象。
例如:v-my-directive.foo.bar 中,
修饰符对象为 { foo: true, bar: true }
instance该指令的组件实例Vue2 中没有
dir指令定义的对象Vue2 中没有
vnodeVue 编译生成的虚拟节点(绑定元素的底层 VNode
oldVnodeprevNode上一个虚拟节点
(之前的渲染中代表指令所绑定的VNode
命名不同,
Vue2 中仅在 updatecomponentUpdated 中可用,
Vue3 中仅在 beforeUpdateupdated 中可用

有哪些应用场景