最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

詳解Vue自定義指令及使用

 更新時(shí)間:2021年05月11日 16:14:35   作者:sugar_coffee  
這篇文章主要介紹了Vue自定義指令及使用,對(duì)Vue感興趣的同學(xué),可以參考下

一、什么是指令

學(xué)習(xí) vue 的時(shí)候肯定會(huì)接觸指令,那么什么是指令呢?

在 vue 中提供了一些對(duì)于頁面和數(shù)據(jù)更為方便的輸出,這些操作就叫做指令,以 v-xxx 表示,比如 html 頁面中的屬性 <div v-xxx ></div>

比如在 angular 中 以 ng-xxx 開頭的就叫做指令

指令中封裝了一些 DOM 行為,結(jié)合屬性作為一個(gè)暗號(hào),暗號(hào)有對(duì)應(yīng)的值,根據(jù)不同的值,會(huì)進(jìn)行相關(guān) DOM 操作的綁定,即可以進(jìn)行一些模板的操作

vue 中常用的一些內(nèi)置 v- 指令

  • v-text:元素的 innerText 屬性,只能用在雙標(biāo)簽中, 和{{ }}效果是一樣的,使用較少
  • v-html:元素的 innerHTML,其實(shí)就是給元素的 innerHTML 賦值
  • v-show:元素的顯示與隱藏,基于 css 樣式的切換。如果確定要隱藏,會(huì)給元素的 style 加上display: none
  • v-if:元素的插入和移除操作,相當(dāng)于對(duì)元素的銷毀和創(chuàng)建。如果表達(dá)式的值為 false,會(huì)留下一個(gè) <!----> 作為標(biāo)記,若未來 v-if 的值是 true 了,就在這里插入元素(如果 if 有 else 就不要單獨(dú)留坑了)。
  • v-else-if:前一個(gè)相鄰元素必須有 v-if 或 v-else-if
  • v-else:前一個(gè)相鄰元素必須有 v-if 或 v-else-if,如果 v-if 和 v-else-if 都有對(duì)應(yīng)的表達(dá)式,則 v-else 可以直接寫
  • v-for:用于循環(huán)渲染一組數(shù)據(jù)(數(shù)組或?qū)ο?。必須使用特定語法:v-for="alias in expression"。注:當(dāng) v-for 和 v-if 同處于一個(gè)節(jié)點(diǎn)時(shí),v-for 的優(yōu)先級(jí)比 v-if 更高。即 v-if 將運(yùn)行在每個(gè) v-for循環(huán)中
  • v-on:主要用來監(jiān)聽 dom 時(shí)間,然后執(zhí)行一些操作。簡(jiǎn)寫為【@】
  • v-model:用于 input/textarea 等表單控件上創(chuàng)建雙向數(shù)據(jù)綁定。
  • v-bind:動(dòng)態(tài)的綁定一個(gè)或多個(gè)屬性,常用于綁定 class,style,href 等。
  • v-once:組件和元素只渲染一次,當(dāng)數(shù)據(jù)發(fā)生變化,也不會(huì)重新渲染。

v-if 和 v-show 的對(duì)比

  • v-if 是真正的條件渲染,因?yàn)樗鼤?huì)確保在切換過程中條件塊內(nèi)的事件監(jiān)聽器和子組件適當(dāng)?shù)谋讳N毀和重建。
  • v-if 也是惰性的,如果在初始渲染時(shí)條件為假,則什么也不做,直到條件第一次為真時(shí),才會(huì)開始渲染條件塊。
  • 相比之下 v-show 就簡(jiǎn)單的多,不管初始條件是什么,元素總是會(huì)被渲染,并且只是簡(jiǎn)單的基于 css 進(jìn)行切換。

一般來說,v-if 有更高的切換開銷,而 v-show 有更高的初始渲染開銷。因此,如果需要非常頻繁的切換,則使用 v-show 較好,如果在運(yùn)行時(shí)條件很少改變,則使用 v-if 較好。

在實(shí)際的開發(fā)過程中,可能這些內(nèi)置指令并不能滿足所有的需求,或者說想為元素附件一些特別的功能。這時(shí)候,就需要用到 Vue 給我們提供的一個(gè)強(qiáng)大又靈活的功能「 自定義指令 」。

官方api 文檔里有這么一句話:對(duì)普通 DOM 元素進(jìn)行底層操作,這時(shí)候就會(huì)用到自定義指令。也就是說自定義指令解決的問題或者說使用場(chǎng)景是對(duì)普通 DOM 元素進(jìn)行底層操作,所以我們不能盲目的胡亂的使用自定義指令。

二、自定義指令的鉤子函數(shù)

Vue 提供了自定義指令的5個(gè)鉤子函數(shù):

  • bind:指令第一次綁定到元素時(shí)調(diào)用,只執(zhí)行一次。在這里可以進(jìn)行一次性的初始化設(shè)置。
  • inserted:被綁定的元素,插入到父節(jié)點(diǎn)的 DOM 中時(shí)調(diào)用(僅保證父節(jié)點(diǎn)存在)。
  • update:組件更新時(shí)調(diào)用。
  • componentUpdated:組件與子組件更新時(shí)調(diào)用。
  • unbind:指令與元素解綁時(shí)調(diào)用,只執(zhí)行一次。

注意:

1.除 update 與 componentUpdated 鉤子函數(shù)之外,每個(gè)鉤子函數(shù)都含有 el、binding、vnode 這三個(gè)參數(shù)

2.在每個(gè)函數(shù)中,第一個(gè)參數(shù)永遠(yuǎn)是 el, 表示被綁定了指令的那個(gè) dom 元素,這個(gè)el 參數(shù),是一個(gè)原生的 JS 對(duì)象,所以 Vue 自定義指令可以用來直接和 DOM 打交道

3.binding 是一個(gè)對(duì)象,它包含以下屬性:name、value、oldValue、expression、arg、modifiers

4.oldVnode 只有在 update 與 componentUpdated 鉤子中生效

5.除了 el 之外,binding、vnode 屬性都是只讀的

鉤子函數(shù)說白了也就是生命周期,即當(dāng)一個(gè)指令綁定到一個(gè)元素上時(shí),這個(gè)指令內(nèi)部有5個(gè)生命周期事件函數(shù)。接下來創(chuàng)建一個(gè)案例來看看這幾個(gè)鉤子函數(shù)的觸發(fā)情況:

<p v-test>這是一段文字</p>
​
export default {
    ... ...
    directives: {
        test: {
              bind () {
                console.log('bind')
              },
              inserted () {
                console.log('inserted')
              },
              update () {
                console.log('update')
              },
              componentUpdated () {
                console.log('componentUpdated')
              },
              unbind () {
                console.log('unbind')
              }
        }
    }
}

結(jié)果:

頁面渲染時(shí),觸發(fā)了 bind 和inserted 函數(shù)。那么另外三個(gè)鉤子函數(shù)什么時(shí)候會(huì)觸發(fā)呢?

關(guān)于 update 的官方解釋:

update:所在組件的 VNode 更新時(shí)調(diào)用,但是可能發(fā)生在其子 VNode 更新之前。指令的值可能發(fā)生了改變,也可能沒有。但是你可以通過比較更新前后的值來忽略不必要的模板更新 (詳細(xì)的鉤子函數(shù)參數(shù)見下)。

有點(diǎn)疑惑,‘ 所在組件的 VNode ' 是指當(dāng)前綁定了該指令的 dom 元素嗎?如果是的話,是不是只要當(dāng)前元素的狀態(tài)發(fā)生了變化就會(huì)觸發(fā) update 呢?如下通過 v-show 來切換元素顯示隱藏:

<p v-test v-show="show">這是另外一段文字</p>
<button @click="show = !show">toggle</button>

export default {
  data () {
    return {
      show: true
    }
  }
}

默認(rèn)還是觸發(fā) bind 和inserted ,當(dāng)點(diǎn)擊按鈕切換元素的 display 時(shí),結(jié)果如下:

即:改變?cè)氐臉邮降臅r(shí)候觸發(fā)了 update 和componentUpdated 函數(shù)。如果使用 v-if 會(huì)觸發(fā)哪個(gè)事件呢?

<p v-test v-if="show">這是另外一段文字</p>
<button @click="show = !show">toggle</button>

結(jié)果:

發(fā)現(xiàn) unbind 被觸發(fā),因?yàn)?v-if 是刪除或者重建 dom 元素,當(dāng)指令綁定的元素被銷毀時(shí),會(huì)觸發(fā)指令的 unbind 事件,新建顯示仍是觸發(fā) bind 和inserted 。

總結(jié):

  • bind():當(dāng)指令綁定在 HTML 元素上時(shí)觸發(fā)
  • inserted():當(dāng)指令綁定的元素插入到父節(jié)點(diǎn)中的時(shí)候觸發(fā)
  • update():當(dāng)指令綁定的元素狀態(tài)/樣式、內(nèi)容(這里指元素綁定的 vue 數(shù)據(jù)) 發(fā)生改變時(shí)觸發(fā)
  • componentUpdated():當(dāng) update() 執(zhí)行完畢之后觸發(fā)
  • unbind():當(dāng)指令綁定的元素從 dom 中刪除時(shí)觸發(fā)

舉幾個(gè)應(yīng)用場(chǎng)景的栗子

1、輸入框自動(dòng)獲取焦點(diǎn)(官方示例)。

2、點(diǎn)擊下拉菜單以外的區(qū)域隱藏菜單。

3、輸入的郵箱、電話的校驗(yàn)。

上面這幾個(gè)場(chǎng)合,在做項(xiàng)目的時(shí)候可以用其他方法代替,但是 vue 自定義指令能做到一處定義,全局調(diào)用,使得代碼簡(jiǎn)潔高效,更便于維護(hù)。

指令的注冊(cè)方式和「過濾器」「混入」「組件」注冊(cè)的方式一樣都分為兩種:一是全局注冊(cè),二是局部注冊(cè)。

三、全局指令

// 給元素添加隨機(jī)背景
<div v-bgcolor></div>
   
Vue.directive('bgcolor', {
    bind: function(el, binding, vnode) {
        el.style.backgroundColor = "#" + Math.random().toString(16).slice(2,8);
    }
})

注意:在定義的時(shí)候,指令的名稱前面不需要加 v- 前綴,在調(diào)用的時(shí)候,必須在指定的名稱前加上 v-前綴來進(jìn)行調(diào)用

四、局部指令

// 和data, methods同級(jí)
methods: {},
directives: {
    bgcolor: {
         bind: function(el, binding) {
            el.style.backgroundColor = "#" + Math.random().toString(16).slice(2,8);
        }
    }
}

我個(gè)人更傾向于使用全局注冊(cè)的方式,因?yàn)榧热灰呀?jīng)使用了自定義指令,應(yīng)該是通用的可復(fù)用的。所以提供整個(gè)項(xiàng)目使用的指令才更有價(jià)值,而不僅僅只限于某個(gè)組件內(nèi)部。如果單一地方使用直接把功能摟出來就行了,何必費(fèi)這力氣。

五、帶參數(shù)的自定義指令

<div v-bgcolor='{color: 'orange'}'></div>

Vue.directive('bgcolor', {
    bind: function(el, binding) {
        el.style.backgroundColor = binding.value.color;
    }
})

六、函數(shù)簡(jiǎn)寫

如果想在 bind 和 update 時(shí)觸發(fā)相同行為,而不關(guān)心其它的鉤子,可以這樣寫:

// 全局
Vue.directive('bgcolor', function (el, binding) {
      el.style.backgroundColor = binding.value
})

// 局部
directives: {
    bgcolor: (el, binding) => {
        el.style.backgroundColor = binding.value  
    }
}

七、應(yīng)用實(shí)例

熟悉指令的創(chuàng)建方式與參數(shù)之后,我們就用它來創(chuàng)建兩個(gè)實(shí)際案例。

通過指令來實(shí)現(xiàn)點(diǎn)擊空白處子菜單隱藏的功能,具體代碼如下:

// clickOutside.js
export default {
    bind (el, binding) {
        const self = {} // 定義一個(gè)私有變量,方便在unbind中可以解除事件監(jiān)聽
        self.documentHandler = (e) => {
            if (el.contains(e.target)) { // 這里判斷綁定的元素是否包含點(diǎn)擊元素,如果包含則返回
                return false
            }
            if (binding.value) { // 判斷指令中是否綁定了值
                binding.value(e) // 如果綁定了函數(shù)則調(diào)用那個(gè)函數(shù),此處 binding.value就是handleClose方法
            }
            return true
        }
        document.addEventListener('click', self.documentHandler)
    },
    unbind (el) {
        // 解除事件監(jiān)聽
        document.removeEventListener('click', self.documentHandler)
        delete self.documentHandler
    }
}

在組件中使用:

<template>
    <div>
        <div v-show="isShow" v-clickoutside="handleClickOutside" @click="showOrHide">
            子菜單 ... 
        </div>
    </div>
</template>
​
<script>
    import clickoutside from './js/clickOutside'
    
    export default {
        ... ...
        directives: {
            clickoutside
        },
        data() {
            return {
                isShow: true,
            };
        },
        methods: {
            handleOutsideClick () {
                this.isShow = false
            }
        }
    }
</script>

自定義指令來優(yōu)化圖片的加載:圖片在加載過程中,未加載完成時(shí)使用灰色背景占位,圖片加載完后直接顯示

<template>
    <div>
        <!-- 參數(shù)不可以直接填寫url地址-->
        <img v-imgUrl='url' /> 
    </div>
</template>
​
<script>
    export default {
        data () {
            return {
                url: '../src/assets/logo.png'
            }
        }
    }
</script>

// 全局注冊(cè)
Vue.directive('imgUrl', function (el, binding) {
    el.style.backgroundColor = '#FEFEFE' //設(shè)置背景顏色
    var img = new Image()
    img.src = binding.value // binding.value 指令后的參數(shù)
    img.onload = function () {
        el.style.backgroundColor = ''
        el.src = binding.value
    }
})

以上就是詳解Vue自定義指令及使用的詳細(xì)內(nèi)容,更多關(guān)于Vue的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • Vue中對(duì)比scoped css和css module的區(qū)別

    Vue中對(duì)比scoped css和css module的區(qū)別

    這篇文章主要介紹了Vue中scoped css和css module的區(qū)別對(duì)比,scoped css可以直接在能跑起來的vue項(xiàng)目中使用而css module需要增加css-loader配置才能生效。具體內(nèi)容詳情大家參考下本文
    2018-05-05
  • Element?table?上下移需求的實(shí)現(xiàn)

    Element?table?上下移需求的實(shí)現(xiàn)

    本文主要介紹了Element?table?上下移需求的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2022-07-07
  • Vue3路由配置createRouter、createWebHistory、useRouter和useRoute詳解

    Vue3路由配置createRouter、createWebHistory、useRouter和useRoute詳解

    Vue3和Vue2基本差不多,只不過需要將createRouter、createWebHistory從vue-router中引入,再進(jìn)行使用,下面這篇文章主要給大家介紹了關(guān)于Vue3路由配置createRouter、createWebHistory、useRouter和useRoute的相關(guān)資料,需要的朋友可以參考下
    2023-02-02
  • Vue ECharts簡(jiǎn)易實(shí)現(xiàn)雷達(dá)圖

    Vue ECharts簡(jiǎn)易實(shí)現(xiàn)雷達(dá)圖

    這篇文章主要介紹了基于Vue ECharts簡(jiǎn)易實(shí)現(xiàn)雷達(dá)圖,本文通過實(shí)例代碼圖文相結(jié)合給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-12-12
  • 教你如何在 Nuxt 3 中使用 wavesurfer.js

    教你如何在 Nuxt 3 中使用 wavesurfer.js

    這篇文章主要介紹了如何在 Nuxt 3 中使用 wavesurfer.js,本文結(jié)合實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2023-01-01
  • Vue3利用自定義ref實(shí)現(xiàn)防抖功能

    Vue3利用自定義ref實(shí)現(xiàn)防抖功能

    在Vue3中,ref提供了訪問組件內(nèi)DOM元素和子組件實(shí)例的方法,防抖是一種限制函數(shù)調(diào)用頻率的方法,即在一定時(shí)間內(nèi)多次觸發(fā)同一個(gè)函數(shù),只執(zhí)行最后一次觸發(fā)的函數(shù),本文將給大家介紹了Vue3如何利用自定義ref實(shí)現(xiàn)防抖,需要的朋友可以參考下
    2024-05-05
  • 一文帶你搞懂Vue?Loader是如何工作的

    一文帶你搞懂Vue?Loader是如何工作的

    Vue?Loader?作為一個(gè)?webpack?的?Loader,扮演著將?.vue?文件轉(zhuǎn)化為瀏覽器可執(zhí)行代碼的角色,下面就跟隨小編一起深入了解Vue?Loader?的技術(shù)細(xì)節(jié)與工作機(jī)制吧
    2024-12-12
  • vue遞歸組件實(shí)現(xiàn)elementUI多級(jí)菜單

    vue遞歸組件實(shí)現(xiàn)elementUI多級(jí)菜單

    這篇文章主要為大家詳細(xì)介紹了vue遞歸組件實(shí)現(xiàn)elementUI多級(jí)菜單,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-07-07
  • Vue.js中實(shí)現(xiàn)密碼修改及頁面跳轉(zhuǎn)和刷新的完整指南

    Vue.js中實(shí)現(xiàn)密碼修改及頁面跳轉(zhuǎn)和刷新的完整指南

    在現(xiàn)代Web應(yīng)用中,用戶賬戶管理是一個(gè)核心功能,其中密碼修改是一個(gè)常見的需求,本文將詳細(xì)介紹如何在Vue.js應(yīng)用中實(shí)現(xiàn)用戶密碼修改功能,并在成功后跳轉(zhuǎn)到登錄頁面并刷新該頁面,需要的朋友可以參考下
    2024-12-12
  • 在Vue中使用Echarts+封裝

    在Vue中使用Echarts+封裝

    這篇文章主要介紹了在Vue中使用Echarts++封裝,需要的朋友可以參考下
    2023-11-11

最新評(píng)論

曲周县| 南充市| 枝江市| 建德市| 吉安县| 邵武市| 宿州市| 望城县| 鸡东县| 博野县| 外汇| 理塘县| 娄底市| 蓬安县| 崇仁县| 克什克腾旗| 略阳县| 宁明县| 宾阳县| 桃源县| 七台河市| 泽库县| 罗山县| 丰县| 澄城县| 福建省| 买车| 商水县| 和田市| 宁国市| 博野县| 卢氏县| 凤台县| 麻栗坡县| 肇东市| 郴州市| 五家渠市| 华坪县| 无极县| 东乡县| 綦江县|