五月天青色头像情侣网名,国产亚洲av片在线观看18女人,黑人巨茎大战俄罗斯美女,扒下她的小内裤打屁股

歡迎光臨散文網(wǎng) 會(huì)員登陸 & 注冊

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

2023-04-14 20:12 作者:技術(shù)之心  | 我要投稿

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

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

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

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

componentUpdated:組件更新

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

Vue.directive 內(nèi)置了五個(gè)鉤子函數(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ù)會(huì)被傳入以下參數(shù)

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

binding:一個(gè)對象,包含以下屬性:

  • name:指令名,不包含前綴v-

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

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

  • expression: 綁定值的字符串形式。 例如 v-my-directive=“1 + 1” , expression 的值是 “1 + 1”。

  • arg: 傳給指令的參數(shù)。例如 v-my-directive:foo, arg 的值是 “foo”。

  • modifiers: 一個(gè)包含修飾符的對象。 例如: v-my-directive.foo.bar, 修飾符對象 modifiers 的值是{ foo: true, bar: true }。

  • vnode: Vue 編譯生成的虛擬節(jié)點(diǎn)

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

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

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

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

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) => {
????????????//按下鼠標(biāo),獲取點(diǎn)擊的位置 距離 彈窗的左邊和上邊的距離
????????????//點(diǎn)擊的點(diǎn)距離左邊窗口的距離 - 彈窗距離左邊窗口的距離
????????????const distX = e.clientX - dialogHeader.offsetLeft;
????????????const distY = e.clientY - dialogHeader.offsetTop;
?
????????????//彈窗的left屬性值和top屬性值
????????????let styL, styT
?
????????????//注意在ie中,第一次獲取到的值為組件自帶50%,移動(dòng)之后賦值為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) {
????????????????//通過事件委托,計(jì)算移動(dòng)距離
????????????????const l = e.clientX - distX
????????????????const t = e.clientY - distY
?
????????????????//移動(dòng)當(dāng)前的元素
????????????????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 可拖動(dòng)彈窗寬度(右側(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) {
??????????????// 鼠標(biāo)按下,計(jì)算當(dāng)前元素距離可視區(qū)的距離
??????????????const disX = e.clientX - el.offsetLeft;
??????????????// 當(dāng)前寬度
??????????????const curWidth = dragDom.offsetWidth;
??????????????document.onmousemove = function (e) {
??????????????????e.preventDefault(); // 移動(dòng)時(shí)禁用默認(rèn)事件
??????????????????// 通過事件委托,計(jì)算移動(dòng)的距離
??????????????????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 可拖動(dòng)彈窗高度(右下角)
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) {
??????????????// 鼠標(biāo)按下,計(jì)算當(dāng)前元素距離可視區(qū)的距離
??????????????const disX = e.clientX - el.offsetLeft;
??????????????const disY = e.clientY - el.offsetTop;
??????????????// 當(dāng)前寬度 高度
??????????????const curWidth = dragDom.offsetWidth;
??????????????const curHeight = dragDom.offsetHeight;
??????????????document.onmousemove = function(e) {
??????????????????e.preventDefault(); // 移動(dòng)時(shí)禁用默認(rèn)事件
??????????????????// 通過事件委托,計(jì)算移動(dòng)的距離
??????????????????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è)置隨機(jī)顏色
????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", {
????// 當(dāng)被綁定的元素插入到 DOM 中時(shí)……
????inserted (el) {
????????// 聚焦元素
????????el.querySelector('input').focus()
????},
??});
?
// 自定義指令示例6:設(shè)置防抖自定義指令
Vue.directive('throttle', {
????bind: (el, binding) => {
??????let setTime = binding.value; // 可設(shè)置防抖時(shí)間
??????if (!setTime) { // 用戶若不設(shè)置防抖時(shí)間,則默認(rèn)2s
????????setTime = 1000;
??????}
??????let cbFun;
??????el.addEventListener('click', event => {
????????if (!cbFun) { // 第一次執(zhí)行
??????????cbFun = setTimeout(() => {
????????????cbFun = null;
??????????}, setTime);
????????} else {
????????????/*如果多個(gè)事件監(jiān)聽器被附加到相同元素的相同事件類型上,當(dāng)此事件觸發(fā)時(shí),
????????????它們會(huì)按其被添加的順序被調(diào)用。如果在其中一個(gè)事件監(jiān)聽器中執(zhí)行 stopImmediatePropagation() ,那么剩下的事件監(jiān)聽器都不會(huì)被調(diào)用*/
??????????event && event.stopImmediatePropagation();
????????}
??????}, true);
????},
??});
?
// 自定義指令示例7:點(diǎn)擊按鈕操作頻繁給出提示
??Vue.directive('preventReClick', {
????inserted: function (el, binding) {
??????el.addEventListener('click', () => {
????????if (!el.disabled) {
??????????el.disabled = true
??????????Message.warning('操作頻繁')
??????????setTimeout(() => {
????????????el.disabled = false
????????????//可設(shè)置時(shí)間
??????????}, binding.value || 3000)
????????}
??????})
????}
})

main.js中引入文件:

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

頁面使用:


<template>
??<div>
????<el-button type="text" @click="dialogVisible = true">點(diǎn)擊打開 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">危險(xiǎn)按鈕</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個(gè)');
????}
??},
}
</script>
<style>
img{
??width: 100px;
??height: 100px;
}
</style>

看下效果吧:

首先進(jìn)入頁面,

1.第二個(gè)輸入框會(huì)鼠標(biāo)聚焦,

2.點(diǎn)擊按鈕,會(huì)有防止重復(fù)點(diǎn)擊

3.圖片加載前有默認(rèn)背景色

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


Vue自定義指令directive的使用方法分享的評論 (共 條)

分享到微博請遵守國家法律
枣庄市| 云南省| 清远市| 睢宁县| 武定县| 刚察县| 同心县| 五常市| 临湘市| 广昌县| 新兴县| 梁山县| 武川县| 绿春县| 汾阳市| 商水县| 建平县| 高清| 扎囊县| 盈江县| 重庆市| 获嘉县| 锡林郭勒盟| 开原市| 罗山县| 古蔺县| 西乡县| 南康市| 东台市| 潞城市| 仙桃市| 台南市| 安阳县| 达日县| 宣城市| 二连浩特市| 屏山县| 苏尼特右旗| 泰州市| 裕民县| 翼城县|