以前,咱們提到了vue能夠解析雙大括號中的語法,數據綁定——{{msg}},以及,列表渲染——v-for。在這一章中,咱們將詳細說明數據的幾種綁定/渲染方式。javascript
以前一章中咱們提到過,此處,咱們經過代碼,進行簡單回顧。css
<body> <div class="container"> <!-- data中的msg映射到此處 --> {{msg}} </div> <script type="text/javascript"> //構建Vue對象實例 new Vue({ //當前Vue對象的做用範圍 el:'.container', //定義頁面中須要渲染的數據 data:{ msg:'hello world' } }); </script> </body>
補充
咱們說過,在雙大括號中的語法變量可以被Vue解析。事實上,雙大括號中還可以放表達式,常規表達式都可以被解析。vue
下面舉幾個例子來講明
①{{a+b}}java
<body> <div class="container"> {{a+b}} </div> <script type="text/javascript"> new Vue({ el:'.container', data:{ a:1, b:2 } }); </script> <!-- 打印結果:3 --> </body>
②三目運算{{a ? 'a存在' : 'a不存在'}}
這句代碼的意思是:是否存在a,若是a存在,那麼打印「a存在」,不然,打印「a不存在」。數組
<body> <div class="container"> {{a?'a存在':'a不存在'}} </div> <script type="text/javascript"> new Vue({ el:'.container', data:{ a:1, b:2 } }); </script> <!-- 打印結果:a存在 --> </body>
若是a爲null,undefined,0,NaN,''等這些值的時候,那麼打印出的結果爲「a不存在」。
此處的原理是:數據類型的轉換。dom
單向數據綁定中msg的數據只能顯示,可是不能改變,經過雙向數據綁定v-model,咱們能夠在頁面中,人爲的改變其中的數據,而且這樣的改變是同步的。ide
v-model 指令能夠在表單 <input> 及 <textarea> 元素上建立雙向數據綁定,它負責監聽用戶的輸入事件以更新數據。
在v-model中,寫入你要綁定的值的模型。
好比,咱們要改變頁面中msg顯示的hello world,那麼咱們就能夠這樣寫,v-model="msg"。測試
咱們要記住,只有表單元素<input>及<textarea> 元素能夠進行雙向數據綁定。字體
下面經過具體例子來講明:ui
<body> <div class="container"> <p>{{msg}}</p> <!-- 雙向數據綁定 這裏,咱們經過input表單,來獲取用戶輸入的值 用v-model綁定模型 --> <input type="text" v-model="msg"> </div> <script type="text/javascript"> new Vue({ el:'.container', data:{ msg:'hello world' } }); </script> </body>
這裏咱們要理清思路:div中{{msg}}的值,是從咱們構建的Vue對象中的data中尋找到的。也就是說:咱們能夠改變表單元素的值,這個值會去改變data中msg的值,而後data中msg的值改變以後,上面div中{{msg}}的值也會發生改變。因此這種形式,咱們稱爲雙向數據綁定。
v-for,列表渲染以前也提到過,它是根據一組數組的選項列表進行渲染。
下面咱們經過簡單的代碼例子來回顧
<body> <div class="container"> <ul> <!-- 在li中經過v-for指令,來遍歷data中,arrList中的數據 自定義一個數據迭代的別名arr,而且arr可以遍歷arrList中的數據 經過雙大括號,將arr中的值輸入在內 --> <li v-for="arr in arrList">{{arr}}</li> </ul> </div> <script type="text/javascript"> new Vue({ el:'.container', data:{ arrList:['terry','larry'] } }); </script> <!-- 打印結果:以列表的形式打印出terry,larry --> </body>
條件渲染的表達式的返回值是「布爾類型」,而且與if-else循環語句類似。
下面來看一下幾種條件渲染的指令:
v-if指令中的值能夠是咱們本身定義在data中的值或者表達式。
表達式,如:"Math.random() > 0.5",這種返回值爲布爾類型的就能夠。
若是返回值爲「true」,那麼v-if中的內容會被顯示;反之,它不會被顯示。
下面來測試一下:
<body> <div class="container"> <!-- 若是data中的user存在,對應返回p標籤中的內容 --> <p v-if="user">歡迎您</p> </div> <script type="text/javascript"> new Vue({ el:'.container', data:{ user:'user',//打印結果:歡迎您 /* user:'',//打印結果:什麼都打印不出來 當user爲null,undefined,0,NaN,''等這些值的時候,都打印不出來 */ } }); </script> </body>
v-else必須與v-if或者v-else-if配合使用,不然它將不會被識別。
它的意思是,若是v-if的返回值爲「false」,那麼它將顯示v-else中的內容。
下面咱們來測試一下:
<body> <div class="container"> <p v-if="user">歡迎您</p> <p v-else>您未登錄</p> </div> <script type="text/javascript"> new Vue({ el:'.container', data:{ user:'', } }); </script> <!-- 打印結果:您未登錄 --> </body>
v-else-if,充當v-if的「else-if」部分,可連續使用。
它也必須緊跟在v-if以後,沒法單獨使用。
下面測試一下:
<body> <div class="container"> <p v-if="type === 'A'">A</p> <p v-else-if="type === 'B'">B</p> <p v-else-if="type === 'C'"> C</p> <p v-else>Not A/B/C</p> </div> <script type="text/javascript"> new Vue({ el:'.container', data:{ type:'B' } }); </script> <!-- 打印結果:B --> </body>
v-show的返回值也爲布爾類型,它用來控制代碼所示的視圖是否顯示。
但與v-if不一樣的是:帶有 v-show 的元素始終會被渲染並保留在DOM中,只是改變css中的display屬性。
下面來測試一下:
<body> <div class="container"> <p v-show="isShow">顯示</p> <!-- isShow是條件渲染的一個屬性,因此是一個變量,放在data中 --> </div> <script type="text/javascript"> new Vue({ el:'.container', data:{ isShow:false /*v-show意味着是否顯示,屬性爲假,所以不會顯示 若是 isShow:true,則會顯示*/ } }); </script> <!-- 無打印結果 --> </body>
下面引用一段官方文檔中的關於v-if與v-show區別的話。
v-if vs v-show
v-if 是「真正」的條件渲染,由於它會確保在切換過程當中條件塊內的事件監聽器和子組件適當地被銷燬和重建。
v-if 也是惰性的:若是在初始渲染時條件爲假,則什麼也不作——直到條件第一次變爲真時,纔會開始渲染條件塊。
相比之下,v-show 就簡單得多——無論初始條件是什麼,元素老是會被渲染,而且只是簡單地基於 CSS 進行切換。
通常來講,v-if 有更高的切換開銷,而 v-show 有更高的初始渲染開銷。所以,若是須要很是頻繁地切換,則使用 v-show 較好;若是在運行時條件不多改變,則使用 v-if 較好。
咱們先來看一下如下代碼
<body> <div class="container"> <!-- 怎麼顯示data中title的值 --> <button>按鈕</button> </div> <script type="text/javascript"> new Vue({ el:'.container', data:{ //隨便定義的值 title:'this is title' }, }); </script> </body>
此時,咱們有一個問題:如何讓data中title的值顯示到button中?
原先咱們是這麼寫的:
<button title="button">按鈕</button>
讓title的值在鼠標懸停到button上時,做爲提示顯示出來。
但這並非咱們所指望的,咱們但願懸停時顯示的值不是寫死的。
這時,咱們能夠用v-bind來給它綁定屬性。
v-bind能夠動態地綁定一個或多個特性,或一個組件prop到表達式(prop以後會在組件中講到)。
它的語法形式是這樣的:v-bind:屬性名="(定義在data中的)變量"
因此上面的代碼能夠這樣變一下:
<!-- v-bind動態的綁定(vue中的)屬性title --> <button v-bind:title="title">按鈕</button> <!-- 簡寫 <button :title="title">按鈕</button> -->
固然,它還能夠其餘特性:
1)樣式屬性的綁定(經過style)
(事件的綁定內容在下一章節會有)
如下面代碼爲例:
<body> <div class="container"> <!-- 目標:當咱們點擊p標籤,字體變色 --> <!-- 屬性的綁定用v-bind 爲樣式綁定屬性,咱們能夠用v-bind:style="", 簡寫 :style="" --> <!-- 直接寫對象,對象中由鍵值對組成,{樣式的屬性名:樣式的屬性值} 樣式的屬性值,必須在vue對象中的data中獲取 事件的綁定用v-on: 簡寫@ ,方法定義在methods中 --> <p :style="{color:fontColor}" @click="scale">{{msg}}</p> </div> <script type="text/javascript"> new Vue({ el:'.container', data:{ msg:'click me', fontColor:'#666' }, methods:{ // 當咱們點擊p標籤,字體變色 scale(){ this.fontColor='orange'; } } }); </script> </body>
2)樣式屬性的綁定(經過class)
<body> <style type="text/css"> .block { background-color: orange; color: #fff; border-radius: 3px; } .aaa { padding: .5em 1em; } .bbb { border:2px solid pink; } .ccc { font-weight: bold; font-size: 24px; } </style> <div class="container"> <!-- 第一種: 只有一個class--> <!-- 在class中的取值就爲一個變量 isBlock爲布爾類型的值 若是,isBlock爲true,那麼class的取值爲block 若是,isBlock爲false,那麼class的取值就不爲block 這種寫法必定要在style標籤中定義block樣式 --> <p v-bind:class="{block:isBlock}">{{msg}}</p> <!-- 第二種: 有多個class--> <!-- 用中括號將多個class包裹,每一個class之間用逗號分隔,至關於數組 --> <!-- {block:isBlock}:若是isBlock爲true,返回值爲block 'aaa':用引號引發來,至關於字符串,不會被解析,原樣輸出 className:沒有單引號,是一個變量,訪問data中的className class="ccc":常規css樣式 --> <p v-bind:class="[{block:isBlock},'aaa',className]" class="ccc">{{msg}}</p> </div> <script type="text/javascript"> new Vue({ el:'.container', data:{ msg:'click me', isBlock:true, // 定義一個樣式爲bbb className:'bbb', } }); </script> </body>
3)style樣式屬性中傳入對象
<body> <div class="container"> <!-- 直接給style屬性樣式傳入對象,並在data中定義 --> <!-- 只有一個對象 --> <p v-bind:style="styleObj">{{msg}}</p> <!-- 有多個對象 --> <p v-bind:style="[styleObj,styleObj2]">{{msg}}</p> </div> <script type="text/javascript"> new Vue({ el:'.container', data:{ msg:'click me', // 給style屬性傳入的對象 // 至關於將css的樣式規則寫在js中 styleObj:{ /*因爲是一個對象, 當屬性名爲普通字符串的時候不須要加引號, 當屬性名爲特殊寫法時,如background-color,要加引號 */ 'background-color':'pink', 'color':'#fff', 'padding':'.5em 1em' }, styleObj2:{ 'border-radius':'10px' } } }); </script> </body>
此處講解的只是基礎內容,若是想要詳細瞭解,能夠查看Vue.js官方教程文檔:https://cn.vuejs.org/v2/guide/