閱讀目錄
- 1.理解VUE中的自定義指令
1.理解VUE中的自定義指令
默認核心指令有 (v-model 和 v-show), 但是有時候我們需要用到自定義指令,在vue中,代碼復用主要形式和抽象是組件,但是在有的情況下,我們仍然需要對DOM元素進行底層操作,所以這個時候我們需要用到自定義指令。
比如下面的一個input框,當頁面加載時,元素將獲得焦點,我們還沒有點擊input框,input就獲得焦點了,如下demo代碼:
<!DOCTYPE html> <html><head><title>演示Vue</title><style></style></head><body><div id='demo'><input v-focus></div></body><script src="./vue.js"></script><script type="text/javascript">// 注冊一個全局定義指令 v-focus Vue.directive('focus', {// 綁定元素插入到DOM 中 inserted: function (el) {// 聚焦元素 el.focus()}})new Vue({el: '#demo'})</script> </html>
查看效果
上面的是全局定義指令 v-foucs, 當然我們也可以局部定義,如下代碼:
<!DOCTYPE html> <html><head><title>演示Vue</title><style></style></head><body><div id='demo'><input v-focus></div></body><script src="./vue.js"></script><script type="text/javascript">new Vue({el: '#demo',directives: {focus: {// 指令的定義 inserted: function (el) {// 聚焦元素 el.focus()}}}})</script> </html>
查看效果
然后我們就可以在任何input元素框或者textarea使用 v-focus 了,如下代碼:
<input v-focus />
2. 指令定義函數提供了如下幾個鉤子函數(根據VUE教程來):
bind: 只調用一次,指令第一次綁定到元素時調用,也就是說初始化時候調用一次。
inserted: 被綁定元素插入父節點時調用(父節點需要存在才會調用)。
update: 被綁定元素所在的模板更新時調用(通過比較更新前后的綁定值)。
componentUpdated: 被綁定元素所在模板完成一次更新周期時調用。
unbind: 指令與元素解綁時調用,只調用一次,和bind對應。
上面幾個鉤子函數有如下參數 (el, binding, vnode, oldVnode)
el: 指令所綁定的元素,可用來直接操作DOM。
binding: {Object} obj有如下屬性:
name: 指令名,不包括 v- 前綴
value: 指令綁定值。比如 v-my-directive = '1+1', 那么value就是2.
oldValue: 指令綁定的前一個值,僅在 update 和 componentUpdated 鉤子中可用。無論值是否改變都可用。
expression: 綁定值的字符串形式。 例如 v-my-directive="1 + 1" , expression 的值是 "1 + 1"。
arg: 傳給指令的參數。例如 v-my-directive:foo, arg 的值是 "foo"。
modifiers: 一個包含修飾符的對象。 例如: v-my-directive.foo.bar, 修飾符對象 modifiers 的值是 { foo: true, bar: true }。
vnode: Vue編譯生成的虛擬節點。
oldVnode: 上一個虛擬節點,僅在 update 和 componentUpdated 鉤子中可用。
注意: 除了 el 之外,其它參數都應該是只讀的,盡量不要修改他們。如果需要在鉤子之間共享數據,建議通過元素的 dataset 來進行。
如下demo代碼:
<!DOCTYPE html> <html><head><title>演示Vue</title><style></style></head><body><div id='demo' v-demo:hello.a.b='message'></div></body><script src="./vue.js"></script><script type="text/javascript">Vue.directive('demo', {bind: function(el, binding, vnode) {var s = JSON.stringify;el.innerHTML = 'name: ' + s(binding.name) + '<br/>' + 'value: ' + s(binding.value) + '<br/>' + 'expression: ' + s(binding.expression) + '<br/>' + 'argument: ' + s(binding.arg) + '<br/>' + 'modifiers: ' + s(binding.modifiers) + '<br/>' + 'vnode: ' + Object.keys(vnode).join(', ')}})new Vue({el: '#demo',data: {message: 'hello!'}})</script> </html>
查看效果
對象字面量
如果指令需要多個值,可以傳入一個 JavaScript 對象字面量。
如下代碼:
<!DOCTYPE html> <html><head><title>演示Vue</title><style></style></head><body><div id='demo' v-demo="{ color: 'white', text: 'hello!' }"></div></body><script src="./vue.js"></script><script type="text/javascript">Vue.directive('demo', function (el, binding) {console.log(binding.value.color) // => "white" console.log(binding.value.text) // => "hello!" })new Vue({el: '#demo'})</script> </html>
查看效果
在控制臺可以看到輸出了字符串了。
2. Vue.js自定義指令的用途。
上面是教程中的一些demo,但是在實際當中我們需要用到什么地方呢?我們可以預想到可以使用到預加載數據的地方,比如預加載圖片,由于圖片加載需要一些時間,因此我們先加載一張占位符圖片,
等圖片真正加載完成時候,才加載真正的圖片,這樣的用戶體驗效果更能更好點。下面是使用vue自定義指令來實現這個功能,代碼如下:
?
<!DOCTYPE html> <html><head><title>演示Vue</title><style>img { width: 180px; height: 180px; overflow: hidden;}</style></head><body><div id='demo'><img v-for='item in list' v-img='item.url'/></div></body><script src="./vue.js"></script><script type="text/javascript">Vue.directive('img', {inserted: function(el, binding) {console.log(el)// 下面使用一張背景顏色來演示一下,var color = Math.floor(Math.random()*1000000);el.style.backgroundColor = '#' + color; // 隨機的背景顏色var img = new Image();img.src = binding.value; img.onload = function() {el.style.backgroundImage = 'url(' + binding.value + ')';}}});new Vue({el: '#demo',data: {list: [{url: 'http://img.alicdn.com/imgextra/i3/730692984/TB2.dQMdxXkpuFjy0FiXXbUfFXa_!!730692984-0-beehive-scenes.jpg_180x180q70'},{url: 'http://img.alicdn.com/imgextra/i2/730692984/TB239AJdw0kpuFjSspdXXX4YXXa_!!730692984-0-beehive-scenes.jpg_180x180q70'},{url: 'http://img.alicdn.com/imgextra/i4/730692984/TB29TsZdrVkpuFjSspcXXbSMVXa_!!730692984-0-beehive-scenes.jpg_180x180q70'}]}})</script> </html>
查看效果
如上演示可以看到,剛開始載入頁面的時候,有那么一瞬間先是背景顏色 最后是圖片,這里只是簡單的演示一下,在實際使用中,我們可以先放一張預加載的圖片,當真正圖片加載完成的時候,才顯示真正的圖片,省的在圖片未加載完成的時候,背景圖片是空白的效果就不是很好了。