Vue 通過自定義指令回顧v-內(nèi)置指令(小結(jié))
Vue.js 的各種指令(Directives)更加方便我們?nèi)?shù)據(jù)驅(qū)動 DOM,例如 v-bind、v-on、v-model、v-if、v-for、v-once 等內(nèi)置指令,這些指令的職責(zé)就是當(dāng)表達(dá)式改變時將某些行為應(yīng)用到 DOM 上,盡量不去操作增刪改 DOM。通過了解如何去自定義指令,可以想象內(nèi)置指令是如何完成的。
內(nèi)置指令
指令名稱 | 描述 | 使用 |
---|---|---|
v-model | 綁定數(shù)據(jù) | <\input v-model="message"> |
v-text | 輸出文本,不能解析標(biāo)簽 | <\p v-text="message"></p> |
v-html | 輸出文本,可解析標(biāo)簽 | <\p v-html="message">/p> |
v-once | 只綁定一次數(shù)據(jù) | <\p v-once >{{message}}</p> |
v-bind | 綁定屬性 | <\img v-bind:src="imgurl"> 或 <\img :src="imgurl"> |
v-if | 控制是否顯示容器 值轉(zhuǎn)為布爾為false時 注釋該容器,反之顯示 | <\div v-if="true"></div> |
v-show | 控制是否顯容器,改變的時display:none/block | <\div v-show="true"></diiv> |
v-for | 循環(huán)遍歷數(shù)組、對象 | <\li v-for="(val,key) in arr">{{val}}</li> |
v-cloak | 在還沒有執(zhí)行到vue代碼的時候隱藏元素,可解決‘閃爍'問題 | <\p v-cloak>{{message}}</p> |
自定義指令
在需要特殊功能時,使用自定義指令對 DOM 進行底層操作
注冊
自定義指令的注冊分為全局注冊和局部注冊,類似組件的注冊,只是方法名為 directive,寫法如下:
// 全局注冊 自定義指令 Vue.directive(‘mydir',{ // 指令選項 }); // 全局注冊 自定義指令函數(shù) Vue.directive('mydir', function () { // 這里將會被 `bind` 和 `update` 調(diào)用 }) // 局部注冊(只針對組件內(nèi)元素) export default { directives: { mydir: { // 指令選項 } } }
需要注意的是:Vue.directive( ) 注冊指令要在實例初始化 new Vue( ) 之前才能全局注冊指令。定義指令時駝峰式寫法會報錯,所以一般小寫。
指令選項
自定義指令的選項是由幾個鉤子函數(shù)(可選)組成,可以根據(jù)需求選擇不同的鉤子,例如使用全局注冊一個指令時:
Vue.directive('mydir', { bind: function () { // 只調(diào)用一次,指令第一次綁定到元素時調(diào)用,用于在綁定元素時執(zhí)行一次的初始化動作。 }, update: function () { // 第一次是緊跟在 bind 之后調(diào)用,獲得的參數(shù)是綁定的初始值, // 之后被綁定元素所在的模板更新時調(diào)用,而不論綁定值是否變化,可以忽略不必要的模板更新。 }, inserted: function () { // 被綁定元素插入父節(jié)點時調(diào)用(父節(jié)點存在即可調(diào)用,不必存在于 document 中)。 }, componentUpdated: function () { // 被綁定元素所在模板完成一次更新周期時調(diào)用。 }, unbind: function () { // 只調(diào)用一次, 指令與元素解綁時調(diào)用。 } })
以上每個鉤子函數(shù)都有幾個參數(shù)可用:
- el:指令所綁定的元素,可以用來直接操作 DOM;
- binding:包含指令信息的一個對象;
- vnode:Vue 編譯的生成虛擬節(jié)點;
- oldVnode:上一次的虛擬節(jié)點,僅在update和componentUpdated鉤子函數(shù)中可用。
示例
// 一個帶自定義指令的元素 <div v-mytest:foo.m1.m2="1+1">MyDirective</div> // 部分 JS 代碼 export default { directives:{ mytest: { bind: function (el, binding, vnode) { console.log(el) console.log(binding) console.log(vnode) } } } }
控制臺輸出截圖:
其中對于 binding 對象輸出的屬性有:
- rawName: "v-mytest:foo.m1.m2" // 自定義指令
- name: "mytest" // 指令名稱
- arg: "foo" // 指令的參數(shù)
- modifiers: {m1: true, m2: true} // 指令的修飾符
- expression: "1+1" // 指令綁定值的字符串形式
- value: 2 // 指令的綁定值
v-bind || : 綁定屬性
Vue 內(nèi)置指令 v-bind 用于動態(tài)更新 HTML 元素屬性,使用 v-bind:someAttr = "someData"或者語法糖 :someAttr = "someData"就可以在 someData 改變時更新綁定的 someAttr 屬性。
基本用法
綁定單一的屬性值
<a :href="url" rel="external nofollow" rel="external nofollow" :id="linkID">鏈接</a>
測試 data 如下:
// js data : { url: 'https://www.baidu.com/', linkID : 'myid' }
元素渲染輸出:
<a rel="external nofollow" rel="external nofollow" id="myid">鏈接</a>
對象語法
v-bind 最常用的是綁定 class 或 style 屬性來動態(tài)改變樣式。例如可以給 :class 設(shè)置一個對象來動態(tài)切換 class 的值:
<!-- class 綁定 --> <div :class="{colorRed: isRed}"></div>
當(dāng) isRed:true 時渲染輸出:
<div class="colorRed"></div>
對象中可以傳入多個屬性值來動態(tài)切換 class:
<!-- class 綁定,傳入多個屬性 --> <div :class="{ classA: isA, classB: isB }">
當(dāng) isA、isB 變化時 classA、classB 會動態(tài)更新,當(dāng)都為 true 時顯然渲染結(jié)果為:
<div class="classA classB"></div>
同理對于 style 可以傳入對象屬性,并且可以使用字符串拼接:
<!-- style 綁定 --> <div :style="{ fontSize: size + 'px' }"></div>
對于元素中的各個對象可以統(tǒng)一用 v-bind 綁定:
<!-- 綁定一個有屬性的對象 --> <div v-bind="{ id: someProp, 'other-attr': otherProp }"></div>
數(shù)組語法
class 可以傳入多值,給 :class 綁定一個數(shù)組就可以使用 class 列表
<div :class="[activeA, activeB]"></div>
例如當(dāng) {activeA: 'class1', activeB: 'class2'} 時渲染結(jié)果為:
<div class="class1 class2"></div>
還可以在數(shù)組語法中使用三元表達(dá)式切換 class,例如:
<div :class="[isA ? activeA : '', activeB]">
在 class 有多個條件時使用三元表達(dá)式比較繁瑣,可以在數(shù)組語法中使用對象語法:
<div :class="[{activeA: isA}, activeB]">
修飾符
v-bind 的修飾符很少,API 中只提供.prop、.camel和.sync,并且多用于組件,使用方式示例:
<!-- 通過 prop 修飾符綁定 DOM 屬性 (property) --> <div v-bind:text-content.prop="text"></div> <!-- .camel 修飾符(2.1.0+)將 v-bind 屬性名稱 kebab-case 駝峰化為 camelCase --> <svg :view-box.camel="viewBox"></svg> <!-- .sync 修飾符(2.3.0+) 語法糖,會擴展成一個更新父組件綁定值的 v-on 偵聽器--> <text-document v-bind:title.sync="doc.title"></text-document> <!-- 批量綁定,將 doc 對象中的每一個屬性 (如 title) 都作獨立的 prop ,各自添加 v-on 監(jiān)聽器--> <text-document v-bind.sync="doc"></text-document>
v-on || @ 監(jiān)聽事件
v-on 用于動態(tài)綁定事件監(jiān)聽器,使用 v-on:someEvent = "someFunction"或者語法糖 @someEvent = "someFunction"就可以監(jiān)聽 someEvent 進行交互。
基本用法
@someEvent 調(diào)用的方法名后面可以不跟(),例如:
<a :href="url" rel="external nofollow" rel="external nofollow" :id="linkID">鏈接</a> <!-- 監(jiān)聽一個事件 --> <button @click="changeFun">change button</button>
可以在 methods 中添加函數(shù):
// 部分 JS 代碼 methods :{ changeFun : function () { this.linkID = 'changeID' // 指向當(dāng)前組件本身 } }
點擊 button 按鈕后 a 元素的 id 改變:
<a rel="external nofollow" rel="external nofollow" id="changeID">鏈接</a>
當(dāng)然 v-on 還可以使用對象語法監(jiān)聽多個事件:
<!-- v2.4.0+ --> <button v-on="{ mousedown: doThis, mouseup: doThat }"></button>
對于在 HTML 元素上監(jiān)聽的事件,當(dāng) ViewModel 銷毀時,所有的事件處理器會自動刪除,無需自己清理。
修飾符
Vue 可以將原生事件對象參數(shù) event 傳入事件方法中,并提供了特殊變量$event用來訪問元素 DOM 事件。此外可以通過一些事件修飾符來實現(xiàn)特定的事件,如 .stop、.prevent、.capture、.once 等,常用的使用示例:
<!-- 停止單擊事件冒泡,調(diào)用 event.stopPropagation()--> <button @click.stop="doThis"></button> <!-- 阻止默認(rèn)行為,調(diào)用 event.preventDefault() --> <button @submit.prevent="doThis"></button> <!-- 添加事件偵聽器時使用 capture 事件捕獲模式 --> <button @click.capture="doThis"></button> <!-- 點擊回調(diào)只會觸發(fā)一次 --> <button @click.once="doThis"></button> <!-- 只當(dāng)點擊鼠標(biāo)左鍵時觸發(fā)(2.2.0) --> <button @click.left="doThis"></button> <!-- 串聯(lián)修飾符 --> <button @click.stop.prevent="doThis"></button>
此外,v-on 還提供按鍵修飾符來監(jiān)聽鍵盤事件,鍵值為 .keyCode,常用有.entry、.delete、.tab、.esc、.space、.down等,如下:
<!-- 只有在 `keyCode` 是 5 時調(diào)用 `vm.submit()` --> <input v-on:keyup.5="submit"> <!-- 為重要的 keyCode 如 enter 提供別名--> <input v-on:keyup.enter="submit"> <!-- 縮寫語法 --> <input @keyup.enter="submit">
此外還有系統(tǒng)修飾符監(jiān)聽鍵盤事件,不同的系統(tǒng)其鍵盤/系統(tǒng)修飾符不一樣。這些按鍵修飾符可以任意組合使用。
v-if、v-show 條件渲染
條件渲染 v-if 根據(jù)表達(dá)式的值的真假條件渲染元素,在表達(dá)式為真時渲染,為假時移除。
<p v-if="status === 1">當(dāng) status 為 1 時顯示此行</p> <p v-else-if="status === 1">當(dāng) status 為 2 時顯示此行</p> <p v-else>其它情況默認(rèn)顯示此行</p>
v-show 也是條件渲染,但只切換元素的 CSS 屬性 display,無論條件真假都會被編譯,相比于 v-if 更適用于頻繁切換場景。
<p v-show="status === 1">當(dāng) status 為 1 時顯示此行</p>
當(dāng) data: {status: 2} 時隱藏,但依舊會被編譯,渲染結(jié)果為:
<p style="display: none;">當(dāng) status 為 1 時顯示此行</p>
顯然在 Vue.js 內(nèi)置的 <template> 元素上可以使用 v-if,但不能使用 v-show,可以思考下為什么。
v-for 列表渲染
列表渲染指令 v-for 常用于數(shù)組遍歷或枚舉一個對象的循環(huán)顯示,必須結(jié)合 in 使用特定語法 alias in expression 為當(dāng)前遍歷的元素提供別名:
<!-- 遍歷一個數(shù)組 --> <div v-for="item in items">{{ item.text }}</div> <!-- 提供第二個的參數(shù)為數(shù)組的索引 --> <div v-for="(item, index) in items">{{ index }} - {{ item.text }}</div> <!-- 遍歷對象屬性 --> <div v-for="value in object">{{ value }}</div> <!-- 提供第二個可選的參數(shù):對象的鍵名 --> <div v-for="(value, key) in object">{{ key }}: {{ value }}</div> <!-- 提供第三個的可選參數(shù):對象的索引 --> <div v-for="(value, key, index) in object">{{ index }}. {{ key }}: {{ value }}</div>
可以用 of 替代 in 作為分隔符
當(dāng) v-for 和 v-if 在同一節(jié)點一起使用時,v-for 的優(yōu)先級比 v-if 更高。
v-model 表單控件雙向綁定
v-model 其實也是一個特殊的語法糖,其實實現(xiàn)的數(shù)據(jù)雙向綁定也可用v-bind和v-on實現(xiàn),但v-model在不同表單上會有更加智能的處理。
文本框
經(jīng)典的使用案例是對<input>、<textarea>文本框的雙向數(shù)據(jù)綁定:
<!-- 輸入框 --> <input type="text" v-model="message" placeholder="edit me"> <!-- 文本域 --> <textarea v-model="message" placeholder="edit me"></textarea> <!-- 實時更新 --> <p>Message is: {{ message }}</p>
動態(tài)選擇
對于單選按鈕,復(fù)選框及選擇框的選項,v-model配合 Vue 實例的數(shù)據(jù)作為value屬性值實現(xiàn)不同效果,即會忽略所有表單元素的 value、checked、selected 特性的值。
<!--單選按鈕的互斥效果--> <div id="example-radio"> <input type="radio" id="one" value="One" v-model="picked"> <label for="one">One</label> <input type="radio" id="two" value="Two" v-model="picked"> <label for="two">Two</label> <!-- picked 顯示的是 value 的值 --> <p>Picked: {{ picked }}</p> </div> <!--多選按鈕--> <div id='example-checkbox'> <input type="checkbox" id="one" value="One" v-model="checkedNames"> <label for="jack">Jack</label> <input type="checkbox" id="two" value="Two" v-model="checkedNames"> <label for="john">John</label> <!-- Checked 顯示的是 value 組成的數(shù)組 --> <p>Checked: {{ checkedNames }}</p> </div>
修飾符
v-model的修飾符的使用限制在<input>、<select>、<textarea> 和組件。
- .lazy - 取代 input 監(jiān)聽 change 事件
- .number - 輸入字符串轉(zhuǎn)為數(shù)字
- .trim - 輸入首尾空格過濾
v-pre、v-cloak、v-once
這三個指令的共同點是無需表達(dá)式,用法如下:
<!-- 不顯示未編譯的標(biāo)簽直到實例初始化完 --> <div v-cloak>{{ message }}</div> <!-- 需要配合 CSS 隱藏樣式 [v-cloak]{ display: none;}--> <!-- 只渲染一次,隨后的渲染將被視為靜態(tài)內(nèi)容并跳過 --> <div v-once>{{ message }}</div> <!-- 不會被編譯,直接顯示顯示原始{{ }}標(biāo)簽 --> <div v-pre>{{ message }}</div>
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
Vue2?響應(yīng)式系統(tǒng)之深度響應(yīng)
這篇文章主要介紹了Vue2?響應(yīng)式系統(tǒng)之深度響應(yīng),文章基于Vue2?響應(yīng)式系統(tǒng)的相關(guān)資料展開對Vue2?深度響應(yīng)的介紹,需要的小伙伴可以參考一下2022-04-04Vue登錄后添加動態(tài)路由并跳轉(zhuǎn)的實踐分享
這篇文章講給大家詳細(xì)介紹一下Vue如何實現(xiàn)登錄后添加動態(tài)路由并跳轉(zhuǎn),文章通過代碼示例介紹的非常詳細(xì),對我們的學(xué)習(xí)或工作有一定的的幫助,需要的朋友可以參考下2023-07-07element-vue實現(xiàn)網(wǎng)頁鎖屏功能(示例代碼)
這篇文章主要介紹了element-vue實現(xiàn)網(wǎng)頁鎖屏功能,本文通過實例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友參考下吧2023-11-11vue+element UI中如何給指定日期添加標(biāo)記
這篇文章主要介紹了vue+element UI中如何給指定日期添加標(biāo)記問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2024-02-02vue實現(xiàn)播放后端flask發(fā)送的mp3文件
這篇文章主要為大家詳細(xì)介紹了vue如何實現(xiàn)播放后端flask發(fā)送的mp3文件,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下2024-01-01