除了核心功能默認內置的指令 (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="小車">