除了核心功能默认内置的指令 (v-model 和 v-show),Vue 也允许注册自定义指令。这样很好的一点就是有的时候我们可以自建一些满足特殊需求的指令。
// 注册一个全局自定义指令 `v-focus`
Vue.directive('focus', {
// 当被绑定的元素插入到 DOM 中时……
inserted: function (el) {
// 聚焦元素
el.focus()
}
})
钩子函数
钩子函数参数
函数简写
- 到这里我们就简单的了解了vue自定义指令的创建规则,接下来就可以试着写一个指令。之前项目中有做过图片展示的,需求是在所给的图片没有展示出来的时候给一张默认图,由于用的地方比较多,索性就直接写了一个指令,现在就拿出来重新整理一下。
/**
* 图片占位图
*/
/* eslint no-param-reassign: ["error", { "props": false }] */
const onLoadingImage = 'https:zhanweitu.png'
const carBackgroundImgs = [
'https:a.jpg', 'https:b.jpg', 'https:c.jpg', 'https:d.jpg', 'https:e.jpg', 'https:f.jpg'
]
const newImg = url => new Promise((resolve) => {
const img = new Image()
img.src = url
img.onload = function () {
resolve()
}
})
const imageLoad = (el) => {
const { src, level } = el.dataset
const carBackgroundImg = carBackgroundImgs[level - 1] // 小车背景图片
if (src && level) {
Promise.all([newImg(src), newImg(carBackgroundImg)]).then(() => {
el.src = src
el.classList.remove('default-img')
el.removeAttribute('data-src')
el.removeAttribute('data-level')
el.classList.add(`bg-img-${level}`)
})
}
}
export default {
global: true,
install(Vue) {
Vue.directive('img', {
bind(el) {
el.classList.add('default-img')
el.src = onLoadingImage
},
inserted(el) {
imageLoad(el)
},
update(el) {
imageLoad(el)
}
})
}
}
- 这里这样写的原因是我将其作为插件引入,通过插件的形式,将这个指令作为全局使用。
- 同级别的index.js文件
export default {
install(Vue) {
const context = require.context('./', false, /\.js$/)
const keys = context.keys().filter(item => item !== './index.js')
for (let i = 0; i < keys.length; i += 1) {
/* eslint-disable global-require */
/* eslint-disable import/no-dynamic-require */
try {
const obj = require(`${keys[i]}`).default
if (obj.global) {
obj.install.call(null, Vue)
}
} catch (err) {
console.log(err)
}
}
}
}
- 当然最终我们还需要在主文件main.js文件中引入
import directives from '@/directives/'
/**
* 加载全部全局指令
*/
Vue.use(directives)
- 之后就可以使用了
<img v-img :data-level="car.level" :data-src="car.png_img_url" alt="小车">