指令 (Directives) 是帶有 v-
前綴的特殊特性。指令特性的值預期是單個 JavaScript 表達式 (v-for
是例外狀況,稍後咱們再討論)。指令的職責是,當表達式的值改變時,將其產生的連帶影響,響應式地做用於 DOM。javascript
<p v-if="seen">如今你看到我了</p>
這裏,v-if
指令將根據表達式 seen
的值的真假來插入/移除 <p>
元素html
一些指令可以接收一個「參數」,在指令名稱以後以冒號表示。例如,v-bind
指令能夠用於響應式地更新 HTML 特性:vue
<a v-bind:href="url">...</a>
在這裏 href
是參數,告知 v-bind
指令將該元素的 href
特性與表達式 url
的值綁定。java
另外一個例子是 v-on
指令,它用於監聽 DOM 事件:react
<a v-on:click="doSomething">...</a>
在這裏參數是監聽的事件名。咱們也會更詳細地討論事件處理。ajax
v-bind 漸變寫法 :
<!-- 完整語法 --> <a v-bind:href="url">...</a> <!-- 縮寫 --> <a :href="url">...</a>
v-on 簡便寫法 @click
<!-- 完整語法 --> <a v-on:click="doSomething">...</a> <!-- 縮寫 --> <a @click="doSomething">...</a>
咱們用 v-for
指令根據一組數組的選項列表進行渲染。v-for
指令須要使用 item in items
形式的特殊語法,items
是源數據數組而且 item
是數組元素迭代的別名。數組
<ul id="example-1"> <li v-for="item in items"> {{ item.message }} </li> </ul> var example1 = new Vue({ el: '#example-1', data: { items: [ { message: 'Foo' }, { message: 'Bar' } ] } })
結果:緩存
你也能夠用 of 替代 in 做爲分隔符,由於它是最接近 JavaScript 迭代器的語法: <div v-for="item of items"></div>
另外一個用於根據條件展現元素的選項是 v-show
指令。用法大體同樣:cookie
<h1 v-show="ok">Hello!</h1>
注意,v-show
不支持 <template>
元素,也不支持 v-else
。不一樣的是帶有 v-show
的元素始終會被渲染並保留在 DOM 中。v-show
只是簡單地切換元素的 CSS 屬性 display
。session
7. v-if
vs v-show
v-if 是「真正」的條件渲染,由於它會確保在切換過程當中條件塊內的事件監聽器和子組件適當地被銷燬和重建。 v-if 也是惰性的:若是在初始渲染時條件爲假,則什麼也不作——直到條件第一次變爲真時,纔會開始渲染條件塊。 相比之下,v-show 就簡單得多——無論初始條件是什麼,元素老是會被渲染,而且只是簡單地基於 CSS 進行切換。 通常來講,v-if 有更高的切換開銷,而 v-show 有更高的初始渲染開銷。所以,若是須要很是頻繁地切換,則使用 v-show 較好;若是在運行時條件不多改變,則使用 v-if 較好。
<div id="app"> <div v-html='str'></div> </div> var app = new Vue({ el:'#app', data:{ str:'<p>嘿嘿嘿</p>', }, }
指令系統、對象的單體模式、vue的生命週期練習、輪播圖示例
<!doctype html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <style> *{ margin: 0; padding:0; } #app{ width: 600px; margin: 100px auto; } .box{ width: 100px; height:100px; background-color: red; } .box2{ background-color: green; } .box3{ background-color: yellow; } ul{ width: 180px; list-style: none; overflow: hidden; } ul li{ background-color: purple; margin-left: 10px; float: left; width: 30px; height: 30px; text-align: center; color: white; } </style> <title>Document</title> </head> <body> <div id="app"> <!-- 插值語法 react {} angular {{}} {%%} <%%> --> <h3>{{msg}}</h3> <h3>{{1>2?"真的":"假的"}}</h3> <h3>{{1+1}}</h3> <div v-if="show">哈哈指令系統</div> <div v-if="Math.random()>0.5"> Now you see me </div> <div v-else-if="Math.random()>0.3"> Now you do </div> <div v-else> Now you don't </div> <h3 v-show="isShow" v-bind:title='title'>這是一個三級標題</h3> <img v-bind:src="imgSrc" v-bind:alt="time"> <!-- v-bind 漸變寫法 : --> <!-- v-on 簡便寫法 @click --> <button v-on:click="clickHandler">切換</button> <div class="box" :class="{box2:isGreen,box3:isYellow}"></div> <button @click="changeColor">切換顏色</button> <button @click='count+=1'>加{{count}}</button> <!-- 聲明式的指令 命令式 --> <div class="lunbo"> <img :src="currentSrc" alt="" @mouseenter='closeTimer' @mouseleave='openTimer'> <ul> <li v-for="(item,index) in imgArr" @click='currentHandler(item)'>{{index+1}}</li> </ul> <button @click="lastImg">上一張</button> <button @click="nextImg">下一張</button> </div> <div v-html='str'></div> </div> <script src="vue.js"></script> <script type="text/javascript"> // vue的實例化對象 // MVVM Model View ViewModel // MTV Model Template View // 指令系統 // 核心思想概念:數據驅動視圖 var app = new Vue({ el:'#app', data:{ msg:'今天學習vue', msg2:'今天學vue2', title:'三級標題', show:false, isShow:true, imgSrc:'石原.jpg', time:`頁面加載於${new Date().toLocaleString()}`, isGreen:false, isYellow:false, count:0, currentSrc:'1.jpg', imgArr:[ {'id':1,'src':'1.jpg'}, {'id':2,'src':'2.jpg'}, {'id':3,'src':'3.jpg'}, {'id':4,'src':'4.jpg'}, ], currentIndex:0, timer: null, str:'<p>嘿嘿嘿</p>', }, created(){ // 提早獲取cookie和session this.timer = setInterval(this.nextImg,2000) }, methods:{ // 對象的單體模式 // clickHandler:function(){ clickHandler(){ // alert('111') console.log(this); this.show = !this.show; }, changeColor(){ this.isGreen = !this.isGreen }, currentHandler(item){ this.currentSrc = item.src }, nextImg(){ if (this.currentIndex == this.imgArr.length) { this.currentIndex=1 }else{ this.currentIndex++; } console.log(this.currentIndex, this.imgArr.length); this.currentSrc = this.imgArr[this.currentIndex-1].src }, lastImg(){ if (this.currentIndex == 1) { this.currentIndex=this.imgArr.length }else{ this.currentIndex--; } this.currentSrc = this.imgArr[this.currentIndex-1].src }, closeTimer(){ clearInterval(this.timer) }, openTimer(){ this.timer = setInterval(this.nextImg,2000) } } }) console.log(app); console.log(app.$data.msg); console.log(app.msg); </script> </body> </html>
你可能已經注意到咱們能夠經過在表達式中調用方法來達到一樣的效果:
<p>Reversed message: "{{ reversedMessage() }}"</p>
// 在組件中
methods: {
reversedMessage: function () {
return this.message.split('').reverse().join('')
}
}
這也一樣意味着下面的計算屬性將再也不更新,由於 Date.now()
不是響應式依賴:咱們能夠將同一函數定義爲一個方法而不是一個計算屬性。兩種方式的最終結果確實是徹底相同的。然而,不一樣的是計算屬性是基於它們的依賴進行緩存的。只在相關依賴發生改變時它們纔會從新求值。這就意味着只要 message
尚未發生改變,屢次訪問 reversedMessage
計算屬性會當即返回以前的計算結果,而沒必要再次執行函數。
computed: { now: function () { return Date.now() } }
咱們爲何須要緩存?假設咱們有一個性能開銷比較大的計算屬性 A,它須要遍歷一個巨大的數組並作大量的計算。而後咱們可能有其餘的計算屬性依賴於 A 。若是沒有緩存,咱們將不可避免的屢次執行 A 的 getter!若是你不但願有緩存,請用方法來替相比之下,每當觸發從新渲染時,調用方法將總會再次執行函數。
<div id="computed"> <div> <!-- 字符串反轉 --> <!-- {{msg.split('').reverse().join('')}} --> {{reverseStr}} </div> <button @click="clickHandler">修改</button> </div> <script type="text/javascript" src="vue.js"></script> <script type="text/javascript"> var com = new Vue({ el:'#computed', data:{ msg:'hello world', }, methods:{ clickHandler(){ // this.msg = 'hello zhangyafei' console.log(this.reverseStr); this.reverseStr = 'hello zhangyafei' } }, computed:{ // 默認只有getattr方法 // reverseStr(){ // return this.msg.split('').reverse().join(''); // } // set方法 reverseStr:{ set:function(newValue){ this.msg = newValue }, get:function(){ return this.msg.split('').reverse().join('') } } } }) </script>
表單輸入綁定的應用
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> </head> <body> <form id="computed" @submit.prevent> <!-- 雙向綁定 --> 文本 <input type="text" name="" v-model='msg'> <!-- <input type="text" v-bind:value='getValue' @input='msgChange'> --> <input type="text" v-model.lazy='msg'> <input type="number" v-model.number='msg'> <br> 多行文本 <textarea v-model="msg" placeholder="add multiple lines"></textarea> </br> <input type="submit" name="" value="提交"> <h3>{{msg}}</h3> <div>單選框<br> <input type="checkbox" id="checkbox" v-model="checked"> <label for="checkbox">{{ checked }}</label> </div> <div> 多選框<br> <input type="checkbox" id="jack" value="Jack" v-model="checkedNames"> <label for="jack">Jack</label> <input type="checkbox" id="john" value="John" v-model="checkedNames"> <label for="john">John</label> <input type="checkbox" id="mike" value="Mike" v-model="checkedNames"> <label for="mike">Mike</label> <br> <span>Checked names: {{ checkedNames }}</span> </div> <div id="example-4">單選按鈕<br> <input type="radio" id="one" value="One" v-model="picked"> <label for="one">One</label> <br> <input type="radio" id="two" value="Two" v-model="picked"> <label for="two">Two</label> <br> <span>Picked: {{ picked }}</span> </div> <div id="example-5">選擇下拉框<br> <select v-model="selected"> <option disabled value="">請選擇</option> <option>A</option> <option>B</option> <option>C</option> </select> <span>Selected: {{ selected }}</span> </div> <div id="example-6"> 多選狀況<br> <select v-model="mul_selected" multiple style="width: 50px;"> <option>A</option> <option>B</option> <option>C</option> </select> <br> <span>Selected: {{ mul_selected }}</span> </div> <select v-model="for_selected">v-for渲染的動態狀況<br> <option v-for="option in options" v-bind:value="option.value"> {{ option.text }} </option> </select> <span>Selected: {{ for_selected }}</span> </form> <script type="text/javascript" src="vue.js"></script> <script type="text/javascript"> var com = new Vue({ el:'#computed', data:{ msg:'123', checked:false, checkedNames:[], picked:'', selected:'', for_selected:'', mul_selected:'', options: [ { text: 'One', value: 'A' }, { text: 'Two', value: 'B' }, { text: 'Three', value: 'C' } ], }, methods:{ msgChange(e){ console.log(e.target.value) this.getValue = e.target.value; } // $.ajax() xmlhttpRequest }, computed:{ getValue:{ set:function(newValue){ self.msg = newValue; }, get:function(){ return self.msg } } } }) </script> </body> </html>