VUE双向数据绑定
模板語法
選項中主要影響模板或DOM的選項有el和template,屬性replace和template需要一起使用。 el:類型為字符串,DOM元素或函數。其作用是為實例提供掛載元素。一般來說我們會使用css選擇符,或者原生的DOM元素。例如el:’#app’。在初始項中指定了el,實例將立即進入編譯過程。
template:類型為字符串。默認會將template值替換掛載元素(即el值對應的元素),并合并掛載元素和模板根節點的屬性(如果屬性具有唯一性,類似id,則以模板根節點為準)。如果replace為false,模板template的值將插入掛載元素內。通過template插入模板的時候,掛載元素的內容都將被互聯,除非使用slot進行分發。在使用template時,我們往往不會把所有的HTML字符串之間寫在js里面,這樣影響可讀性也不利于維護所以經常用’#tpl’的方式賦值,并且在body內容添加為標簽包含的HTML內容,這樣就能將HTML從js中分離開來,示例如下:
最終輸出HTML結構為:
<div class='tpl'><p>This is a tpl from script tag</p></div>瀏覽器顯示This is a tpl from script tag
數據
Vue.js實例中可以通過data屬性定義數據,這些數據可以在實例對應的模板中進行綁定并使用。需要注意的是,如果傳入data的是一個對象,Vue實例會代理起data對象里的所有屬性,而不會對傳入的對象進行深拷貝。另外,我們也可以引用Vue實例vm中的$data來獲取聲明的數據,例如:
var data = { a: 1 } var vm = new Vue({data: data }) vm.$data === data // -> true vm.a === data.a // -> true // 設置屬性也會影響到原始數據 vm.a = 2 data.a // -> 2 // 反之亦然 data.a = 3 vm.a // -> 3然后在模板中使用{{a}}就會輸出vm.a的值,并且修改vm.a的值,模板中的值會隨之改變,我們也會稱這個數據為響應式(responsive)數據。 需要注意的是,只有初始化時傳入的對象才是響應式的,即在聲明完實例后,再加上一句vm.$data.b = ‘2’,并在模板中使用{{b}},這時是不會輸出字符串’2’的。例如:
<div id="app"><p>{{a}}</p><p>{{b}}</p> </div> var vm = new Vue({el : '#app',data : {a:1}});vm.$data.b = 2;如果需要在實例化之后加入響應式變量,需要調用實例方法$set, 例如: vm.$set(‘b’, 2); 不過Vue.js并不推薦這么做,這樣會拋出一個異常: 所以,我們應盡量在初始化的時候,把所有的變量都設定好,如果沒有值,也可以用undefined或null占位。 另外,組件類型的實例可以通過props獲取數據,同data一樣,也需要在初始化時預設好。
示例:
數據綁定語法
文本插值
1.文本插值 數據綁定最基礎的形式就是文本插值,使用的是雙大括號標簽{{}},為“Mustache”語法(源自前端模板引擎Mustache.js),示例如下: <span>Hello {{ name }}</span> // -> Hello Vue Vue.js
實例vm中name屬性的值將會替換Mustache標簽中的name,并且修改數據對象中的name屬性,DOM也會隨之更新。在瀏覽器console中運行 vm.name = ‘Vue 1.0’, 輸出結果為Hello Vue 1.0。 模板語法同時也支持單次插值,即首次賦值后再更改vm實例屬性值不會引起DOM變化, 例如以下模板在運行vm.name = 'Vue 1.0’后,依舊會輸出Hello Vue:
<span>Hello {{* name }} </span> // -> Hello Vue
Vue.js 2.0去除了{{*}}這種寫采用v-once代替。以上模板需要改寫為
指令語法
Vue.js提供指令(Directives)這一概念,可以理解為當表達式的值發生改變時,會有些特殊行為作用到綁定的DOM上。指令通常會直接書寫在模板的HTML元素中,而為了有別于普通的屬性Vue.js指令是帶有前綴的v-的屬性。寫法上來說,指令的值限定為綁定表達式,所以上述提到的 JavaScript 表達式及過濾器規則在這里也適用。
① 參數
指令v-bind可以在后面帶一個參數,用冒號(:)隔開,src即為參數。此時img標簽中的src會與vm實例中的avatar綁定,等同于: <img src="{{avatar}}" />
② 修飾符 修飾符(Modifiers)是以半角句號.開始的特殊后綴,用于表示指令應該以特殊方式綁定。 <button v-on:click.stop="doClick"></button>
v-on的作用是在對應的DOM元素上綁定事件監聽器,doClick為函數名,而stop即為修飾符,作用是停止冒泡,相當于調用了e. stopPropagation()。
1.v-model的使用
我們可以使用v-model為可輸入元素(input & textarea)創建雙向數據綁定,它會根據元素類型自動選取正確的方法來更新元素。先演示單行文本框、多行文本框、單選框和復選框的綁定方法,代碼如下:
<div id="app"><h3>單行文本框</h3><input type="text" v-model="singleText" style="width: 240px;"><p>{{ singleText }}</p ><h3>多行文本框</h3><textarea v-model="multiText" style="width: 240px;"></textarea><pre>{{ multiText }}</pre><h3>單選框</h3><!--由于點擊被選中的單選項無法取消其被選中狀態,所以實戰中一般沒有使用單個單選項的場景。這里,設置v-model共用同一個變量(radioValue)可實現RadioGroup的效果--><input id="ra" type="radio" value="楊玉環" v-model="radioValue"><label for="ra">A.楊玉環</label><input id="rb" type="radio" value="趙飛燕" v-model="radioValue"><label for="rb">B.趙飛燕</label><p>{{ radioValue }}</p ><h3>單個復選框</h3><!-- 單個復選框被用于true和false的切換 --><input id="c" type="checkbox" v-model="toggleValue"><label for="c">天生麗質</label><p>{{ toggleValue }}</p ><h3>多個復選框</h3><!-- 多個復選框,v-model接收數組類型變量 --><input id="ca" type="checkbox" value="漂亮" v-model="checkedValues"><label for="ca">A.回眸一笑百媚生</label><input id="cb" type="checkbox" value="瘦弱" v-model="checkedValues"><label for="cb">B.體輕能為掌上舞</label><input id="cc" type="checkbox" value="得寵" v-model="checkedValues"><label for="cc">C.三千寵愛在一身</label><p>{{ checkedValues.join(',') }}</p ></div><script src="https://cdn.jsdelivr.net/npm/vue@2.5.16/dist/vue.min.js"></script><script type="text/javascript">let vm = new Vue({el: '#app',data () {return {singleText: '',multiText: '',radioValue: '',toggleValue: false,checkedValues: []}}})</script>效果:
此外,下拉選擇框也可以使用v-model進行雙向數據綁定,代碼:
效果L:
畫圈的為綁定的部分
這里,筆者將select下拉選擇框拎出來單獨講述,并不是因為它具有何種妙用,而是因為它的視圖表現太差,而當下的規范尚不允許開發者自定義option的樣式,所以在實戰中一般都會使用其他元素來模擬下拉選擇框,它存在的意義只是為我們定
義組件時提供一個參照物。
2 .v-model與修飾符
在使用v-model時,我們還可以為其后綴一些修飾符以豐富用戶輸入時的行為,Vue內置的修飾符如表。
下面來看一個簡單示例,代碼如下:
<input type=“text” v-model.trim.number=“text” @keyup=“handleKeyUp”>
為v-model綁定了trim和number修飾符,并在輸入時打印出輸入值及其類型(輸入值原始類型為String),運行結果如圖:
3. 條件渲染和列表渲染
程序中有三大結構:順序結構、分支結構、循環機構。順序結構不必多說,分支和循環結構則分別由條件判斷語句和循環語句實現。同樣地,Vue也為視圖渲染提供了條件判斷和循環的機制,簡稱為條件渲染和列表渲染。
3.1 指令v-if和v-show
v-if的使用方法并不復雜,只需要為元素掛上v-if指令即可,與之配套的還有v-else-if和v-else,不過它們只能與v-if配合使用。下面來看一個簡單示例,代碼如下:
<div id="app"><h2 v-if="order === 0">站在前排的 v-if</h2><h2 v-else-if="order === 1">不上不下的 v-else-if</h2><h2 v-else>負責墊后的 v-else</h2><button @click="toggleTitle">切換標題</button></div><script src="https://cdn.jsdelivr.net/npm/vue@2.5.16/dist/vue.min. js"></script><script type="text/javascript">let vm = new Vue({el: '#app',data () {return {order: 0}},methods: {toggleTitle () {this.order = ++this.order % 3console.log('order的值為:', this.order)}}})</script>在這個示例中,設置了多個h2元素,當order值被修改時,視圖將渲染滿足條件的元素,運行結果如圖所示。
點擊切換標題:
本例中的order只會在012三者之中切換
v-show
v-show也可以用于實現條件渲染,不過它只是簡單地切換元素的CSS屬性:display。當條件判定為假時,元素的display屬性將被賦值為none;反之,元素的display屬性將被恢復為原有值。 相對于v-if來說,v-show并不能算作真正的條件渲染,因為掛載它的多個元素之間并沒有條件上下文關系,我們可以從下面的一段代碼中體會一下:
<div id="app"><h2 v-show="visible">v-show, visible = true</h2><h2 v-show="!visible">v-show, visible = false</h2><h2 v-if="visible">v-if, visible = true</h2><h2 v-else>v-if, visible = false</h2></div><script src="https://cdn.jsdelivr.net/npm/vue@2.5.16/dist/vue.min.js"></script><script type="text/javascript">let vm = new Vue({el: '#app',data () {return {visible: false}}})</script>從圖中可以看到,v-show判定為假的元素的display屬性被賦值為none,不過仍保留在DOM中,而v-if判定為假的元素則根本沒有在DOM中出現。 最后,筆者羅列了以下幾個注意點。
●v-if會在切換中將組件上的事件監聽器和子組件銷毀和重建。當組件被銷毀時,它將無法被任何方式獲取,因為它已不存在于DOM中。
●在創建父組件時,如果子組件的v-if被判定為假,Vue不會對子組件做任何事情,直到第一次判定為真時。這在使用Vue生命周期鉤子函數時要尤為注意,如果生命周期已走過組件創建的階段,卻仍無法獲取組件對象,想一想,是不是v-if在作怪。
●v-show有更高的初始渲染開銷,而v-if有更高的切換開銷,這與它們的實現機制有關,在使用時要多加考慮具體的應用場景。
●v-show不支持template元素,不過在Vue 2.0中,template的應用并不廣泛,了解即可。
v-if和v-show的組件化實例
<template><div><button @click="isshow = !isshow" >顯示/隱藏</button><div v-if="isshow">{{msg}}</div></div> </template> <script>export default {name: 'app',data(){return {msg: 'test',isshow: true,num: 0}},}</script> <style> #app {color: blue; } #box1{width: 150px;height: 150px;background: #FFA722; } #box2{width: 40px;height: 40px;background: coral; } </style>
按鍵顯示或者隱藏以后test會顯示或者隱藏
用v-show:將樣式隱藏了,但是元素還在。
v-if和v-show
v-if是“真正”的條件渲染,因為它會確保在切換過程中條件塊內的事件監聽器和子組件適當地被銷毀和重建。
v-show就簡單得多—不管初始條件是什么元素總是會被渲染,并且只是簡單地基于CSS進行切換
4.1 指令v-for
v-for用于實現列表渲染,可以使用item in items或者item of items的語法,代碼如下:
<!DOCTYPE html> <html> <head><title>Auto-fill Form Fields</title><style type="text/css">body {font: 1.2em arial, helvetica, sans-serif;margin-top: 50px;margin-left:500px;color: aqua;}</style></head> <body> <div id="app"><div style=" float: left; width: 160px;"><h2>用戶列表</h2><ul><!-- index作為第二個參數,用以標識下標 --><li v-for="(item, index) in users">{{ index }}. {{ item.name}}</li></ul></div><div style="margin-left: 170px;overflow: hidden"> <!-- BFC --><h2>用戶列表</h2><ul><!-- uIndex作為第二個參數,用以標識下標 --><li v-for="(user, uIndex) of users">{{ uIndex }}. {{ user.city }} {{ user.age }}</li></ul></div> </div> <script src="https://cdn.jsdelivr.net/npm/vue@2.5.16/dist/vue.min.js"></script> <script type="text/javascript">let vm = new Vue({el: '#app',data () {return {users: [{name: 'Clark',age: 27,city: 'Chicago'},{name: 'Jackson',age: 28,city: 'Sydney'}]}}}) </script> </body> </html>除了渲染數組之外,**v-for還可以渲染一個對象的鍵值對,**對上述示例中的HTML代碼稍作修改,修改后的代碼如下:
<div id="app"><h2>用戶列表</h2><ul><!-- index作為第二個參數,用以標識下標 --><li v-for="(user, index) in users">用戶{{ index + 1 }}<ul><!-- key作為第二個參數,用以標識鍵名 --><li v-for="(value, key) of user">{{ key }}: {{ value }}</li></ul></li></ul></div><script src="https://cdn.jsdelivr.net/npm/vue@2.5.16/dist/vue.min.js"></script> <script type="text/javascript">let vm = new Vue({el: '#app',data () {return {users: [{name: 'Clark',age: 27,city: 'Chicago'},{name: 'Jackson',age: 28,city: 'Sydney'}]}}}) </script>結果:
Vue會把數組當作被觀察者加入響應式系統中,當調用一些方法修改數組時,對應的視圖將會同步更新
與數據響應有關的數組方法 下面是一個用到了push()和reverse()方法的示例,代碼如下:
<div id="app"><h2>用戶列表</h2><button @click="createUser">創建用戶</button><button @click="reverse">倒序數組</button><ul><!-- index作為第二個參數,用以標識下標 --><li v-for="(user, index) in users">用戶{{ index + 1 }}<ul><!-- key作為第二個參數,用以標識鍵名 --><li v-for="(value, key) of user"><strong style="display: inline-block;width: 60px;">{{ key }}:</strong><span>{{ value }}</span></li></ul></li></ul> </div> <script src="https://cdn.jsdelivr.net/npm/vue@2.5.16/dist/vue.min.js"></script> <script type="text/javascript">let vm = new Vue({el: '#app',data () {return {users: []}},methods: {random (factor, base) { // 根據乘積因子和基數生成隨機整數return Math. floor(Math.random() * (factor || 1)) + (base || 0)},createUser () {// 獲取 name 大寫首字母let fLetter = '王張李吳何梁蘭'[this.random(6.999)]// 隨機截取 name 字符串let nameStr = '國靖新韓信鑫心欣辛夢梅眉舞灣宛菀莉利立歷黎'let bLetters = nameStr.substr(this.random(3.999), this.random(3.999, 1))let user = {name: fLetter + bLetters,age: this.random(5.999, 25),city: ['北京', '上海', '深圳', '杭州','大連'][this.random(4.999)]}console.log('--------------- 創建用戶 ---------------\n', user)this.users.push(user)},reverse () {console.log('--------------- 倒序列表 ---------------')console.log('Before:', this.users.map(user => user.name))this.users.reverse()console.log('After:', this.users.map(user => user.name))}}}) </script>注:<strong></strong>類似于<b></b>都是強調的,在網頁中形成的字是粗體,<strong>在性質上和一樣是屬于行內聯
結果:
點擊倒序數組以后:
注意:關于姓之后的字的多少用 let bLetters = nameStr.substr(this.random(3.999), this.random(1.999, 1))來控制,第二個this.random中第一個數字的大小
查看控制臺信息:
4.2 列表渲染中的key
在使用v-for時,最好為每個迭代元素提供一個值不重復的key。 當列表渲染被重新執行(數組內容發生改變)時,如果不使用key, Vue會為數組成員就近復用已存在的DOM節點,如圖所示。
不使用key時的列表渲染
當使用key時,Vue會根據key的變化重新排列節點順序,如圖所示,并將移除key不存在的節點。
實質上,key的存在是為DOM節點標注了一個身份信息,讓Vue能夠有跡可循追蹤到數據對應的節點。在實戰開發中,是否使用key都不會影響功能的實現,不過在Vue 2.2.0+的版本中,使用v-for時沒有附加key的話,Vue會給出一個警告。
計算屬性
Vue.js還提供了計算屬性這種方法,避免在模板中加入過重的業務邏輯,保證模板的結構清晰和可維護性。 1.基礎例子
var vm = new Vue({el : '#app,data: {firstName : 'Gavin',lastName: 'CLY'}computed : {fullName : function() {// this 指向vm實例return this.firstName + ' ' + this.lastName}} });<p>{{ firstName }}</p> // Gavin <p>{{ lastName }}</p> // CLY <p>{{ fullName }}</p> // Gavin CLY 此時,你對vm.firstName和vm.lastName進行修改,始終會影響vm.fullName。總結
- 上一篇: spring项目属性注入和bean管理x
- 下一篇: 笔记·mybatis核心对象和全局配置文