除了核心功能默認內置的指令 (v-model 和 v-show),Vue 也容許註冊自定義指令。注意,在 Vue2.0 中,代碼複用和抽象的主要形式是組件。然而,有的狀況下,你仍然須要對普通 DOM 元素進行底層操做,這時候就會用到自定義指令。vue
vue指令(directive)通常用於直接對DOM元素進行操做,此次以vue2爲例實現一個圖片放大鏡指令node
bind: 首次綁定執行一次,負責初始化markdown
inserted: 被綁定元素插入父節點時候調用,僅保證父節點存在,不必定已 被插入文檔app
update: 組件VNode更新時,可能在其子VNode更新前ssh
componentUpdated: 組件VNode及其子VNode都更新後調用函數
unbind: 解綁時調用ui
el: 綁定的元素spa
binding: 綁定對象,包含參數值,value和oldValueprototype
vnode: 當前虛擬節點code
oldVnode: 上一個虛擬節點,僅在update和componentUpdate鉤子可用
const setCss = (el,obj)=>{
for (const key in obj) {
if (Object.prototype.hasOwnProperty.call(obj, key)) el.style[key] = obj[key]
}
}
export default {
install(Vue) {
Vue.directive('zoom', {
inserted(el) {
el.onload = (imgRes) => {
console.log(imgRes);
const {offsetWidth, offsetHeight, offsetTop, offsetLeft} = imgRes.target
const zoomBox = document.createElement('div')
const zoomImg = document.createElement('img')
const imgs = imgRes.target
el.addEventListener('mouseover', (ev) => {
console.log(ev)
imgs.style.cursor = 'crosshair'
zoomImg.src = imgs.src
zoomImg.width = offsetWidth * 2
zoomImg.height = offsetHeight * 2
zoomBox.id = 'zoomBox'
setCss(zoomBox, {
width: offsetWidth + 'px',
height: offsetHeight + 'px',
border: '1px solid #eee',
overflow: 'hidden',
position: 'absolute',
backgroundColor: '#fff',
left: offsetWidth + offsetLeft + 'px',
top: offsetTop + 'px',
display: 'none'
})
zoomBox.appendChild(zoomImg)
document.body.appendChild(zoomBox)
})
el.addEventListener('mousemove', (moveEv) => {
const zoomBoxs = document.getElementById('zoomBox')
const zoomImgs = zoomBoxs.getElementsByTagName('img')[0]
const mx = moveEv.offsetX, my = moveEv.offsetY
zoomBoxs.style.display = 'block'
zoomImgs.style.marginLeft = `-${mx}px`
zoomImgs.style.marginTop = `-${my}px`
})
el.addEventListener('mouseout', () => {
const zoomBoxs = document.getElementById('zoomBox')
document.body.removeChild(zoomBoxs)
el.removeEventListener('mouseover', () => {
})
el.removeEventListener('mousemove', () => {
})
el.removeEventListener('mouseout', () => {
})
})
}
},
unbind(el) {
el.removeEventListener('mousemove', () => {
})
el.removeEventListener('mouseout', () => {
})
}
})
}
}
複製代碼
在main.js註冊全局指令
import zoom from "./directive/zoomBox"
Vue.use(zoom)
複製代碼
在任何組件就能夠直接調用這個v-zoom的指令了,固然還能夠傳值和傳參
<img src="../assets/image1.png" v-zoom alt="" >
複製代碼
vue指令還能夠實現不少複用功能,好比複製文字、長按、一些權限的顯示的功能。另外vue3的指令簡化了鉤子函數的使用。