##Python項目-Day55-vue-watch-computed-class與style綁定-列表渲染-事件處理-表單輸入綁定
-
偵聽器watch
當有一些數據改變時,watch會監聽到這些數據的改變
<div id="myapp"> <input type="text" v-model="firstName"> <input type="text" v-model="lastName"> <h1 v-text="fullName"></h1> </div> let app =new Vue({ el:'#myapp', data:{ firstName:"abc", lastName:"edf", }, watch:{ firstName:function (newval,oldval) { console.log(newval,oldval) }, lastName:function (newval,oldval) { console.log(newval,oldval) } } //比如說這裏會監聽到firstName和lastName的變化,第一個參數是新值,第二個參數是舊值
-
計算屬性computed
在computed:{}中定義的屬性可以直接用,但是不能和data裏面的屬性重名
<div id="myapp"> <input type="text" v-model="firstName"> <input type="text" v-model="lastName"> <h1 v-text="fullName"></h1> </div> let app =new Vue({ el:'#myapp', data:{ firstName:"abc", lastName:"edf", }, computed:{ fullName:function (val) { return this.firstName+this.lastName; } }}) //這裏firstName和lastName發生變化時,fullName都會發生變化
setter和getter
計算屬性默認只有 getter ,不過在需要時你也可以提供一個 setter :
computed:{ fullName:{ get:function () { return this.firstName+this.lastName; }, set:function (newval,oldval) { this.firstName=1; this.lastName=2; console.log(this.firstName,this.lastName) } }, } app.fullName=1 當運行app.fullName=1的時,setter會被調用this.firstName和this.lastName會被刷新
-
class與style綁定
在將 v-bind 用於 class 和 style 時,Vue.js 做了專門的增強。表達式結果的類型除了字符串之外,還可以是對象或數組。
-
對象語法
我們可以傳給 v-bind:class 一個對象,以動態地切換 class:
例如:實現點擊切換背景顏色
<div style="width: 200px;height: 200px" :class="{'background-green':ok}"></div> <button @click="ok=!ok"></button> el:'#myapp', data:{ ok:true, },
-
數組語法
<div :class="[borderClass,backClass]"></div> //或者這樣寫 //<div :class="['haveBorder',backClass]"></div> data:{ borderClass:'haveBorder', backClass:'background-green' }
-
多重值
<div :style="{ display: ['-webkit-box', '-ms-flexbox', 'flex'] }"></div>
這樣寫只會渲染數組中最後一個被瀏覽器支持的值。在本例中,如果瀏覽器支持不帶瀏覽器前綴的 flexbox,那麼就只會渲染 display: flex。
-
-
條件渲染
使用v-if可以使元素顯示或者不顯示
<h1 v-if="!ok">123</h1>
v-else:
<h1 v-if="!ok">123</h1> <h1 v-else>NO</h1> //這時只顯示一個
-
在 元素上使用 v-if 條件渲染分組
v-if只能控制本身,如果想要控制一組元素,可以使用再一組元素之外加上div或者template,但是div會被渲染出來,而template不會被渲染出來
<template v-if="ok"> <h1 >123</h1> <h1 >234</h1> <h1 >456</h1> </template>
-
v-else-if
<template v-if="ok==1"> <h1 >123</h1> </template> <template v-if="ok==2"> <h1 >456</h1> </template> <template v-if="ok==3"> <h1 >789</h1> </template>
當ok=2的時候 456 出現
-
用key管理可複用的元素
Vue 會儘可能高效地渲染元素,通常會複用已有元素而不是從頭開始渲染。這麼做除了使 Vue 變得非常快之外,還有其它一些好處。例如,如果你允許用戶在不同的登錄方式之間切換:
<template v-if="loginType === 'username'"> <label>Username</label> <input placeholder="Enter your username"> </template> <template v-else> <label>Email</label> <input placeholder="Enter your email address"> </template>
那麼在上面的代碼中切換 loginType 將不會清除用戶已經輸入的內容。因爲兩個模板使用了相同的元素,<input> 不會被替換掉——僅僅是替換了它的 placeholder。
這樣也不總是符合實際需求,所以 Vue 爲你提供了一種方式來表達“這兩個元素是完全獨立的,不要複用它們”。只需添加一個具有唯一值的 key 屬性即可:
<template v-if="loginType === 'username'"> <label>Username</label> <input placeholder="Enter your username" key="username-input"> </template> <template v-else> <label>Email</label> <input placeholder="Enter your email address" key="email-input"> </template> //添加了key屬性之後,兩個input就會被區分開
-
-
v-show
用於根據條件展示元素的選項是 v-show 指令,類似v-if
<h1 v-show="ok">123</h1>
不同的是帶有 v-show 的元素始終會被渲染並保留在 DOM 中。v-show 只是簡單地切換元素的 CSS 屬性 display。
注意,v-show 不支持 元素,也不支持 v-else。
-
v-if和v-show的區別:
v-if 是“真正”的條件渲染,因爲它會確保在切換過程中條件塊內的事件監聽器和子組件適當地被銷燬和重建。
v-if 也是惰性的:如果在初始渲染時條件爲假,則什麼也不做——直到條件第一次變爲真時,纔會開始渲染條件塊。
相比之下,v-show 就簡單得多——不管初始條件是什麼,元素總是會被渲染,並且只是簡單地基於 CSS 進行切換。
一般來說,v-if 有更高的切換開銷,而 v-show 有更高的初始渲染開銷。因此,如果需要非常頻繁地切換,則使用 v-show 較好;如果在運行時條件很少改變,則使用 v-if 較好。
-
v-if 與 v-for 一起使用
當 v-if 與 v-for 一起使用時,v-for 具有比 v-if 更高的優先級,官方不推薦v-if和v-for同時使用。
若想要同時使用:
<template v-for="job in jobs"> <h1 v-text="job.title"></h1> </template>
-
-
列表渲染
用 v-for 指令根據一組數組的選項列表進行渲染。v-for 指令需要使用 item in items 形式的特殊語法,items 是源數據數組並且 item 是數組元素迭代的別名。
在 v-for 塊中,我們擁有對父作用域屬性的完全訪問權限。v-for 還支持一個可選的第二個參數爲當前項的索引。
<template v-for="(job,index) in jobs"> <h1 v-text="job.title+index"></h1> </template> data:{ jobs:[ {"id":"001","title":"python","salary":8000}, {"id":"001","title":"pytshon","salary":8000}, {"id":"001","title":"pytshon","salary":80}, ] } //結果 python0 pytshon1 pytshon2
-
循環列出json
<template v-for="(value,key) in jobs"> <h1 v-text="value+'---'+key"></h1> </template> <template v-for="key in jobs"> <h1 v-text="key"></h1> </template> jobs:{ "name":"tom", "age":18, "hobby":"eat" } //結果 tom---name 18---age eat---hobby tom 18 eat
-
建議在遍歷的時候使用key
<template v-for="(value,key,index) in jobs"> <h1 v-text="value+'---'+key" :key="key+index"></h1> </template>
-
數組更新檢測
Vue 包含一組觀察數組的變異方法,所以它們也將會觸發視圖更新。這些方法如下:
push() pop() shift() unshift() splice() sort() reverse()
在控制輸入app.jobs.pop(),會發現頁面會少一個h1標籤
-
注意事項
由於 JavaScript 的限制,Vue 不能檢測以下變動的數組:
app.jobs[2]="爬蟲"
但是下面的變動會被檢測到:
app.jobs[2].title="爬蟲"
修改長度也不是響應式的:
app.jobs.length=7
可以使用$set來使數組被檢測到:
app.$set(app.jobs,2,"爬蟲")
-
對象更改檢測注意事項
還是由於 JavaScript 的限制,Vue 不能檢測對象屬性的添加或刪除:
var vm = new Vue({ data: { a: 1 } }) // `vm.a` 現在是響應式的 vm.b = 2 // `vm.b` 不是響應式的
對於已經創建的實例,Vue 不能動態添加根級別的響應式屬性。但是,可以使用 Vue.set(object, key, value) 方法向嵌套對象添加響應式屬性。例如,對於:
var vm = new Vue({ data: { userProfile: { name: 'Anika' } } })
你可以添加一個新的 age 屬性到嵌套的 userProfile 對象:
Vue.set(vm.userProfile, 'age', 27)
你還可以使用 vm.$set 實例方法,它只是全局 Vue.set 的別名:
vm.$set(vm.userProfile, 'age', 27)
-
-
顯示過濾/排序結果
有時,我們想要顯示一個數組的過濾或排序副本,而不實際改變或重置原始數據。在這種情況下,可以創建返回過濾或排序數組的計算屬性。
<li v-for="n in evenNumbers">{{ n }}</li> data: { numbers: [ 1, 2, 3, 4, 5 ] }, computed: { evenNumbers: function () { return this.numbers.filter(function (number) { return number % 2 === 0 }) } }
-
一段取值範圍的 v-for
v-for 也可以取整數。在這種情況下,它將重複多次模板。
<div> <span v-for="n in 10">{{ n }} </span> </div>
-
-
事件處理
可以用 v-on 指令監聽 DOM 事件,並在觸發時運行一些 JavaScript 代碼。
<div id="example-1"> <button v-on:click="counter += 1">Add 1</button> <p>The button above has been clicked {{ counter }} times.</p> </div> var example1 = new Vue({ el: '#example-1', data: { counter: 0 } })
事件處理方法:
<div id="example-2"> <!-- `greet` 是在下面定義的方法名 --> <button v-on:click="greet">Greet</button> </div>
方法傳值:
<button @click="say('hi')"></button> say:function(msg){ console.log(msg) },
把特殊變量$event傳入方法:
<button @click="say('hi',$event)"></button> say:function(msg,event){ console.log(msg,event.target.nodeName)//button },
事件修飾符:
在事件處理程序中調用 event.preventDefault() 或 event.stopPropagation() 是非常常見的需求。儘管我們可以在方法中輕鬆實現這點,但更好的方式是:方法只有純粹的數據邏輯,而不是去處理 DOM 事件細節。
爲了解決這個問題,Vue.js 爲 v-on 提供了事件修飾符。之前提過,修飾符是由點開頭的指令後綴來表示的。
<!-- 阻止單擊事件繼續傳播 --> <a v-on:click.stop="doThis"></a> <!-- 提交事件不再重載頁面 --> <form v-on:submit.prevent="onSubmit"></form> <!-- 修飾符可以串聯 --> <a v-on:click.stop.prevent="doThat"></a> <!-- 只有修飾符 --> <form v-on:submit.prevent></form> <!-- 添加事件監聽器時使用事件捕獲模式 --> <!-- 即元素自身觸發的事件先在此處理,然後才交由內部元素進行處理 --> <div v-on:click.capture="doThis">...</div> <!-- 只當在 event.target 是當前元素自身時觸發處理函數 --> <!-- 即事件不是從內部元素觸發的 --> <div v-on:click.self="doThat">...</div>
案件修飾符:
在監聽鍵盤事件時,我們經常需要檢查常見的鍵值。Vue 允許爲 v-on 在監聽鍵盤事件時添加按鍵修飾符:
<input type="text" v-on:keyup.enter="say()" v-model="txt">
檢測用戶輸入按鍵:
<input type="text" v-on:keyup="say($event)" v-model="txt"> say:function(event){ console.log(event.key); },
-
表單輸入綁定
你可以用 v-model 指令在表單 <input>、<textarea> 及 <select> 元素上創建雙向數據綁定。它會根據控件類型自動選取正確的方法來更新元素。儘管有些神奇,但 v-model 本質上不過是語法糖。它負責監聽用戶的輸入事件以更新數據,並對一些極端場景進行一些特殊處理。
v-model 會忽略所有表單元素的 value、checked、selected 特性的初始值而總是將 Vue 實例的數據作爲數據來源。你應該通過 JavaScript 在組件的 data 選項中聲明初始值。
也就是說:v-model和value同時存在時,v-model起作用
-
複選框
<input type="checkbox" v-model="checkedNames" value="1" id="1"> <label for="1">1</label> <input type="checkbox" v-model="checkedNames" value="2" id="2"> <label for="2">2</label> <input type="checkbox" v-model="checkedNames" value="3" id="3"> <label for="3">3</label> <span v-text="'checkedNames'+checkedNames"></span> checkedNames: []
可以實現添加標籤的效果
簡單點說:v-model和value,在選中時value會被添加到checkedNames這個數組中,取消時從數組中取下來
-
值綁定
對於單選按鈕,複選框及選擇框的選項,v-model 綁定的值通常是靜態字符串 (對於複選框也可以是布爾值):
<!-- 當選中時,`picked` 爲字符串 "a" --> <input type="radio" v-model="picked" value="a"> <!-- `toggle` 爲 true 或 false --> <input type="checkbox" v-model="toggle"> <!-- 當選中第一個選項時,`selected` 爲字符串 "abc" --> <select v-model="selected"> <option value="abc">ABC</option> </select>
-
修飾符
-
.lazy
<input type="text" v-model.lazy="checkedNames">
在輸入的時候checkedNames不會變,當鼠標焦點離開輸入框之後,checkedNames值會被改變
-
.trim
<input v-model.trim="msg">
如果要自動過濾用戶輸入的首尾空白字符,可以給 v-model 添加 trim 修飾符:
-
-