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

vue中自定義指令directive的詳細(xì)指南

 更新時間:2021年09月24日 09:45:55   作者:星空之火@田興  
這篇文章主要給大家介紹了關(guān)于vue中自定義指令directive的相關(guān)資料,自定義指令解決的問題或者說使用場景是對普通 DOM 元素進(jìn)行底層操作,所以我們不能盲目的胡亂的使用自定義指令,需要的朋友可以參考下

一、 什么是自定義指令

我們看到的v-開頭的行內(nèi)屬性,都是指令,不同的指令可以完成或?qū)崿F(xiàn)不同的功能,對普通 DOM元素進(jìn)行底層操作,這時候就會用到自定義指令。除了核心功能默認(rèn)內(nèi)置的指令 (v-model 和 v-show),Vue 也允許注冊自定義指令

指令使用的幾種方式:

//會實例化一個指令,但這個指令沒有參數(shù) 
`v-xxx`
 
// -- 將值傳到指令中
`v-xxx="value"`  
 
// -- 將字符串傳入到指令中,如`v-html="'<p>內(nèi)容</p>'"`
`v-xxx="'string'"` 
 
// -- 傳參數(shù)(`arg`),如`v-bind:class="className"`
`v-xxx:arg="value"` 
 
// -- 使用修飾符(`modifier`)
`v-xxx:arg.modifier="value"` 

二、 如何自定義指令

注冊一個自定義指令有全局注冊與局部注冊

全局注冊注冊主要是用過Vue.directive方法進(jìn)行注冊

Vue.directive第一個參數(shù)是指令的名字(不需要寫上v-前綴),第二個參數(shù)可以是對象數(shù)據(jù),也可以是一個指令函數(shù)

// 注冊一個全局自定義指令 `v-focus`
Vue.directive('focus', {
  // 當(dāng)被綁定的元素插入到 DOM 中時……
  inserted: function (el) {
    // 聚焦元素
    el.focus()  // 頁面加載完成之后自動讓輸入框獲取到焦點的小功能
  }
})

局部注冊通過在組件options選項中設(shè)置directive屬性

directives: {
  focus: {
    // 指令的定義
    inserted: function (el) {
      el.focus() // 頁面加載完成之后自動讓輸入框獲取到焦點的小功能
    }
  }
}

然后你可以在模板中任何元素上使用新的 v-focus property,如下:

<input v-focus />

鉤子函數(shù)

自定義指令也像組件那樣存在鉤子函數(shù):

  • bind:只調(diào)用一次,指令第一次綁定到元素時調(diào)用。在這里可以進(jìn)行一次性的初始化設(shè)置
  • inserted:被綁定元素插入父節(jié)點時調(diào)用 (僅保證父節(jié)點存在,但不一定已被插入文檔中)
  • update:所在組件的 VNode 更新時調(diào)用,但是可能發(fā)生在其子 VNode更新之前。指令的值可能發(fā)生了改變,也可能沒有。但是你可以通過比較更新前后的值來忽略不必要的模板更新
  • componentUpdated:指令所在組件的 VNode 及其子 VNode 全部更新后調(diào)用
  • unbind:只調(diào)用一次,指令與元素解綁時調(diào)用

所有的鉤子函數(shù)的參數(shù)都有以下:

  • el:指令所綁定的元素,可以用來直接操作 DOM
  • binding:一個對象,包含以下 property:

`name`:指令名,不包括 v- 前綴。

`value`:指令的綁定值,例如:v-my-directive="1 + 1" 中,綁定值為 2。

`oldValue`:指令綁定的前一個值,僅在 update 和 componentUpdated 鉤子中可用。無論值是否改變都可用。

`expression`:字符串形式的指令表達(dá)式。例如 v-my-directive="1 + 1" 中,表達(dá)式為 "1 + 1"。

`arg`:傳給指令的參數(shù),可選。例如 v-my-directive:foo 中,參數(shù)為 "foo"。

`modifiers`:一個包含修飾符的對象。例如:v-my-directive.foo.bar 中,修飾符對象為 { foo: true, bar: true }

`vnode`:Vue 編譯生成的虛擬節(jié)點

`oldVnode`:上一個虛擬節(jié)點,僅在 update 和 componentUpdated 鉤子中可用

除了 el 之外,其它參數(shù)都應(yīng)該是只讀的,切勿進(jìn)行修改。如果需要在鉤子之間共享數(shù)據(jù),建議通過元素的 dataset 來進(jìn)行

舉個例子:

<div v-demo="{ color: 'white', text: 'hello!' }"></div>
<script>
    Vue.directive('demo', function (el, binding) {
    console.log(binding.value.color) // "white"
    console.log(binding.value.text)  // "hello!"
    })
</script>

三、應(yīng)用場景

使用自定義組件組件可以滿足我們?nèi)粘R恍﹫鼍埃@里給出幾個自定義組件的案例:

  • 防抖
  • 圖片懶加載
  • 一鍵 Copy的功能

輸入框防抖

防抖這種情況設(shè)置一個v-throttle自定義指令來實現(xiàn)

舉個例子:

// 1.設(shè)置v-throttle自定義指令
Vue.directive('throttle', {
  bind: (el, binding) => {
    let throttleTime = binding.value; // 防抖時間
    if (!throttleTime) { // 用戶若不設(shè)置防抖時間,則默認(rèn)2s
      throttleTime = 2000;
    }
    let cbFun;
    el.addEventListener('click', event => {
      if (!cbFun) { // 第一次執(zhí)行
        cbFun = setTimeout(() => {
          cbFun = null;
        }, throttleTime);
      } else {
        event && event.stopImmediatePropagation();
      }
    }, true);
  },
});
// 2.為button標(biāo)簽設(shè)置v-throttle自定義指令
<button @click="sayHello" v-throttle>提交</button>

圖片懶加載

設(shè)置一個v-lazy自定義組件完成圖片懶加載

const LazyLoad = {
    // install方法
    install(Vue,options){
       // 代替圖片的loading圖
        let defaultSrc = options.default;
        Vue.directive('lazy',{
            bind(el,binding){
                LazyLoad.init(el,binding.value,defaultSrc);
            },
            inserted(el){
                // 兼容處理
                if('InterpObserver' in window){
                    LazyLoad.observe(el);
                }else{
                    LazyLoad.listenerScroll(el);
                }
                
            },
        })
    },
    // 初始化
    init(el,val,def){
        // src 儲存真實src
        el.setAttribute('src',val);
        // 設(shè)置src為loading圖
        el.setAttribute('src',def);
    },
    // 利用InterpObserver監(jiān)聽el
    observe(el){
        let io = new InterpObserver(entries => {
            let realSrc = el.dataset.src;
            if(entries[0].isIntersecting){
                if(realSrc){
                    el.src = realSrc;
                    el.removeAttribute('src');
                }
            }
        });
        io.observe(el);
    },
    // 監(jiān)聽scroll事件
    listenerScroll(el){
        let handler = LazyLoad.throttle(LazyLoad.load,300);
        LazyLoad.load(el);
        window.addEventListener('scroll',() => {
            handler(el);
        });
    },
    // 加載真實圖片
    load(el){
        let windowHeight = document.documentElement.clientHeight
        let elTop = el.getBoundingClientRect().top;
        let elBtm = el.getBoundingClientRect().bottom;
        let realSrc = el.dataset.src;
        if(elTop - windowHeight<0&&elBtm > 0){
            if(realSrc){
                el.src = realSrc;
                el.removeAttribute('src');
            }
        }
    },
    // 節(jié)流
    throttle(fn,delay){
        let timer; 
        let prevTime;
        return function(...args){
            let currTime = Date.now();
            let context = this;
            if(!prevTime) prevTime = currTime;
            clearTimeout(timer);
            
            if(currTime - prevTime > delay){
                prevTime = currTime;
                fn.apply(context,args);
                clearTimeout(timer);
                return;
            }
 
            timer = setTimeout(function(){
                prevTime = Date.now();
                timer = null;
                fn.apply(context,args);
            },delay);
        }
    }
 
}
export default LazyLoad;

一鍵 Copy的功能

import { Message } from 'ant-design-vue';
 
const vCopy = { //
  /*
    bind 鉤子函數(shù),第一次綁定時調(diào)用,可以在這里做初始化設(shè)置
    el: 作用的 dom 對象
    value: 傳給指令的值,也就是我們要 copy 的值
  */
  bind(el, { value }) {
    el.$value = value; // 用一個全局屬性來存?zhèn)鬟M(jìn)來的值,因為這個值在別的鉤子函數(shù)里還會用到
    el.handler = () => {
      if (!el.$value) {
      // 值為空的時候,給出提示,我這里的提示是用的 ant-design-vue 的提示,你們隨意
        Message.warning('無復(fù)制內(nèi)容');
        return;
      }
      // 動態(tài)創(chuàng)建 textarea 標(biāo)簽
      const textarea = document.createElement('textarea');
      // 將該 textarea 設(shè)為 readonly 防止 iOS 下自動喚起鍵盤,同時將 textarea 移出可視區(qū)域
      textarea.readOnly = 'readonly';
      textarea.style.position = 'absolute';
      textarea.style.left = '-9999px';
      // 將要 copy 的值賦給 textarea 標(biāo)簽的 value 屬性
      textarea.value = el.$value;
      // 將 textarea 插入到 body 中
      document.body.appendChild(textarea);
      // 選中值并復(fù)制
      textarea.select();
      // textarea.setSelectionRange(0, textarea.value.length);
      const result = document.execCommand('Copy');
      if (result) {
        Message.success('復(fù)制成功');
      }
      document.body.removeChild(textarea);
    };
    // 綁定點擊事件,就是所謂的一鍵 copy 啦
    el.addEventListener('click', el.handler);
  },
  // 當(dāng)傳進(jìn)來的值更新的時候觸發(fā)
  componentUpdated(el, { value }) {
    el.$value = value;
  },
  // 指令與元素解綁的時候,移除事件綁定
  unbind(el) {
    el.removeEventListener('click', el.handler);
  },
};
 
export default vCopy;

拖拽

<div ref="a" id="bg" v-drag></div>

  directives: {
    drag: {
      bind() {},
      inserted(el) {
        el.onmousedown = (e) => {
          let x = e.clientX - el.offsetLeft;
          let y = e.clientY - el.offsetTop;
          document.onmousemove = (e) => {
            let xx = e.clientX - x + "px";
            let yy = e.clientY - y + "px";
            el.style.left = xx;
            el.style.top = yy;
          };
          el.onmouseup = (e) => {
            document.onmousemove = null;
          };
        };
      },
    },
  },

關(guān)于自定義組件還有很多應(yīng)用場景,如:拖拽指令、頁面水印、權(quán)限校驗等等應(yīng)用場景

總結(jié)

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

相關(guān)文章

  • VUE axios上傳圖片到七牛的實例代碼

    VUE axios上傳圖片到七牛的實例代碼

    本篇文章主要介紹了VUE axios上傳圖片到七牛的實例代碼,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-07-07
  • vuex學(xué)習(xí)之Actions的用法詳解

    vuex學(xué)習(xí)之Actions的用法詳解

    本篇文章主要介紹了vuex學(xué)習(xí)之Actions的用法詳解,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-08-08
  • Vue開發(fā)中常見的套路和技巧總結(jié)

    Vue開發(fā)中常見的套路和技巧總結(jié)

    這篇文章主要給大家介紹了關(guān)于Vue開發(fā)中常見的套路和技巧的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-11-11
  • vue.js做一個簡單的編輯菜譜功能

    vue.js做一個簡單的編輯菜譜功能

    本文通過實例代碼給大家一個簡單的基于vue.js實現(xiàn)的編輯菜譜功能,代碼簡答易懂,非常不錯,具有參考借鑒價值,需要的朋友參考下吧
    2018-05-05
  • 解決在vue的mounted中獲取對象為null問題

    解決在vue的mounted中獲取對象為null問題

    這篇文章主要介紹了解決在vue的mounted中獲取對象為null問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-03-03
  • Vue自定義表單驗證(rule,value,callback)使用詳解

    Vue自定義表單驗證(rule,value,callback)使用詳解

    這篇文章主要介紹了Vue自定義表單驗證(rule,value,callback)使用詳解,今天我們講一講自定義驗證規(guī)則具體使用場景和它的三個參數(shù)意思和使用,需要的朋友可以參考下
    2023-07-07
  • 詳解Vue 事件驅(qū)動和依賴追蹤

    詳解Vue 事件驅(qū)動和依賴追蹤

    本篇文章主要介紹了詳解Vue 事件驅(qū)動和依賴追蹤 ,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-04-04
  • vue中$emit傳遞多個參(arguments和$event)

    vue中$emit傳遞多個參(arguments和$event)

    本文主要介紹了vue中$emit傳遞多個參(arguments和$event),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-02-02
  • vue如何設(shè)置定時器和清理定時器

    vue如何設(shè)置定時器和清理定時器

    這篇文章主要介紹了vue如何設(shè)置定時器和清理定時器,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-05-05
  • Vue.js學(xué)習(xí)記錄之在元素與template中使用v-if指令實例

    Vue.js學(xué)習(xí)記錄之在元素與template中使用v-if指令實例

    這篇文章主要給大家介紹了關(guān)于Vue.js學(xué)習(xí)記錄之在元素與template中使用v-if指令的相關(guān)資料,文中給出了詳細(xì)的示例代碼供大家參考學(xué)習(xí),相信對大家具有一定的參考學(xué)習(xí)價值,需要的朋友們下面來一起看看吧。
    2017-06-06

最新評論