除了核心功能默认内置的指令 (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的指令简化了钩子函数的使用。