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

Vue自定義指令directive的使用方法分享

 更新時間:2023年04月13日 16:47:38   作者:口袋の的天空  
這篇文章主要為大家詳細介紹了Vue中自定義指令directive的使用方法,文中的示例代碼講解詳細,感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下

1. 一個指令定義對象可以提供如下幾個鉤子函數(shù)(均為可選)

bind:只調(diào)用一次,指令第一次綁定到元素時調(diào)用。在這里可以進行一次性的初始化設(shè)置。

inserted:被綁定元素插入父節(jié)點時調(diào)用(僅保證父節(jié)點存在,但不一定已被插入文檔中)。

update:只要當前元素不被移除,其他操作幾乎都會觸發(fā)這2個生命周期,先觸發(fā)update后觸發(fā)componentUpdate。虛擬DOM什么時候更新:只要涉及到元素的隱藏、顯示(display)值的改變、內(nèi)容的改變等都會觸發(fā)虛擬DOM更新.

componentUpdated:組件更新

unbind:當使用指令的元素被卸載的時候會執(zhí)行,就是當前元素被移除的時候,只調(diào)用一次

Vue.directive 內(nèi)置了五個鉤子函數(shù) :

bind(綁定觸發(fā))、inserted(插入觸發(fā))、update(更新觸發(fā))、componentUpdated(組件更新觸發(fā))和unbind(解綁觸發(fā))函

 // 注冊
    Vue.directive('my-directive',{
        bind:  function () {},         
        inserted: function () {},
        update: function () {},
        componentUpdated: function () {},
        unbind: function() {}
    })

2.指令鉤子函數(shù)會被傳入以下參數(shù)

el:指定所綁定的元素,可以用來直接操作DOM

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

  • name:指令名,不包含前綴v-
  • value:指令的綁定值,例如:v-my-directive="1+1"中,綁定值為2
  • oldValue:指令綁定的前一個值,僅在update和componentUpdated鉤子中可用,無論值是否改變都可用。
  • expression: 綁定值的字符串形式。 例如 v-my-directive=“1 + 1” , expression 的值是 “1 + 1”。
  • arg: 傳給指令的參數(shù)。例如 v-my-directive:foo, arg 的值是 “foo”。
  • modifiers: 一個包含修飾符的對象。 例如: v-my-directive.foo.bar, 修飾符對象 modifiers 的值是{ foo: true, bar: true }。
  • vnode: Vue 編譯生成的虛擬節(jié)點
  • oldVnode: 上一個虛擬節(jié)點,僅在 update 和 componentUpdated 鉤子中可用

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

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

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

3.使用自定義指令場景的示例

drag.js

import Vue from 'vue'
import { Message } from 'element-ui';


// 自定義指令示例1:彈窗拖拽
Vue.directive('dialogDrag',{
    bind(el,binding,vnode,oldVnode){
        const dialogHeader = el.querySelector('.el-dialog__header');
        const dialogDom = el.querySelector('.el-dialog');
        dialogHeader.style.cursor = 'move'

        /**
         * 不同瀏覽器獲取行內(nèi)樣式屬性
         * ie瀏覽器:       dom元素.currentStyle
         * 火狐瀏覽器:window.getComputedStyle(dom元素, null)
        */
        const sty = dialogDom.currentStyle || window.getComputedStyle(dialogDom, null)

        dialogHeader.onmousedown = (e) => {
            //按下鼠標,獲取點擊的位置 距離 彈窗的左邊和上邊的距離
            //點擊的點距離左邊窗口的距離 - 彈窗距離左邊窗口的距離
            const distX = e.clientX - dialogHeader.offsetLeft;
            const distY = e.clientY - dialogHeader.offsetTop;

            //彈窗的left屬性值和top屬性值
            let styL, styT

            //注意在ie中,第一次獲取到的值為組件自帶50%,移動之后賦值為Px
            if(sty.left.includes('%')){
                styL = +document.body.clientWidth * (+sty.left.replace(/%/g,'') / 100)
                styT = +document,body.clientHeight * (+sty.top.replace(/%/g,'') / 100)
            }else{
                styL = +sty.left.replace(/px/g,'');
                styT = +sty.top.replace(/px/g,'');
            }

            document.onmousemove = function(e) {
                //通過事件委托,計算移動距離
                const l = e.clientX - distX
                const t = e.clientY - distY

                //移動當前的元素
                dialogDom.style.left = `${l + styL}px`
                dialogDom.style.top = `${t + styT}px`
            }

            document.onmouseup = function(e){
                document.onmousemove = null
                document.onmouseup = null
            }
        }
    }
})

//自定義指令示例2:v-dialogDragWidth 可拖動彈窗寬度(右側(cè)邊)
Vue.directive('dragWidth',{
  bind(el) {
      const dragDom = el.querySelector('.el-dialog');
      const lineEl = document.createElement('div');
      lineEl.style = 'width: 5px; background: inherit; height: 80%; position: absolute; right: 0; top: 0; bottom: 0; margin: auto; z-index: 1; cursor: w-resize;';
      lineEl.addEventListener('mousedown',
          function (e) {
              // 鼠標按下,計算當前元素距離可視區(qū)的距離
              const disX = e.clientX - el.offsetLeft;
              // 當前寬度
              const curWidth = dragDom.offsetWidth;
              document.onmousemove = function (e) {
                  e.preventDefault(); // 移動時禁用默認事件
                  // 通過事件委托,計算移動的距離
                  const l = e.clientX - disX;
                  if(l > 0){
                      dragDom.style.width = `${curWidth + l}px`;
                  }
              };
              document.onmouseup = function (e) {
                  document.onmousemove = null;
                  document.onmouseup = null;
              };
          }, false);
      dragDom.appendChild(lineEl);
  }
})

// 自定義指令示例3:v-dialogDragWidth 可拖動彈窗高度(右下角)
Vue.directive('dragHeight',{
  bind(el) {
      const dragDom = el.querySelector('.el-dialog');
      const lineEl = document.createElement('div');
      lineEl.style = 'width: 6px; background: inherit; height: 10px; position: absolute; right: 0; bottom: 0; margin: auto; z-index: 1; cursor: nwse-resize;';
      lineEl.addEventListener('mousedown',
          function(e) {
              // 鼠標按下,計算當前元素距離可視區(qū)的距離
              const disX = e.clientX - el.offsetLeft;
              const disY = e.clientY - el.offsetTop;
              // 當前寬度 高度
              const curWidth = dragDom.offsetWidth;
              const curHeight = dragDom.offsetHeight;
              document.onmousemove = function(e) {
                  e.preventDefault(); // 移動時禁用默認事件
                  // 通過事件委托,計算移動的距離
                  const xl = e.clientX - disX;
                  const yl = e.clientY - disY
                  dragDom.style.width = `${curWidth + xl}px`;
                  dragDom.style.height = `${curHeight + yl}px`;
              };
              document.onmouseup = function(e) {
                  document.onmousemove = null;
                  document.onmouseup = null;
              };
          }, false);
      dragDom.appendChild(lineEl);
  }
})

// 自定義指令示例4:圖片加載前填充背景色
Vue.directive('imgUrl',function(el,binding){
    var color=Math.floor(Math.random()*1000000);//設(shè)置隨機顏色
    el.style.backgroundColor='#'+color;
   
    var img=new Image();
    img.src=binding.value;// -->binding.value指的是指令后的參數(shù)
    img.onload=function(){
      el.style.backgroundColor='';
      el.src=binding.value;      
    }
  })

// 自定義指令示例5:輸入框聚焦
Vue.directive("focus", {
    // 當被綁定的元素插入到 DOM 中時……
    inserted (el) {
        // 聚焦元素
        el.querySelector('input').focus()
    },
  });

// 自定義指令示例6:設(shè)置防抖自定義指令
Vue.directive('throttle', {
    bind: (el, binding) => {
      let setTime = binding.value; // 可設(shè)置防抖時間
      if (!setTime) { // 用戶若不設(shè)置防抖時間,則默認2s
        setTime = 1000;
      }
      let cbFun;
      el.addEventListener('click', event => {
        if (!cbFun) { // 第一次執(zhí)行
          cbFun = setTimeout(() => {
            cbFun = null;
          }, setTime);
        } else {
            /*如果多個事件監(jiān)聽器被附加到相同元素的相同事件類型上,當此事件觸發(fā)時,
            它們會按其被添加的順序被調(diào)用。如果在其中一個事件監(jiān)聽器中執(zhí)行 stopImmediatePropagation() ,那么剩下的事件監(jiān)聽器都不會被調(diào)用*/
          event && event.stopImmediatePropagation();
        }
      }, true);
    },
  });

// 自定義指令示例7:點擊按鈕操作頻繁給出提示
  Vue.directive('preventReClick', {
    inserted: function (el, binding) {
      el.addEventListener('click', () => {
        if (!el.disabled) {
          el.disabled = true
          Message.warning('操作頻繁')
          setTimeout(() => {
            el.disabled = false
            //可設(shè)置時間
          }, binding.value || 3000)
        }
      })
    }
})

main.js中引入文件:

import '@/assets/js/drag.js'

頁面使用:

<template>
  <div>
    <el-button type="text" @click="dialogVisible = true">點擊打開 Dialog</el-button>
    <div style="display:flex">
      <img v-imgUrl="url"></img> 
      <img v-imgUrl="url"></img> 
      <img v-imgUrl="url"></img> 
      <img v-imgUrl="url"></img> 
      <img v-imgUrl="url"></img> 
      <img v-imgUrl="url"></img> 
      <img v-imgUrl="url"></img> 
      <img v-imgUrl="url"></img> 
    </div>
    <div>
      <el-input  placeholder="請選擇日期" suffix-icon="el-icon-date"  v-model="input1"></el-input>
      <el-input v-focus placeholder="請輸入內(nèi)容" prefix-icon="el-icon-search" v-model="input2"></el-input>
    </div>

    <div>
      <el-button type="danger" v-throttle @click="throttleBtn">危險按鈕</el-button>
      <el-button @click="submitForm()">創(chuàng)建</el-button>
    </div>

    <el-dialog title="提示" v-dialogDrag v-dragWidth v-dragHeight :visible.sync="dialogVisible" width="30%" :before-close="handleClose">
      <span>這是一段信息</span>
      <span slot="footer" class="dialog-footer">
        <el-button @click="dialogVisible = false">取 消</el-button>
        <el-button type="primary" @click="dialogVisible = false">確 定</el-button>
      </span>
    </el-dialog>
  </div>
</template>

<script>

export default {

  data() {
    return {
      dialogVisible: false,
      url:'//www.baidu.com/img/flexible/logo/pc/result.png',
      input1: '',
      input2: '',
    }
  },
  methods: {
    handleClose(done) {
      console.log('彈窗打開')  
    },
    throttleBtn(){
      console.log('我的用來測試防抖的按鈕')
    },
    submitForm(){
      this.$message.error('Message 消息提示每次只能1個');
    }
  },
}
</script>
<style>
img{
  width: 100px;
  height: 100px;
}
</style>

看下效果吧:

首先進入頁面,

1.第二個輸入框會鼠標聚焦,

2.點擊按鈕,會有防止重復(fù)點擊

3.圖片加載前有默認背景色

4.彈窗 可以隨處移動。右邊可拖拽變寬,右下角可以整體變大

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

相關(guān)文章

  • 詳解Nuxt.js中使用Element-UI填坑

    詳解Nuxt.js中使用Element-UI填坑

    這篇文章主要介紹了詳解Nuxt.js中使用Element-UI填坑,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-09-09
  • Vue實現(xiàn)網(wǎng)頁首屏加載動畫及頁面內(nèi)請求數(shù)據(jù)加載loading效果

    Vue實現(xiàn)網(wǎng)頁首屏加載動畫及頁面內(nèi)請求數(shù)據(jù)加載loading效果

    Loading加載動畫組件看起來很簡單不重要,實際上它是保證用戶留存的關(guān)鍵一環(huán),下面這篇文章主要給大家介紹了關(guān)于Vue實現(xiàn)網(wǎng)頁首屏加載動畫及頁面內(nèi)請求數(shù)據(jù)加載loading效果的相關(guān)資料,需要的朋友可以參考下
    2023-02-02
  • 詳解關(guān)于vue2.0工程發(fā)布上線操作步驟

    詳解關(guān)于vue2.0工程發(fā)布上線操作步驟

    這篇文章主要介紹了詳解關(guān)于vue2.0工程發(fā)布上線操作步驟,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-09-09
  • Vue項目新一代狀態(tài)管理工具Pinia的使用教程

    Vue項目新一代狀態(tài)管理工具Pinia的使用教程

    pinia是一個輕量級的狀態(tài)管理庫,屬于 vue3 生態(tài)圈新的成員之一,下面這篇文章主要給大家介紹了關(guān)于Vue項目新一代狀態(tài)管理工具Pinia的使用教程,需要的朋友可以參考下
    2022-11-11
  • vue實現(xiàn)el-menu和el-tab聯(lián)動的示例代碼

    vue實現(xiàn)el-menu和el-tab聯(lián)動的示例代碼

    本文主要介紹了vue實現(xiàn)el-menu和el-tab聯(lián)動的示例代碼,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-04-04
  • vue組件強制刷新的4種方案

    vue組件強制刷新的4種方案

    在開發(fā)過程中,有時候會遇到這么一種情況,通過動態(tài)的賦值,但是dom沒有及時更新,能夠獲取到動態(tài)賦的值,但是無法獲取到雙向綁定的dom節(jié)點,這就需要我們手動進行強制刷新組件,下面這篇文章主要給大家介紹了關(guān)于vue組件強制刷新的4種方案,需要的朋友可以參考下
    2023-05-05
  • 使用開源Cesium+Vue實現(xiàn)傾斜攝影三維展示功能

    使用開源Cesium+Vue實現(xiàn)傾斜攝影三維展示功能

    這篇文章主要介紹了使用開源Cesium+Vue實現(xiàn)傾斜攝影三維展示,本文通過實例代碼給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2022-07-07
  • Vue+Java 通過websocket實現(xiàn)服務(wù)器與客戶端雙向通信操作

    Vue+Java 通過websocket實現(xiàn)服務(wù)器與客戶端雙向通信操作

    這篇文章主要介紹了Vue+Java 通過websocket實現(xiàn)服務(wù)器與客戶端雙向通信操作,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-09-09
  • 詳解Vue3.x中組件間參數(shù)傳遞的示例代碼

    詳解Vue3.x中組件間參數(shù)傳遞的示例代碼

    在?Vue3.x?中,組件間的參數(shù)傳遞是構(gòu)建復(fù)雜應(yīng)用時不可或缺的一部分,無論是父子組件還是兄弟組件之間,合理的數(shù)據(jù)流動都是保持應(yīng)用狀態(tài)一致性和可維護性的關(guān)鍵,本文將通過示例代碼,詳細介紹?Vue3.x?中組件間如何傳遞參數(shù),需要的朋友可以參考下
    2024-03-03
  • 從vue源碼看props的用法

    從vue源碼看props的用法

    平時寫vue的時候知道 props 有很多種用法,今天我們來看看vue內(nèi)部是怎么處理 props 中那么多的用法的。非常具有實用價值,需要的朋友可以參考下
    2019-01-01

最新評論