Vue.js 使用了基於 HTML 的模版語法,容許開發者聲明式地將 DOM 綁定至底層 Vue 實例的數據。全部 Vue.js 的模板都是合法的 HTML ,因此能被遵循規範的瀏覽器和 HTML 解析器解析。javascript
在底層的實現上, Vue 將模板編譯成虛擬 DOM 渲染函數。結合響應系統,在應用狀態改變時, Vue 可以智能地計算出從新渲染組件的最小代價並應用到 DOM 操做上。php
若是你熟悉虛擬 DOM 而且偏心 JavaScript 的原始力量,你也能夠不用模板,直接寫渲染(render)函數,使用可選的 JSX 語法。html
數據綁定最多見的形式就是使用 「Mustache」 語法(雙大括號)的文本插值:vue
<span>Message: {{ msg }}</span>
Mustache 標籤將會被替代爲對應數據對象上 msg 屬性的值。不管什麼時候,綁定的數據對象上 msg 屬性發生了改變,插值處的內容都會更新java
經過使用 v-once 指令,你也能執行一次性地插值,當數據改變時,插值處的內容不會更新。但請留心這會影響到該節點上全部的數據綁定:ios
<span v-once>This will never change: {{ msg }}</span>
v-text指令:更新元素的 textContent。若是要更新部分的 textContent ,須要使用 {{ Mustache }} 插值。git
<span v-text="msg"></span> <!-- 和下面的同樣 --> <span>{{msg}}</span>
示例:ajax
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Vue2模板語法</title> </head> <body> <div id="app1"> <input v-model="msg" /> <span v-once>{{msg}}</span> <h3 v-text="msg"></h3> <h3>{{msg}}</h3> </div> <script src="../js/vue.js" type="text/javascript" charset="utf-8"></script> <script type="text/javascript"> var app1 = new Vue({ el: "#app1", data:{ msg:"vue" } }); </script> </body> </html>
結果:vue-cli
雙大括號會將數據解釋爲純文本,而非 HTML 。爲了輸出真正的 HTML ,你須要使用 v-html 指令:bootstrap
<div v-html="rawHtml"></div>
被插入的內容都會被當作 HTML —— 數據綁定會被忽略。注意,你不能使用 v-html 來複合局部模板,由於 Vue 不是基於字符串的模板引擎。組件更適合擔任 UI 重用與複合的基本單元
站點上動態渲染的任意 HTML 可能會很是危險,由於它很容易致使 XSS 攻擊。請只對可信內容使用 HTML 插值,毫不要對用戶提供的內容插值
示例:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Vue2模板語法</title> </head> <body> <div id="app1"> <textarea v-model="msg" rows="3" cols="30"></textarea> <p>{{msg}}</p> <p v-html="msg"></p> </div> <script src="../js/vue.js" type="text/javascript" charset="utf-8"></script> <script type="text/javascript"> var app1 = new Vue({ el: "#app1", data:{ msg:"<span style='color:blue;font-weight:bold'>zhangguo</span>" } }); </script> </body> </html>
結果:
Mustache 不能在 HTML 屬性中使用,應使用 v-bind 指令:
<div v-bind:id="dynamicId"></div>
這對布爾值的屬性也有效 —— 若是條件被求值爲 false 的話該屬性會被移除:
<button v-bind:disabled="someDynamicCondition">Button</button>
someDynamicCondition爲true是disabled出現,爲false時移除disabled
示例:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Vue2模板語法</title> </head> <body> <div id="app1"> <button type="button" v-on:click="disabled=!disabled">反轉{{disabled}}</button> <button type="button" v-bind:disabled="disabled">提交</button> </div> <script src="../js/vue.js" type="text/javascript" charset="utf-8"></script> <script type="text/javascript"> var app1 = new Vue({ el: "#app1", data:{ disabled:true } }); </script> </body> </html>
結果:
修改disabled的值爲false
迄今爲止,在咱們的模板中,咱們一直都只綁定簡單的屬性鍵值。但實際上,對於全部的數據綁定, Vue.js 都提供了徹底的 JavaScript 表達式支持
{{ number + 1 }} {{ ok ? 'YES' : 'NO' }} {{ message.split('').reverse().join('') }} <div v-bind:id="'list-' + id"></div>
這些表達式會在所屬 Vue 實例的數據做用域下做爲 JavaScript 被解析。有個限制就是,每一個綁定都只能包含單個表達式,因此下面的例子都不會生效,不須要在屬性前使用this
{{ var a = 1 }} <!-- 這是語句,不是表達式 --> {{ if (ok) { return message } }} <!-- 流控制也不會生效,請使用三元表達式 -->
模板表達式都被放在沙盒中,只能訪問全局變量的一個白名單,如 Math 和 Date 。你不該該在模板表達式中試圖訪問用戶定義的全局變量
指令(Directives)是帶有 v- 前綴的特殊屬性。指令屬性的值預期是單一 JavaScript 表達式。指令的職責就是當其表達式的值改變時相應地將某些行爲應用到 DOM 上
<p v-if="seen">Now you see me</p>
這裏, v-if 指令將根據表達式 seen 的值的真假來移除/插入元素
經常使用的指令有:
示例:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Vue2模板語法</title> </head> <body> <div id="app1"> <button type="button" v-on:click="isShow=!isShow">反轉{{isShow}}</button> <button type="button" v-if="isShow">提交v-if</button> <button type="button" v-show="isShow">提交v-show</button> <br/><br/> <div> 等級A-C:<input v-model="type" /> </div> <div v-if="type === 'A'"> A優秀 </div> <div v-else-if="type === 'B'"> B良好 </div> <div v-else-if="type === 'C'"> C及格 </div> <div v-else> D其它 </div> </div> <script src="../js/vue.js" type="text/javascript" charset="utf-8"></script> <script type="text/javascript"> var app1 = new Vue({ el: "#app1", data: { isShow: true, type: 'D' } }); </script> </body> </html>
結果:
修改:
事件處理指令很是強大,說明以下:
v-on指令
縮寫:@
預期:Function | Inline Statement | Object
參數:event
修飾符:
.stop
- 調用 event.stopPropagation()
。.prevent
- 調用 event.preventDefault()
。.capture
- 添加事件偵聽器時使用 capture 模式。.self
- 只當事件是從偵聽器綁定的元素自己觸發時才觸發回調。.{keyCode | keyAlias}
- 只當事件是從特定鍵觸發時才觸發回調。.native
- 監聽組件根元素的原生事件。.once
- 只觸發一次回調。.left
- (2.2.0) 只當點擊鼠標左鍵時觸發。.right
- (2.2.0) 只當點擊鼠標右鍵時觸發。.middle
- (2.2.0) 只當點擊鼠標中鍵時觸發。.passive
- (2.3.0) 以 { passive: true }
模式添加偵聽器用法:
綁定事件監聽器。事件類型由參數指定。表達式能夠是一個方法的名字或一個內聯語句,若是沒有修飾符也能夠省略。
從 2.4.0
開始,v-on
一樣支持不帶參數綁定一個事件/監聽器鍵值對的對象。注意當使用對象語法時,是不支持任何修飾器的。
用在普通元素上時,只能監聽 原生 DOM 事件。用在自定義元素組件上時,也能夠監聽子組件觸發的自定義事件。
在監聽原生 DOM 事件時,方法以事件爲惟一的參數。若是使用內聯語句,語句能夠訪問一個 $event
屬性:v-on:click="handle('ok', $event)"
。
示例:
<!-- 方法處理器 --> <button v-on:click="doThis"></button> <!-- 對象語法 (2.4.0+) --> <button v-on="{ mousedown: doThis, mouseup: doThat }"></button> <!-- 內聯語句 --> <button v-on:click="doThat('hello', $event)"></button> <!-- 縮寫 --> <button @click="doThis"></button> <!-- 中止冒泡 --> <button @click.stop="doThis"></button> <!-- 阻止默認行爲 --> <button @click.prevent="doThis"></button> <!-- 阻止默認行爲,沒有表達式 --> <form @submit.prevent></form> <!-- 串聯修飾符 --> <button @click.stop.prevent="doThis"></button> <!-- 鍵修飾符,鍵別名 --> <input @keyup.enter="onEnter"> <!-- 鍵修飾符,鍵代碼 --> <input @keyup.13="onEnter"> <!-- 點擊回調只會觸發一次 --> <button v-on:click.once="doThis"></button>
在子組件上監聽自定義事件 (當子組件觸發「my-event」時將調用事件處理器):
<my-component @my-event="handleThis"></my-component> <!-- 內聯語句 --> <my-component @my-event="handleThis(123, $event)"></my-component> <!-- 組件中的原生事件 --> <my-component @click.native="onClick"></my-component>
示例:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Vue2模板語法</title> </head> <body> <div id="app1"> <div> 等級A-C:<input v-model="type" @keyup.13="submit_click($event)" /> </div> </div> <script src="../js/vue.js" type="text/javascript" charset="utf-8"></script> <script type="text/javascript"> var app1 = new Vue({ el: "#app1", data: { isShow: true, type: 'D' }, methods: { submit_click: function(e) { if(confirm("確證要提交嗎?")) { console.log(e); } } } }); </script> </body> </html>
結果:
示例:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Vue2 Demo</title> <style> [v-cloak] { display: none; } </style> </head> <body> <div id="app1" v-on:click="++n"> <div v-on:click="++n"> <a href="http://best.cnblogs.com" @click.stop.prevent.ctrl="go_click($event)">{{n}}</a> </div> <textarea cols="30" rows="5" @keyup.enter.ctrl="show" v-model="msg"></textarea> <p> {{msg}} </p> </div> <script src="../../js/vue/vue.min.js"></script> <script> var vm = new Vue({ el: "#app1", data: { isShow: true, students: ["tom", "mark", "rose"], level: "A", n: 1, msg:"" }, methods: { go_click: function (event) { console.log(event); //阻止事件冒泡 //event.stopPropagation(); //阻止默認事件 //event.preventDefault(); alert("準備進入博客園!"); }, show:function () { console.log(this.msg); } } }); </script> </body> </html>
運行結果:
一些指令能接受一個「參數」,在指令後以冒號指明。例如, v-bind 指令被用來響應地更新 HTML 屬性:
<a v-bind:href="url"></a>
在這裏 href 是參數,告知 v-bind 指令將該元素的 href 屬性與表達式 url 的值綁定
v-on 指令用於監聽 DOM 事件:
<a v-on:click="doSomething">
修飾符(Modifiers)是以半角句號 . 指明的特殊後綴,用於指出一個指令應該以特殊方式綁定:
<form v-on:submit.prevent="onSubmit"></form>
使用方法:
<!-- 方法處理器 --> <button v-on:click="doThis"></button> <!-- 對象語法 (2.4.0+) --> <button v-on="{ mousedown: doThis, mouseup: doThat }"></button> <!-- 內聯語句 --> <button v-on:click="doThat('hello', $event)"></button> <!-- 縮寫 --> <button @click="doThis"></button> <!-- 中止冒泡 --> <button @click.stop="doThis"></button> <!-- 阻止默認行爲 --> <button @click.prevent="doThis"></button> <!-- 阻止默認行爲,沒有表達式 --> <form @submit.prevent></form> <!-- 串聯修飾符 --> <button @click.stop.prevent="doThis"></button> <!-- 鍵修飾符,鍵別名 --> <input @keyup.enter="onEnter"> <!-- 鍵修飾符,鍵代碼 --> <input @keyup.13="onEnter"> <!-- 點擊回調只會觸發一次 --> <button v-on:click.once="doThis"></button>
Vue.js 容許你自定義過濾器,可被用做一些常見的文本格式化。過濾器能夠用在兩個地方:mustache 插值和 v-bind 表達式。過濾器應該被添加在 JavaScript 表達式的尾部,由「管道」符指示:
{{ message | capitalize }} <!-- in mustaches --> <div v-bind:id="rawId | formatId"></div> <!-- in v-bind -->
Vue 2.x 中,過濾器只能在 mustache 綁定和 v-bind 表達式(從 2.1.0 開始支持)中使用,由於過濾器設計目的就是用於文本轉換。爲了在其餘指令中實現更復雜的數據變換,你應該使用計算屬性
過濾器函數總接受表達式的值做爲第一個參數
new Vue({ filters: { capitalize: function (value) { if (!value) return '' value = value.toString() return value.charAt(0).toUpperCase() + value.slice(1) } } })
過濾器能夠串聯:
{{ message | filterA | filterB }}
過濾器是 JavaScript 函數,所以能夠接受參數:
{{ message | filterA('arg1', arg2) }}
這裏,字符串 'arg1' 將傳給過濾器做爲第二個參數, arg2 表達式的值將被求值而後傳給過濾器做爲第三個參數
在vue1中有一些內置的過濾器,而vue2中須要自定義。
示例:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Vue2模板語法</title> </head> <body> <div id="app1"> <span>{{msg | toUpper | toLower(" zhuhai")}}</span> </div> <div id="app2"> <span v-bind:title=" 'Hello Filter!' | toUpper">{{msg | toUpper | toLower}}</span> </div> <script src="../js/vue.js" type="text/javascript" charset="utf-8"></script> <script type="text/javascript"> //全局過濾器 Vue.filter("toUpper",function(value){ return value.toUpperCase(); }); var app1 = new Vue({ el: "#app1", data:{ msg:"China" }, filters:{ //帶參數的當前實例過濾器 toLower:function(value,add){ return value.toLowerCase()+add; } } }); //可使用全局過濾器 var app2 = new Vue({ el: "#app2", data:{ msg:"Vue" } }); </script> </body> </html>
結果:
v- 前綴在模板中是做爲一個標示 Vue 特殊屬性的明顯標識。當你使用 Vue.js 爲現有的標記添加動態行爲時,它會頗有用,但對於一些常用的指令來講有點繁瑣。同時,當搭建 Vue.js 管理全部模板的 SPA 時,v- 前綴也變得沒那麼重要了。所以,Vue.js 爲兩個最爲經常使用的指令提供了特別的縮寫:
<a v-bind:href="url"></a> <!-- 完整語法 --> <a :href="url"></a> <!-- 縮寫 -->
<a v-on:click="doSomething"></a> <!-- 完整語法 --> <a @click="doSomething"></a> <!-- 縮寫 -->
它們看起來可能與普通的 HTML 略有不一樣,但 : 與 @ 對於屬性名來講都是合法字符,在全部支持 Vue.js 的瀏覽器都能被正確地解析。並且,它們不會出如今最終渲染的標記。縮寫語法是徹底可選的。
在模板中綁定表達式是很是便利的,可是它們實際上只用於簡單的操做。在模板中放入太多的邏輯會讓模板太重且難以維護。例如:
<div id="example"> {{ message.split('').reverse().join('') }} </div>
在這種狀況下,模板再也不簡單和清晰。在實現反向顯示 message
以前,你應該確認它。這個問題在你不止一次反向顯示 message 的時候變得更加糟糕。
這就是爲何任何複雜邏輯,你都應當使用計算屬性。
<div id="example"> <p>Original message: "{{ message }}"</p> <p>Computed reversed message: "{{ reversedMessage }}"</p> </div>
var vm = new Vue({ el: '#example', data: { message: 'Hello' }, computed: { // a computed getter reversedMessage: function () { // `this` points to the vm instance return this.message.split('').reverse().join('') } } })
結果:
Original message: "Hello"
Computed reversed message: "olleH"
這裏咱們聲明瞭一個計算屬性 reversedMessage
。咱們提供的函數將用做屬性vm.reversedMessage
的 getter 。
console.log(vm.reversedMessage) // -> 'olleH' vm.message = 'Goodbye' console.log(vm.reversedMessage) // -> 'eybdooG'
你能夠打開瀏覽器的控制檯,修改 vm 。 vm.reversedMessage
的值始終取決於vm.message
的值。
你能夠像綁定普通屬性同樣在模板中綁定計算屬性。 Vue 知道 vm.reversedMessage
依賴於 vm.message
,所以當 vm.message
發生改變時,依賴於 vm.reversedMessage
的綁定也會更新。並且最妙的是咱們是聲明式地建立這種依賴關係:計算屬性的 getter 是乾淨無反作用的,所以也是易於測試和理解的。
你可能已經注意到咱們能夠經過調用表達式中的method來達到一樣的效果:
<p>Reversed message: "{{ reverseMessage() }}"</p>
// in component methods: { reverseMessage: function () { return this.message.split('').reverse().join('') } }
不通過計算屬性,咱們能夠在 method 中定義一個相同的函數來替代它。對於最終的結果,兩種方式確實是相同的。然而,不一樣的是計算屬性是基於它的依賴緩存。計算屬性只有在它的相關依賴發生改變時纔會從新取值。這就意味着只要 message
沒有發生改變,屢次訪問 reversedMessage
計算屬性會當即返回以前的計算結果,而沒必要再次執行函數。
這也一樣意味着以下計算屬性將不會更新,由於 Date.now()
不是響應式依賴:
computed: { now: function () { return Date.now() } }
相比而言,每當從新渲染的時候,method 調用總會執行函數。
咱們爲何須要緩存?假設咱們有一個重要的計算屬性 A ,這個計算屬性須要一個巨大的數組遍歷和作大量的計算。而後咱們可能有其餘的計算屬性依賴於 A 。若是沒有緩存,咱們將不可避免的屢次執行 A 的 getter !若是你不但願有緩存,請用 method 替代。
區別:
計算屬性只能看成屬性用,不能帶參數,有緩存,效率高
方法能夠直接調用,可帶參數,沒有緩存,每次調用都會執行,效率不如計算屬性高。
Vue.js 提供了一個方法 $watch
,它用於觀察 Vue 實例上的數據變更。當一些數據須要根據其它數據變化時, $watch
很誘人 —— 特別是若是你來自 AngularJS 。不過,一般更好的辦法是使用計算屬性而不是一個命令式的 $watch
回調。思考下面例子:
<div id="demo">{{ fullName }}</div>
var vm = new Vue({ el: '#demo', data: { firstName: 'Foo', lastName: 'Bar', fullName: 'Foo Bar' }, watch: { firstName: function (val) { this.fullName = val + ' ' + this.lastName }, lastName: function (val) { this.fullName = this.firstName + ' ' + val } } })
上面代碼是命令式的和重複的。跟計算屬性對比:
var vm = new Vue({ el: '#demo', data: { firstName: 'Foo', lastName: 'Bar' }, computed: { fullName: function () { return this.firstName + ' ' + this.lastName } } })
這樣更好,不是嗎?
計算屬性默認只有 getter ,不過在須要時你也能夠提供一個 setter :
// ... computed: { fullName: { // getter get: function () { return this.firstName + ' ' + this.lastName }, // setter set: function (newValue) { var names = newValue.split(' ') this.firstName = names[0] this.lastName = names[names.length - 1] } } } // ...
如今在運行 vm.fullName = 'John Doe'
時, setter 會被調用, vm.firstName
和vm.lastName
也會被對應更新。
示例:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>計算屬性和觀察者</title> </head> <body> <div id="app1"> 姓:<input v-model="x" /> 名: <input v-model="m" /> 姓名: <input v-model="xm" /> </div> <script src="../js/vue.js" type="text/javascript" charset="utf-8"></script> <script type="text/javascript"> var app1 = new Vue({ el: "#app1", data: { x: "", m: "" }, computed:{ xm:{ get:function(){ return this.x+this.m; }, set:function(value){ this.x=value.substring(0,1); this.m=value.substring(1); } } } }); app1.xm="張果"; </script> </body> </html>
結果:
示例:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Vue2 Demo</title> </head> <body> <div id="app1"> <p> n3 <input v-model="n3"/> </p> <p> 方法 n1<input v-model="n1"/>+n2<input v-model="n2"/>={{add()}} </p> <p> 屬性 n1 <input v-model="n1"/>+n2<input v-model="n2"/>=<input v-model="total"/> </p> <p> 監視 n1 <input v-model="n1"/>+n2<input v-model="n2"/>=<input v-model="sum"/> </p> </div> <script src="../../js/vue/vue.min.js"></script> <script> var vm = new Vue({ el: "#app1", data: { msg: "merry christmas!", n1: 1000, n2: 1000, n3: 2000, sum:0 }, //方法 methods: { add: function () { console.log("方法"); return parseInt(this.n1) + parseInt(this.n2); } }, //監視值的變化 watch: { n1: { handler:function (newV, oldV) { console.log(newV, oldV); this.sum=parseInt(this.n1) + parseInt(this.n2); }, deep:true, //是否深度監視 immediate:true //首次也調用 }, n2: function (newV, oldV) { console.log(newV, oldV); this.sum=parseInt(this.n1) + parseInt(this.n2); } }, //計算屬性 computed: { total: { get: function () { return parseInt(this.n1) + parseInt(this.n2); }, set: function (value) { this.n1 = parseInt(value) / 2; this.n2 = parseInt(value) / 2; } } } }); </script> </body> </html>
結果:
三者的區別:
計算屬性computed:計算屬性只能看成屬性用,不能帶參數,有緩存,效率高,,能夠直接與v-model綁定。
方法methods:方法能夠直接調用,可帶參數,沒有緩存,每次調用都會執行,效率不如計算屬性高,不可與v-model綁定。
監視watch:不能顯式調用(被監視的對象變化時被動調用),能夠對變化的控制更加具體,但應用複雜,能夠間接與v-model綁定。
雖然計算屬性在大多數狀況下更合適,但有時也須要一個自定義的 watcher 。這是爲何 Vue 提供一個更通用的方法經過 watch
選項,來響應數據的變化。當你想要在數據變化響應時,執行異步操做或昂貴操做時,這是頗有用的。
例如:
<div id="watch-example"> <p> Ask a yes/no question: <input v-model="question"> </p> <p>{{ answer }}</p> </div>
<!-- Since there is already a rich ecosystem of ajax libraries --> <!-- and collections of general-purpose utility methods, Vue core --> <!-- is able to remain small by not reinventing them. This also --> <!-- gives you the freedom to just use what you're familiar with. --> <script src="https://unpkg.com/axios@0.12.0/dist/axios.min.js"></script> <script src="https://unpkg.com/lodash@4.13.1/lodash.min.js"></script> <script> var watchExampleVM = new Vue({ el: '#watch-example', data: { question: '', answer: 'I cannot give you an answer until you ask a question!' }, watch: { // 若是 question 發生改變,這個函數就會運行 question: function (newQuestion) { this.answer = 'Waiting for you to stop typing...' this.getAnswer() } }, methods: { // _.debounce 是一個經過 lodash 限制操做頻率的函數。 // 在這個例子中,咱們但願限制訪問yesno.wtf/api的頻率 // ajax請求直到用戶輸入完畢纔會發出 // 學習更多關於 _.debounce function (and its cousin // _.throttle), 參考: https://lodash.com/docs#debounce getAnswer: _.debounce( function () { var vm = this if (this.question.indexOf('?') === -1) { vm.answer = 'Questions usually contain a question mark. ;-)' return } vm.answer = 'Thinking...' axios.get('https://yesno.wtf/api') .then(function (response) { vm.answer = _.capitalize(response.data.answer) }) .catch(function (error) { vm.answer = 'Error! Could not reach the API. ' + error }) }, // 這是咱們爲用戶中止輸入等待的毫秒數 500 ) } }) </script>
結果:
Ask a yes/no question:
I cannot give you an answer until you ask a question!
在這個示例中,使用 watch
選項容許咱們執行異步操做(訪問一個 API),限制咱們執行該操做的頻率,並直到咱們獲得最終結果時,才設置中間狀態。這是計算屬性沒法作到的。
除了 watch
選項以外,您還可使用 vm.$watch API 命令。
官方幫助: http://vuejs.org/guide/computed.html
示例:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>南方機器人</title> </head> <body> <div id="app1"> <p> 請輸入您的問題: <input v-model="question"> </p> <p>{{ answer }}</p> <p> <img v-bind:src="src"/> </p> </div> <script src="https://unpkg.com/lodash@4.13.1/lodash.min.js"></script> <script src="../js/vue.js" type="text/javascript" charset="utf-8"></script> <script src="https://unpkg.com/axios@0.12.0/dist/axios.min.js"></script> <script type="text/javascript"> var watchExampleVM = new Vue({ el: '#app1', data: { question: '', answer: '您問我一個問題我會給您一個答案!', url:'' }, watch: { // 若是 question 發生改變,這個函數就會運行 question: function(newQuestion) { this.answer = '等待您的輸入...' this.getAnswer() } }, methods: { // _.debounce 是一個經過 lodash 限制操做頻率的函數。 // 在這個例子中,咱們但願限制訪問yesno.wtf/api的頻率 // ajax請求直到用戶輸入完畢纔會發出 // 學習更多關於 _.debounce function (and its cousin // _.throttle), 參考: https://lodash.com/docs#debounce getAnswer: _.debounce( function() { var vm = this if(this.question.indexOf('?') === -1) { vm.answer = '問題請以問號(?)結束' return } vm.answer = '讓我想一想...' axios.get('https://yesno.wtf/api') .then(function(response) { vm.answer = _.capitalize(response.data.answer); vm.src=response.data.image; console.log(response); }) .catch(function(error) { vm.answer = '發生了錯誤,不能調用該應用程序接口' + error }) }, // 這是咱們爲用戶中止輸入等待的毫秒數 500 ) } }) </script> </body> </html>=
結果:
數據綁定一個常見需求是操做元素的 class 列表和它的內聯樣式。由於它們都是屬性 ,咱們能夠用v-bind
處理它們:只須要計算出表達式最終的字符串。不過,字符串拼接麻煩又易錯。所以,在 v-bind
用於 class
和 style
時, Vue.js 專門加強了它。表達式的結果類型除了字符串以外,還能夠是對象或數組。
咱們能夠傳給 v-bind:class
一個對象,以動態地切換 class 。
<div v-bind:class="{ active: isActive }"></div>
上面的語法表示 classactive
的更新將取決於數據屬性 isActive
是否爲 真值 。
咱們也能夠在對象中傳入更多屬性用來動態切換多個 class 。此外, v-bind:class
指令能夠與普通的 class 屬性共存。以下模板:
<div class="static" v-bind:class="{ active: isActive, 'text-danger': hasError }"> </div>
以下 data:
data: { isActive: true, hasError: false }
渲染爲:
<div class="static active"></div>
當 isActive
或者 hasError
變化時,class 列表將相應地更新。例如,若是 hasError
的值爲 true
, class列表將變爲 "static active text-danger"
。
你也能夠直接綁定數據裏的一個對象:
<div v-bind:class="classObject"></div>
data: { classObject: { active: true, 'text-danger': false } }
渲染的結果和上面同樣。咱們也能夠在這裏綁定返回對象的 計算屬性。這是一個經常使用且強大的模式:
<div v-bind:class="classObject"></div>
data: { isActive: true, error: null }, computed: { classObject: function () { return { active: this.isActive && !this.error, 'text-danger': this.error && this.error.type === 'fatal', } } }
示例:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Class 與 Style 綁定</title> <style> .valide{ display: none; } .priceRequired{ display: inline; } .priceRange{ display: inline; } </style> </head> <body> <div id="app1"> <span class="bgGreen" v-bind:class="{bgRed:isShow,bgBlue:isActive}">span1</span> <span class="bgGreen" v-bind:class="classObj1">span2</span> <p> <label>價格:</label> <input v-model="price" /><span class="valide" v-bind:class="priceValide1">必填</span><span class="valide" v-bind:class="priceValide2">介於0.1-99999之間</span> </p> </div> <script src="../js/vue.js" type="text/javascript" charset="utf-8"></script> <script type="text/javascript"> var app1 = new Vue({ el: "#app1", data:{ isShow:true, isActive:false, classObj1:{ isHide:true, isRight:false }, price:0 }, computed: { priceValide1:function(){ return { priceRequired:this.price==='' } }, priceValide2:function(){ return { priceRange:this.price!=''&&(this.price<0.1||this.price>99999) } } } }); </script> </body> </html>
結果:
咱們能夠把一個數組傳給 v-bind:class
,以應用一個 class 列表:
<div v-bind:class="[activeClass, errorClass]">
data: { activeClass: 'active', errorClass: 'text-danger' }
渲染爲:
<div class="active text-danger"></div>
若是你也想根據條件切換列表中的 class ,能夠用三元表達式:
<div v-bind:class="[isActive ? activeClass : '', errorClass]">
此例始終添加 errorClass
,可是隻有在 isActive
是 true 時添加 activeClass
。
不過,當有多個條件 class 時這樣寫有些繁瑣。能夠在數組語法中使用對象語法:
<div v-bind:class="[{ active: isActive }, errorClass]">
示例:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Class 與 Style 綁定</title> </head> <body> <div id="app1"> <span class="bgGreen" v-bind:class="[isHide,isRight]">span3</span> <span class="bgGreen" v-bind:class="[(isShow?'bg3':''),isRight,bg4]">span4</span> <span class="bgGreen" v-bind:class="[{bg3:isShow},isRight,bg4]">span5</span> </div> <script src="../js/vue.js" type="text/javascript" charset="utf-8"></script> <script type="text/javascript"> var app1 = new Vue({ el: "#app1", data: { isShow: true, isHide: 'bg1', isRight: 'bg2', price: 0 } }); </script> </body> </html>
結果:
This section assumes knowledge of Vue Components. Feel free to skip it and come back later.
When you use the class
attribute on a custom component, those classes will be added to the component’s root element. Existing classes on this element will not be overwritten.
For example, if you declare this component:
Vue.component('my-component', { template: '<p class="foo bar">Hi</p>' })
Then add some classes when using it:
<my-component class="baz boo"></my-component>
The rendered HTML will be:
<p class="foo bar baz boo">Hi</p>
The same is true for class bindings:
<my-component v-bind:class="{ active: isActive }"></my-component>
When isActive
is truthy, the rendered HTML will be:
<div class="foo bar active"></div>
v-bind:style
的對象語法十分直觀——看着很是像 CSS ,其實它是一個 JavaScript 對象。 CSS 屬性名能夠用駝峯式(camelCase)或短橫分隔命名(kebab-case):
<div v-bind:style="{ color: activeColor, fontSize: fontSize + 'px' }"></div>
data: { activeColor: 'red', fontSize: 30 }
直接綁定到一個樣式對象一般更好,讓模板更清晰:
<div v-bind:style="styleObject"></div>
data: { styleObject: { color: 'red', fontSize: '13px' } }
一樣的,對象語法經常結合返回對象的計算屬性使用。
v-bind:style
的數組語法能夠將多個樣式對象應用到一個元素上:
<div v-bind:style="[baseStyles, overridingStyles]">
當 v-bind:style
使用須要特定前綴的 CSS 屬性時,如 transform
,Vue.js 會自動偵測並添加相應的前綴。
官方幫助: http://vuejs.org/guide/class-and-style.html
https://git.coding.net/zhangguo5/vue2.git
https://www.bilibili.com/video/av17503637/
6.一、請把v-on指令的每一種「修飾符」與調用方式都應用一遍。
<!-- 方法處理器 --> <button v-on:click="doThis"></button> <!-- 對象語法 (2.4.0+) --> <button v-on="{ mousedown: doThis, mouseup: doThat }"></button> <!-- 內聯語句 --> <button v-on:click="doThat('hello', $event)"></button> <!-- 縮寫 --> <button @click="doThis"></button> <!-- 中止冒泡 --> <button @click.stop="doThis"></button> <!-- 阻止默認行爲 --> <button @click.prevent="doThis"></button> <!-- 阻止默認行爲,沒有表達式 --> <form @submit.prevent></form> <!-- 串聯修飾符 --> <button @click.stop.prevent="doThis"></button> <!-- 鍵修飾符,鍵別名 --> <input @keyup.enter="onEnter"> <!-- 鍵修飾符,鍵代碼 --> <input @keyup.13="onEnter"> <!-- 點擊回調只會觸發一次 --> <button v-on:click.once="doThis"></button>
6.二、請完成一個商品管理模塊,要求以下:
6.三、加強商品管理
6.四、復現全部上課示例
6.五、請完成一個智能機器人,重點練習使用vue-cli+app界面(任意框架)
接口:http://www.itpk.cn/robot.php、http://www.haoservice.com/docs/119
打包後在手機端根據提問給出答案,app界面