欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Vue自定義指令的使用詳細介紹

 更新時間:2022年09月08日 14:41:18   作者:月光曬了很涼快  
我們看到的v-開頭的行內(nèi)屬性,都是指令,不同的指令可以完成或?qū)崿F(xiàn)不同的功能,對普通 DOM元素進行底層操作,這時候就會用到自定義指令。除了核心功能默認內(nèi)置的指令 (v-model 和 v-show),Vue 也允許注冊自定義指令

1. 概述

除了核心功能默認內(nèi)置的指令,Vue也允許注冊自定義指令。有的情況下,對普通 DOM 元素進行底層操作,這時候就會用到自定義指令綁定到元素上執(zhí)行相關操作。

自定義指令分為:

全局指令和局部指令,當全局指令和局部指令同名時以局部指令為準。

局部指令:只對當前實例(或組件)生效

全局指令:對全部實例(或組件)都生效

2. 鉤子函數(shù)

自定義指令常用鉤子函數(shù):

  1. bind 第一次綁定到元素時調(diào)用(初始化)
  2. inserted 被綁定元素插入父節(jié)點時調(diào)用 (僅保證父節(jié)點存在,但不一定已被插入文檔中)
  3. update 數(shù)據(jù)更新時調(diào)用
  4. componentUpdated 指令所在組件的 VNode 及其子 VNode 全部更新后調(diào)用。
  5. unbind 只調(diào)用一次,指令與元素解綁時調(diào)用。

指令的鉤子會傳遞以下幾種參數(shù):

el:指令綁定到的元素。這可以用于直接操作 DOM。

binding:一個對象,包含以下屬性。

  1. value:傳遞給指令的值。例如在 v-my-directive="1 + 1" 中,值是 2。
  2. oldValue:之前的值,僅在 beforeUpdateupdated 中可用。無論值是否更改,它都可用。
  3. arg:傳遞給指令的參數(shù) (如果有的話)。例如在 v-my-directive:foo 中,參數(shù)是 "foo"
  4. modifiers:一個包含修飾符的對象 (如果有的話)。例如在 v-my-directive.foo.bar 中,修飾符對象是 { foo: true, bar: true }
  5. instance:使用該指令的組件實例。
  6. dir:指令的定義對象。

vnode:代表綁定元素的底層 VNode。

prevNode:之前的渲染中代表指令所綁定元素的 VNode。僅在 beforeUpdateupdated 鉤子中可用。

鉤子函數(shù)可以理解為一個類,類中的構(gòu)造函數(shù)綁定了5個函數(shù)(即鉤子函數(shù)),當我們自定義鉤子函數(shù)時,就會初始化這個類,然后讓我們的相關代碼按順序執(zhí)行這5個函數(shù)。

有關鉤子函數(shù)更詳細的解釋,下面這篇文章中的前兩個教程寫得很通俗易懂,特此推薦:

傳送門

鉤子函數(shù)的執(zhí)行順序:

<div id="app1">
    <div v-red v-if="isShow">
        <input type="text" v-model="title">
    </div>
</div>
<script>
    Vue.directive('red', {
        // bind 第一次綁定到元素時調(diào)用
        bind(el, bindings) {
            console.log('bind');
        },
        // inserted
        inserted(el, bindings) {
            console.log('inserted');
        },
        // update
        update(el, bindings) {
            console.log('update');
        },
        // componentUpdate
        componentUpdated(el, bindings) {
            console.log('componentUpdated');
        },
        // unbind
        unbind(el, bindings) {
            console.log('unbind');
        },
    }) 
    const vm1 = new Vue({
        el: '#app1',
        data: {
            isShow: true,
            title: '鉤子函數(shù)執(zhí)行順序'
        }
    })
</script>

程序一執(zhí)行,當數(shù)據(jù)源中的數(shù)據(jù)第一次綁定了元素就會執(zhí)行bind函數(shù),當綁定元素插入到父元素中,即顯示到視圖中時,會執(zhí)行inserted函數(shù):

當我們改變視圖,使得數(shù)據(jù)發(fā)生改變時,就會執(zhí)行updatecomponentUpdated函數(shù):

當我們銷毀被綁定元素時,即被綁定元素和數(shù)據(jù)源解綁,就會觸發(fā)unbind函數(shù):

3. 自定義全局指令

描述:

全局定義的指令,所有的組件或vue的實例都會生效。

語法:

Vue.directive('指令名稱,不需要寫v-開頭',對象或函數(shù))

Vue.directive('test',{
	bind(el,bind){
		console.log(el)
	}
})

案例:

<div id="app1">
    <div v-red>{{title}}</div>
</div>
<div id="app2">
    <div v-red>標題2</div>
</div> 
<script>
	//自定義全局指令
    Vue.directive('red', {
        // bind 第一次綁定到元素時調(diào)用
        bind(el, bindings) {
            el.style.cssText = `color:red;font-size:30px`
        }

    }) 
    const vm1 = new Vue({
        el: '#app1',
        data: {
            isShow: true,
            title: '標題1'
        }
    })
    const vm2 = new Vue({
        el: '#app2',
        data: {
        }
    })
</script>

4. 自定義局部指令

描述:

定義局部指令,只有當前的實例能用。

語法:

new Vue({
	directives: {
		test:{
			bind(el,bind){}
		},
		// bind/update
		test2(el,bind){}
	}
})

案例:

<div id="app1">
    <div v-red>{{title}}</div>
</div>
<div id="app2">
    <div v-red>標題2</div>
</div> 
<script>
    const vm1 = new Vue({
        el: '#app1',
        data: {
            isShow: true,
            title: '標題1'
        },
        // 定義局部指令,只有當前的實例能用
        directives: {
            red: {
                // bind它還沒有綁定到父元素中,初始化
                bind(el) {
                    el.style.cssText = `color:red;font-size:30px`
                }
            }
        }
    })
    const vm2 = new Vue({
        el: '#app2',
        data: {
        },
        directives: {
            red: {
                bind(el) {
                    el.style.cssText = `color:blue;font-size:30px`
                }
            }
        }
    })
</script>

利用自定義局部指令操作Dom:

<div id="app1">
    <div v-red>{{title}}</div>
</div>
<div id="app2">
    <div v-red>標題2</div>
</div> 
<script>
    const vm1 = new Vue({
        el: '#app1',
        data: {
            isShow: true,
            title: '標題1'
        },
        directives: {
            red: {
                // bind表示被綁定元素還沒有插入到父元素中
                bind(el) {
                    el.style.cssText = `color:red;font-size:30px`
                    const divDom = document.createElement('div')
                    divDom.innerHTML = '我是標題1的孩子'
                    el.appendChild(divDom)
                },
                // 這時被綁定元素已經(jīng)插入到父元素中去了,所以可以打印出被綁定元元素的父節(jié)點
                inserted(el) {
                    console.log(el.parentNode);
                }
            }
        }
    })
    const vm2 = new Vue({
        el: '#app2',
        data: {
        },
        directives: {
            red: {
                bind(el) {
                    el.style.cssText = `color:blue;font-size:30px`
                }
            }
        }
    })
</script>

注意:在上面的代碼中,我們在bind函數(shù)中,不能獲取當前被綁定元素的父節(jié)點,因為此時被綁定元素剛剛初始化,還沒有插入到父節(jié)點當中。在inserted函數(shù)中才能獲取被綁定元素的父節(jié)點,因為此時元素已經(jīng)插入到父節(jié)點當中去了。

5. 使用自定義指令實現(xiàn)權(quán)限管理

目標:

根據(jù)地址欄中的數(shù)據(jù),決定是否顯示 button 按鈕。如果地址欄中的 username 的值是 admin 時,就顯示 button 按鈕,否則不顯示。

注意:目標中的顯示與不顯示,是取決于該 Dom 元素(button 按鈕)是否存在,而不是通過 css 來進行顯示與隱藏。

代碼:

<div id="app1">
    <button v-auth>查看工資</button>
</div>
<script>
    const vm1 = new Vue({
        el: '#app1',
        data: {
            isShow: true,
            title: '標題1'
        },
        directives: {
            auth: {
                // 注意:是否刪除按鈕的操作,必須在被綁定元素(即當前元素)已經(jīng)插入父節(jié)點(插入到視圖)當中后進行
                inserted(el) {
                    // 這是一種比較粗暴的寫法,可維護性較低
                    // if (location.search != '?username=admin') {
                    //   el.remove()
                    // }
                    // URLSearchParams它是html5提供的新的Api方法,用于獲取url地址中的search轉(zhuǎn)為對象
                    let urlSearch = new URLSearchParams(location.search)
                    // 這樣的寫法可維護性較高,假如顯示元素的權(quán)限還需要給到 張三 用戶,則直接修改判斷條件中的表達式即可
                    if (urlSearch.get('username') != 'admin') {
                        // 以前兼容性更好的寫法,但是現(xiàn)在可以不管
                        // el.parentNode.removeChild(el)
                        el.remove()
                    }
                }
            }
        }
    })
</script>

6. 使用自定義指令實現(xiàn)表單驗證

首先我們先完成驗證手機號的功能。

目標:

在初始化(在 bind 函數(shù)中進行)和更新數(shù)據(jù)(在 update 函數(shù)中進行)時都要進行手機號的驗證。

思路:

先獲取手機號(收集數(shù)據(jù)),再用正則表達式判斷輸入框中的手機號是否合法,如果合法則手機號顯示黑色,如果不合法則手機號顯示紅色。

代碼:

<div id="app">
    <div>
        <input type="text" v-phone="phone" v-model="phone">
    </div>
</div>
<script>  
    Vue.directive('phone', {
        // 方法1:直接通過dom來完成數(shù)據(jù)的收集
        // update(el) {
        //   console.log(el.value);
        // }
        // 方法2:可以通過傳值的方式(鉤子函數(shù))完成數(shù)據(jù)收集
        bind(el, { value }) {
            // 手機號碼
            let reg = /^1[3-9]\d{9}$/
            if (!reg.test(value)) {
                // 不合法
                el.style.color = 'red'
            } else {
                el.style.color = 'black'
            }
        },
        update(el, { value }) {
            // 手機號碼
            let reg = /^1[3-9]\d{9}$/
            if (!reg.test(value)) {
                // 不合法
                el.style.color = 'red'
            } else {
                el.style.color = 'black'
            }
        }
    }) 
    const vm1 = new Vue({
        el: '#app',
        data: {
            phone: '13525125121',
        }
    })
</script>

在上面代碼中,通過鉤子函數(shù)完成數(shù)據(jù)獲取與驗證,代碼重復率高,所以在鉤子函數(shù)部分,我們可以簡寫成下面這種方式:

Vue.directive('phone', (el, { value }) => {
    // 手機號碼
    let reg = /^1[3-9]\d{9}$/
    if (!reg.test(phone)) {
        // 不合法
        el.style.color = 'red'
    } else {
        el.style.color = 'black'
    }
}) 

注意:簡寫方式就是自定義指令語法中,第二個參數(shù)是函數(shù)的寫法。自定義指令的簡寫,指的是將 bind 函數(shù)和 update 函數(shù)封裝起來的寫法。

在上面的基礎上,我們再加上驗證錯誤信息的顯示:

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>vue學習使用</title>
        <script src="./js/vue.js"></script>
    </head>
    <body>
        <div id="app">
            <div>
                <input type="text" v-phone="phone" v-model="phone">
            </div>
        </div>
        <script>
            Vue.directive('phone', (el, { value }) => {
                // 手機號碼
                let reg = /^1[3-9]\d{9}$/
                if (!reg.test(value)) {
                    // 不合法
                    el.style.color = 'red'
                    // 沒有 span 標簽時,就創(chuàng)建 span 標簽
                    if (!el.nextSibling) {
                        const spanDom = document.createElement('span')
                        spanDom.innerHTML = '不合法,修改一下'
                        // 這里是防止初始化時數(shù)據(jù)就不合法,導致被綁定元素不能成功插入到父結(jié)點中
                        // el.parentNode?.appendChild(spanDom)
                        // 上面的寫法要求的瀏覽器版本較高,下面的寫法兼容性更好
                        el.parentNode && el.parentNode.appendChild(spanDom)
                    }
                } else {// 輸入正確時,移除 span 標簽
                    el.style.color = 'black'
                    el.nextSibling && el.nextSibling.remove()
                }
            })
            const vm1 = new Vue({
                el: '#app',
                data: {
                    phone: '13525125121',
                    phoneMsg: ''
                }
            })
        </script>
    </body>
</html>

最后,我們使用模塊化的的思路,將案例完善一下:

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>vue學習使用</title>
        <script src="./js/vue.js"></script>
    </head>
    <body>
        <div id="app">
            <div>
                <!-- 這種寫法的 value 值直接就是 phone -->
                <!-- <input type="text" v-validate="phone" v-model="phone"> -->
                <input type="text" v-validate.phone v-model="phone">
            </div>
            <div>
                <input type="text" v-validate.email v-model="email">
            </div>
            <div>
                <!-- "{len:3,msg:'長度過長'}":v-validate指令的value值 -->
                <input type="text" v-validate.str="{len:3,msg:'長度過長'}" v-model="str">
            </div>
        </div>
        <script>
            // 在對象里存方法
            const validateMethod = {
                phone(el) {
                    // 手機號碼
                    let reg = /^1[3-9]\d{9}$/
                    if (!reg.test(el.value)) {
                        // 不合法
                        el.style.color = 'red'
                        if (!el.nextSibling) {
                            const spanDom = document.createElement('span')
                            spanDom.innerHTML = '不合法,修改一下'
                            // el.parentNode?.appendChild(spanDom)
                            el.parentNode && el.parentNode.appendChild(spanDom)
                        }
                    } else {
                        el.style.color = 'black'
                        el.nextSibling && el.nextSibling.remove()
                    }
                    console.log('phone');
                },
                email(el, value) {
                    console.log('email')
                },
                str(el, value) {
                    // 這里這個判斷是容錯處理,也可以不寫。因為我們上面的代碼中給 value傳值了
                    // 如果當前封裝好的代碼(當作組件)給別人使用的話,使用者可能不穿值
                    if (value) {
                        if (el.value.length > value.len) {
                            if (!el.nextSibling) {
                                const spanDom = document.createElement('span')
                                spanDom.innerHTML = value.msg
                                // 防止初始化數(shù)據(jù)不合法,父節(jié)點不存在
                                el.parentNode?.appendChild(spanDom)
                            }
                        } else {
                            el.nextSibling?.remove()
                        }
                    }
                }
            }
            Vue.directive('validate', (el, { value, modifiers }) => {
                // modifiers:一個包含修飾符的對象 (如果有的話)。
                // console.log(Object.keys(modifiers))===phone
                Object.keys(modifiers).forEach(name => {
                    // 調(diào)用對象中的方法
                    validateMethod[name](el, value)
                })
            })
            const vm1 = new Vue({
                el: '#app',
                data: {
                    phone: '13525125121',
                    email: 'aa@aa.com',
                    str: 'aaa'
                },
                methods: {
                }
            })
        </script>
    </body>
</html>

注意:

v-validate="phone"的 value 值是數(shù)據(jù)源中的 phone,v-validate.phone的 value 值是 undefined,v-validate.str="{len:3,msg:'長度過長'}"的 value 值是{len:3,msg:'長度過長'}。

到此這篇關于Vue自定義指令的使用詳細介紹的文章就介紹到這了,更多相關Vue自定義指令內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • vue中的row布局靠右對齊

    vue中的row布局靠右對齊

    這篇文章主要介紹了vue中的row布局靠右對齊,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-03-03
  • Vue.js axios響應攔截如何獲取返回狀態(tài)碼

    Vue.js axios響應攔截如何獲取返回狀態(tài)碼

    這篇文章主要介紹了Vue.js axios響應攔截如何獲取返回狀態(tài)碼問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-01-01
  • vue中自定義指令directive的詳細指南

    vue中自定義指令directive的詳細指南

    這篇文章主要給大家介紹了關于vue中自定義指令directive的相關資料,自定義指令解決的問題或者說使用場景是對普通 DOM 元素進行底層操作,所以我們不能盲目的胡亂的使用自定義指令,需要的朋友可以參考下
    2021-09-09
  • 一個因@click.stop引發(fā)的bug的解決

    一個因@click.stop引發(fā)的bug的解決

    這篇文章主要介紹了一個因@click.stop引發(fā)的bug的解決,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2019-01-01
  • 深入理解vue $refs的基本用法

    深入理解vue $refs的基本用法

    本篇文章主要介紹了深入理解vue $refs的基本用法 ,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-07-07
  • vite+vue3+element-plus項目搭建的方法步驟

    vite+vue3+element-plus項目搭建的方法步驟

    因為vue3出了一段時間了,element也出了基于vue3.x版本的element-plus,vite打包聽說很快,嘗試一下,感興趣的可以了解一下
    2021-06-06
  • vue項目添加多頁面配置的步驟詳解

    vue項目添加多頁面配置的步驟詳解

    公司使用 vue-cli 創(chuàng)建的 vue項目 在初始化時并沒有做多頁面配置,隨著需求的不斷增加,發(fā)現(xiàn)有必要使用多頁面配置。這篇文章主要介紹了vue項目添加多頁面配置,需要的朋友可以參考下
    2019-05-05
  • vue引入swiper插件的使用實例

    vue引入swiper插件的使用實例

    本篇文章主要介紹了vue引入swiper插件的使用實例,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-07-07
  • Vue中使用this.$set()如何新增數(shù)據(jù),更新視圖

    Vue中使用this.$set()如何新增數(shù)據(jù),更新視圖

    這篇文章主要介紹了Vue中使用this.$set()實現(xiàn)新增數(shù)據(jù),更新視圖方式。具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-06-06
  • vue修改數(shù)據(jù)的時候,表單值回顯不正確問題及解決

    vue修改數(shù)據(jù)的時候,表單值回顯不正確問題及解決

    這篇文章主要介紹了vue修改數(shù)據(jù)的時候,表單值回顯不正確的解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-11-11

最新評論