首頁 >web前端 >Vue.js >Vue3中如何自訂指令?程式碼講解

Vue3中如何自訂指令?程式碼講解

青灯夜游
青灯夜游轉載
2022-07-28 19:33:452430瀏覽

Vue3中如何自訂指令?以下這篇文章就來手把手教大家在 Vue3 中自訂指令,希望對大家有幫助!

Vue3中如何自訂指令?程式碼講解

TienChin 專案前端是Vue3,前端有這樣的一個需求:有一些前端頁面上的按鈕要根據使用者的權限來決定是否要展示出來,如果使用者俱備相應的權限,那就展示對應的按鈕;如果使用者不具備對應的權限,那麼按鈕就隱藏起來。大致上就這樣一個需求。

看到這個需求,可能有小夥伴先想到用v-if 指令,這個指令確實也能做,但是,由於使用者俱備的權限一般來說可能是多個,甚至可能還有通配符,所以這個比對並不是一個容易的事情,肯定得寫方法。 。 。所以,如果能用一個指令來實現這個功能,那麼就會顯得專業很多了。

說乾就乾,我們來看看 Vue3 中如何自訂指令。 (學習影片分享:vue影片教學

1. 成果展示

我們先來看看實作自訂指令最終的使用方式:

<button @click="btnClick" v-hasPermission="[&#39;user:delete&#39;]">删除用户</button>

小夥伴們看到,這個v-hasPermission 就是我們的自訂指令,如果目前使用者俱備user:delete 權限,這個按鈕就會展示出來,如果目前使用者不具備這個權限,這個按鈕就不會展示出來。

2. 指令基礎

先要和小夥伴們說一下,Vue2 和Vue3 在自訂指令上有一些差異,並不完全一致,下面的介紹主要是針對Vue3 的介紹。

我先來和小夥伴們分享我們具體是怎麼做的,然後在講解程式碼的時候再來和大家說說各個參數的含義。

2.1 兩種作用域

自訂指令可以定義全域的,也可以定義局部的。

在正式開搞之前,小夥伴們需要先明白,自訂指令有兩種作用域,一種是局部的自訂指令,還有一種是全域的自訂指令。局部的自訂指令就只能在目前 .vue 檔案中使用,全域的則可以在所有的 .vue 檔案中使用。

2.1.1 局部指令

直接在目前.vue 檔案中定義即可,如下:

directives: {
  focus: {
    // 指令的定义
    mounted(el) {
      el.focus()
    }
  }
}

不過,在Vue3 中,也可以這樣寫:

<template>
    <p>
        <button v-onceClick="10000" @click="btnClick">ClickMe</button>
    </p>
</template>

<script>

    import {ref} from 'vue';

    export default {
        name: "MyVue01",
        setup() {
            const a = ref(1);
            const btnClick = () => {
                a.value++;
            }
            return {a, btnClick}
        },
        directives: {
            onceClick: {
                mounted(el, binding, vnode) {
                    el.addEventListener('click', () => {
                        if (!el.disabled) {
                            el.disabled = true;
                            setTimeout(() => {
                                el.disabled = false;
                            }, binding.value || 1000);
                        }
                    });
                }
            }
        }
    }
</script>

這裡我自訂了一個名叫onceClick 的指令,給一個button 按鈕加上這個指令之後,可以設定這個button 按鈕在點擊多久之後,處於停用狀態,防止使用者重複點擊。

小夥伴們看,這個指令的執行邏輯其實很簡單,el 相當於添加了這個指令的元素,監聽該元素的點擊事件,如果點擊該元素時,該元素不是處於禁用狀態,那就設定該元素為停用,給定時任務,到期後使該元素變成可用。這裡邊具體的參數,松哥下面會跟大家詳細介紹。

不過這只是一個局部指令​​,只能在目前 .vue 檔案中使用,我們也可以定義全域指令,這樣就可以在所有的 .vue 檔案中使用了。

2.1.2 全域指令

全域指令我們一般寫在main.js 中,或寫一個單獨的js 檔案然後在main.js 中引入,下面的例子是直接寫在main.js 中:

const app = createApp(App);

app.directive('onceClick',{
    mounted(el, binding, vnode) {
        el.addEventListener('click', () => {
            if (!el.disabled) {
                el.disabled = true;
                setTimeout(() => {
                    el.disabled = false;
                }, binding.value || 1000);
            }
        });
    }
})

這樣,我們就可以隨時隨地去使用v-onceClick 這個指令了。

可能小夥伴感覺比較疑惑,自訂指令時候的 mounted 以及這裡的參數都是咋回事,那麼接下來松哥就來和大家詳細介紹一下這些方法和參數。

2.2 七個鉤子函數

在Vue3 中,自訂指令的鉤子函數主要有以下七種(這塊跟Vue2 差異較大):

  • created:在綁定元素的attribute 或事件監聽器被套用之前呼叫。當指令需要附加在普通的 v-on 事件監聽器呼叫前的事件監聽器中時,這很有用。
  • beforeMount:當指令第一次綁定到元素並且在掛載父元件之前呼叫。
  • mounted:在綁定元素的父元件被掛載後調用,大部分自訂指令都寫在這裡
  • beforeUpdate:在更新包含元件的 VNode 之前呼叫。
  • updated:在包含元件的 VNode 及其子元件的 VNode 更新後呼叫。
  • beforeUnmount:在卸載綁定元素的父元件之前呼叫
  • unmounted:當指令解除元素綁定且父元件已卸載時,只呼叫一次。

雖然鉤子函數比較多,看著有點唬人,不過我們日常開發中用的最多的其實是 mounted 函數。

2.3 四个参数

这里七个钩子函数,钩子函数中有回调参数,回调参数有四个,含义基本上和 Vue2 一致:

  • el:指令所绑定的元素,可以用来直接操作 DOM,我们松哥说想实现一个可以自动判断组件显示还是隐藏的指令,那么就可以通过 el 对象来操作 DOM 节点,进而实现组件的隐藏。
  • binding:我们通过自定义指令传递的各种参数,主要存在于这个对象中,该对象属性较多,如下属性是我们日常开发使用较多的几个:

    • name:指令名,不包括 v- 前缀。
    • value:指令的绑定值,例如:v-hasPermission="['user:delete']" 中,绑定值为 'user:delete',不过需要小伙伴们注意的是,这个绑定值可以是数组也可以是普通对象,关键是看你具体绑定的是什么,在 2.1 小节的案例中,我们的 value 就是一个数字。
    • expression:字符串形式的指令表达式。例如 v-my-directive="1 + 1" 中,表达式为 "1 + 1"。
    • arg:传给指令的参数,可选。例如 v-hasPermission:[name]="'zhangsan'" 中,参数为 "name"。
  • vnode:Vue 编译生成的虚拟节点。
  • oldVnode:上一个虚拟节点,仅在 update 和 componentUpdated 钩子中可用。

除了 el 之外,其它参数都应该是只读的,切勿进行修改。如果需要在钩子之间共享数据,建议通过元素的 dataset 来进行。

2.4 动态参数

有一种动态参数,这里也和小伙伴们分享下。正常情况下,我们自定义指令时传递的参数都是通过 binding.value 来获取到的,不过在这之外还有一种方式就是通过 binding.arg 获取参数。

我举一个简单例子,假设我们上面这个 onceClick 指令,默认的时间单位时毫秒,假设现在想给时间设置单位,那么我们就可以这样写:

const app = createApp(App);

app.directive('onceClick',{
    mounted(el, binding, vnode) {
        el.addEventListener('click', () => {
            if (!el.disabled) {
                el.disabled = true;
                let time = binding.value;
                if (binding.arg == "s") {
                    time = time * 1000;
                }
                setTimeout(() => {
                    el.disabled = false;
                }, time);
            }
        });
    }
})

在自定义指令的时候,获取到 binding.arg 的值,这样就可以知道时间单位了,在使用该指令的时候,方式如下:

<button v-onceClick:[timeUnit]="10" @click="btnClick">ClickMe</button>
<script>

    import {ref} from 'vue';

    export default {
        name: "MyVue01",
        setup() {
            const timeUnit = ref('s');
            return {timeUnit}
        }
    }
</script>

timeUnit 是一个提前定义好的变量。

3. 自定义权限指令

好啦,有了上面的基础知识,接下来就来看我们本文的主题,自定义权限指令,我写一个简单的例子大家来看下:

const usersPermissions = ['user'];

app.directive('hasPermission', {
    mounted(el, binding, vnode) {
        const {value} = binding;
        let f = usersPermissions.some(p => {
            return p.indexOf(value) !== -1;
        });
        if (!f) {
            el.parentNode && el.parentNode.removeChild(el);
        }
    }
})

usersPermissions 表示当前用户所具备的权限,正常该数据应该是从服务端加载而来,但是我这里简单起见,就直接定义好了。

具体的逻辑很简单,先从 binding 中提取出 value 的值,这就是当前控件所需要的权限,然后遍历 usersPermissions 用一个 some 函数,去查看 usersPermissions 中是否有满足条件的值,如果没有,说明当前用户不具备展示该组件所需要的权限,那么就要隐藏这个组件,隐藏的方式就是获取到当前组件的父组件,然后从父组件中移除当前组件即可。

这是一个全局的指令,定义好之后,我们就可以在组件中直接使用了:

<button @click="btnClick" v-hasPermission="[&#39;user:delete&#39;]">删除用户</button>

好啦,Vue3 自定义组件学会了没?松哥在最近的 TienChin 项目视频中也会和大家分享这块的内容,敬请期待。

(学习视频分享:web前端开发编程基础视频

以上是Vue3中如何自訂指令?程式碼講解的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文轉載於:segmentfault.com。如有侵權,請聯絡admin@php.cn刪除