專門做資產(chǎn)負(fù)債表結(jié)構(gòu)分析的網(wǎng)站上海市人大常委會
一、理解自定義指令
在 vue 中提供了一些對于頁面和數(shù)據(jù)更為方便的輸出,這些操作就叫做指令,以 v-xxx 表示,比如 html 頁面中的屬性 <div v-xxx ></div>。自定義指令很大程度提高了開發(fā)效率,提高了工程化水平,一定要認(rèn)真學(xué)習(xí)。
vue3:自定義指令
二、vue2 有哪些內(nèi)置指令
序號 | 指令 | 解釋 |
1 | v-for | 基于源數(shù)據(jù)多次渲染元素或模板塊。 |
2 | v-on | 綁定事件監(jiān)聽器。 |
3 | v-bind | 動態(tài)的綁定一個或多個attribute,或一個組件prop到表達(dá)式。 |
4 | v-model | 在表單控件或者組件上創(chuàng)建雙向數(shù)據(jù)綁定。 |
5 | v-slot | 提供具名插槽或需要接收prop的插槽。 |
6 | v-pre | 跳過這個元素和它的子元素的編譯過程。 |
7 | v-cloak | 這個指令保持在元素上直到關(guān)聯(lián)實例結(jié)束編譯。 |
8 | v-once | 只渲染元素或組件一次,隨后的渲染會將組件/元素以及下面的子元素當(dāng)成靜態(tài)頁面不再渲染。 |
9 | v-text | 更新元素的textContent |
10 | v-html | 更新元素的display屬性 |
11 | v-if | 根據(jù)條件渲染元素 |
12 | v-else | 與v-if 或 v-else-if搭配使用 |
13 | v-else-if | 與 v-if 或 v-else 搭配使用,前一兄弟元素必須有 v-if 或 v-else-if。 |
三、vue2?指令修飾符
事件修飾符 | ||
序號 | 修飾符 | 解釋 |
1 | .stop | 阻止事件冒泡,相當(dāng)于調(diào)用?event.stopPropagation() |
2 | .prevent | 阻止默認(rèn)事件的觸發(fā),相當(dāng)于調(diào)用?event.preventDefault() |
3 | .capture | 使用事件捕獲模式,從外部元素開始觸發(fā)事件,然后再觸發(fā)內(nèi)部元素的事件 |
4 | .self | 只有當(dāng)事件在綁定的元素本身觸發(fā)時才觸發(fā)事件,不會觸發(fā)內(nèi)部元素的事件 |
5 | .once | 指令只會觸發(fā)一次,然后自動解綁。 |
6 | .passive | 指示監(jiān)聽器永遠(yuǎn)不會調(diào)用?event.preventDefault() ,可以提高性能。 |
7 | .native | 監(jiān)聽組件根元素的原生事件,而不是組件內(nèi)部的子元素上的事件。 |
v-model修飾符 | ||
序號 | 修飾符 | 解釋 |
1 | .trim | 自動去除輸入內(nèi)容的首尾空格 |
2 | .number | 將輸入的?value ?值轉(zhuǎn)為數(shù)字類型 |
3 | .lazy | 將?input ?事件改為?change ?事件,減少輸入事件的頻率 |
按鍵修飾符 | ||
序號 | 修飾符 | 解釋 |
1 | .enter | 監(jiān)聽鍵盤回車事件 |
其他修飾符 | ||
序號 | 修飾符 | 解釋 |
1 | .camel | 用于將綁定的特性名字轉(zhuǎn)回駝峰命名 <svg :view-box.camel="viewBox"></svg> 上面的代碼等價于 <svg viewBox="..."></svg> |
2 | .sync | .sync 修飾符是一個特殊的修飾符,用于實現(xiàn)父子組件之間的雙向數(shù)據(jù)綁定。 |
四、vue2自定義指令鉤子
在 Vue 2 中,當(dāng)你創(chuàng)建自定義指令時,你可以訪問幾個鉤子函數(shù),這些鉤子函數(shù)允許你在不同的指令生命周期階段執(zhí)行代碼。 | ||
序號 | 鉤子 | 解釋 |
1 | bind | 1、當(dāng)指令第一次綁定到元素上時調(diào)用。此時,你可以執(zhí)行一些初始化操作,比如設(shè)置初始值或添加事件監(jiān)聽器。 2、這個鉤子函數(shù)接收三個參數(shù): el (指令所綁定的元素)、binding (一個對象,包含指令的名稱、值和其他屬性)、vnode (Vue 編譯生成的虛擬節(jié)點)。 |
2 | inserted | 1、當(dāng)被綁定的元素插入到父節(jié)點中時調(diào)用。此時,元素已經(jīng)存在于 DOM 中,你可以執(zhí)行依賴于 DOM 的操作。 2、和? bind ?鉤子一樣,它也接收?el 、binding ?和?vnode ?三個參數(shù)。 |
3 | update | 1、當(dāng)指令的綁定值發(fā)生變化時調(diào)用,并且元素 DOM 也已經(jīng)更新。 2、接收的參數(shù)和? bind ?和?inserted ?一樣。 |
4 | componentUpdated | 1、當(dāng)組件的 VNode 及其子 VNode 更新后調(diào)用,即組件的 DOM 已經(jīng)更新。 2、這個鉤子對于在更新之后的操作非常有用,比如基于新的 DOM 狀態(tài)重新計算位置或大小。 |
5 | unbind | 1、當(dāng)指令與元素解綁時調(diào)用,此時可以執(zhí)行一些清理工作,比如移除事件監(jiān)聽器或清理計時器。 2、同樣接收? el 、binding 、vnode ?這些參數(shù),但?vnode ?參數(shù)在大多數(shù)情況下是?undefined。 |
五、Nuxt2使用自定義指令方法
5.1、全局自定義指令(方法一)
5.1.1、創(chuàng)建目錄directives
創(chuàng)建文件directives/highlight.js
// eslint-disable-next-line import/no-extraneous-dependencies
import Vue from 'vue'Vue.directive('highlight', {// 當(dāng)被綁定的元素插入到 DOM 中時inserted (el, binding) {// 獲取指令的綁定值const color = binding.value || 'yellow';// 應(yīng)用樣式到元素el.style.backgroundColor = color;},// 當(dāng)綁定值更新時update (el, binding) {// 更新元素的背景顏色el.style.backgroundColor = binding.value || 'yellow';}
})
5.1.2、nuxt.config.js配置
nuxt.config.js文件中找到plugins
plugins: [{{ src: '../m-front-common/pc/directives/highlight', mode: 'client' },}
]
5.1.3、頁面使用
<template><div><p v-highlight="'red'">這段文字的背景色會被設(shè)置為紅色。</p></div>
</template>
<script>
</script>
<style lang="less" scoped>
</style>
?驗證成功
5.2、全局自定義指令(方法二)
5.2.1、創(chuàng)建目錄directives
5.2.2、創(chuàng)建文件directives/highlight.js
export default {name: 'highlight',install(Vue) {Vue.directive('highlight', {bind (el, binding) {// 獲取指令的綁定值const color = binding.value || 'yellow';// 應(yīng)用樣式到元素el.style.backgroundColor = color;},// 當(dāng)綁定值更新時unbind (el, binding) {// 更新元素的背景顏色el.style.backgroundColor = binding.value || 'yellow';}})}
}
5.2.3、創(chuàng)建文件directives/index.js
// eslint-disable-next-line import/no-extraneous-dependencies
import Vue from 'vue'
import highlight from './highlight'Vue.use(highlight)
5.2.4、nuxt.config.js配置
nuxt.config.js文件中找到plugins
plugins: [{{ src: '../m-front-common/pc/directives/index'},}
]
5.2.5、頁面使用
<template><div><p v-highlight="'red'">這段文字的背景色會被設(shè)置為紅色。</p></div>
</template>
<script>
</script>
<style lang="less" scoped>
</style>
?
5.3、局部自定義指令 / 頁面自定義指令(方法三)
<template><div><div v-color="'red'">文字顏色</div></div>
</template>
<script>
export default {directives: {'color': {bind: (el, binding) => {el.style.color = binding.value || 'blue';}}}
}
</script>
<style lang="less" scoped>
</style>
驗證成功?
六、Nuxt2使用自定義指令DEMO
6.1、v-focus
當(dāng)輸入表單時,可以使表單第一項自動獲取焦點,減少一個操作步驟。
export default {name: 'focus',install(Vue) {Vue.directive('focus', {inserted (el) {el.focus()}})}
}
6.2、v-color
export default {name: 'color',install(Vue) {Vue.directive('color', {bind (el, binding) {// 獲取指令的綁定值const color = binding.value || 'yellow';// 應(yīng)用樣式到元素el.style.color = color;},unbind (el, binding) {el.style.color = binding.value || 'yellow';}})}
}
6.3、v-copy
import { Message } from 'element-ui'export default {name: 'copy',install(Vue) {Vue.directive('copy', {inserted(el) {el.addEventListener('click', () => {const textarea = document.createElement('textarea');el.style.cursor = 'pointer';textarea.value = el.innerText;document.body.appendChild(textarea);textarea.select();document.execCommand('copy');document.body.removeChild(textarea);Message.success("復(fù)制成功")})}})}
}
6.4、highlight
export default {name: 'highlight',install(Vue) {Vue.directive('highlight', {bind (el, binding) {// 獲取指令的綁定值const color = binding.value || 'yellow';// 應(yīng)用樣式到元素el.style.backgroundColor = color;},// 當(dāng)綁定值更新時unbind (el, binding) {// 更新元素的背景顏色el.style.backgroundColor = binding.value || 'yellow';}})}
}
6.5、lazyLoad
export default {name: 'lazyLoad',install(Vue) {Vue.directive('lazyLoad', {inserted (el) {// 自動監(jiān)聽元素是否進(jìn)入了設(shè)備的可視區(qū)域之內(nèi)const observer = new IntersectionObserver(entries => {entries.forEach(entry => {if (entry.isIntersecting) {const img = entry.targetimg.src = img.dataset.srcobserver.unobserve(img)}})})observer.observe(el)}})}
}
?頁面使用,驗證成功
<img v-lazyLoad data-src="https://www.abc.com.cn/img/6376d08.png" style="height:50px;" />
6.6、dialogDrag
// Element-Dialog 彈窗可拖動
export default {name: 'dialogDrag',install(Vue) {Vue.directive('dialogDrag', {bind(el) {const dialogHeaderEl = el.querySelector('.el-dialog__header');const dragDom = el.querySelector('.el-dialog');dialogHeaderEl.style.cursor = 'move';// 獲取原有屬性 ie dom元素.currentStyle 火狐谷歌 window.getComputedStyle(dom元素, null);const sty = dragDom.currentStyle || window.getComputedStyle(dragDom, null);dialogHeaderEl.onmousedown = e => {// 鼠標(biāo)按下,計算當(dāng)前元素距離可視區(qū)的距離const disX = e.clientX - dialogHeaderEl.offsetLeft;const disY = e.clientY - dialogHeaderEl.offsetTop;// 獲取到的值帶px 正則匹配替換let styL;let styT;// 注意在ie中 第一次獲取到的值為組件自帶50% 移動之后賦值為pxif (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, '');}// eslint-disable-next-line no-shadowdocument.onmousemove = function(e) {// 通過事件委托,計算移動的距離const l = e.clientX - disX;const t = e.clientY - disY;// 移動當(dāng)前元素dragDom.style.left = `${l + styL}px`;dragDom.style.top = `${t + styT}px`;// 將此時的位置傳出去// binding.value({x:e.pageX,y:e.pageY})};document.onmouseup = function() {document.onmousemove = null;document.onmouseup = null;};};}})}
}
?
七、推薦vue指令插件
7.1、vue-lazyload
npm install vue-lazyload