寫這篇文章好像有點多餘了,可是我以爲仍是有多數新手搞不懂它們的區別。數組
那咱們從字面意思來看它們:bash
咱們下面分解學習它們。app
在
methods
裏聲明的方法,都能在當前組件或者實例中使用。經過this.xx
調用。函數
例子:學習
<div id="app">
<div>{{count}}</div>
<button @click="add">點擊+1</button>
</div>
var app = new Vue({
el: '#app', //掛載到#app上
data(){
return {
count:0
}
},
methods:{
add(){
this.count+=1;
}
},
})
複製代碼
<button @click="add">點擊+1</button>
中的@click
就是v-on:click
的縮寫,用來監聽DOM的click
事件。ui
固然咱們還能夠這樣寫:this
<div id="app">
<div>{{count}}</div>
<button @click="count+1">點擊+1</button>
</div>
複製代碼
但不推薦這樣寫,若是邏輯稍微多一些這樣是不可行的,仍是要在methods定義一個方法。固然v-on
不但能夠接收一個方法名稱,還能夠傳參數:spa
<div id="app">
<div>{{count}}</div>
<button @click="add(100)">點擊+1</button>
</div>
var app = new Vue({
el: '#app', //掛載到#app上
data(){
return {
count:0
}
},
methods:{
add(num){
this.count = num;
}
},
})
複製代碼
在
computed
裏的屬性,都不用在data
裏定義,也能夠經過this.xx
訪問到,若是在data
裏定義會報錯The computed property "doubleCount" is already defined in data.
code
例子:咱們計算2倍的count。 兩種方式:對象
1.
<div id="app">
<div>{{count}}</div>
<div>2倍的{{count*2}}</div>
<button @click="add">點擊+1</button>
</div>
var app = new Vue({
el: '#app',
data(){
return {
count:0,
}
},
methods:{
add(){
this.count +=1;
}
},
})
複製代碼
2.
<div id="app">
<div>{{count}}</div>
<div>2倍的{{doubleCount}}</div>
<button @click="add">點擊+1</button>
</div>
var app = new Vue({
el: '#app',
data(){
return {
count:0,
}
},
methods:{
add(){
this.count +=1;
}
},
computed:{
doubleCount(){
return this.count*2;
}
}
})
複製代碼
咱們知道{{}} 裏面是能夠寫表達式的。可是當邏輯複雜一些,咱們就須要用到 computed
。
這裏咱們聲明瞭一個計算屬性 doubleCount
。函數裏面return
的值 就是該計算屬性的依賴項,也就是說doubleCount
的值是根據return
後面的值的變化而變化的。可是這是有條件的:依賴項必須是響應式的,不然doubleCount
的值是不會隨着依賴項的改變而改變的。
咱們看官網的例子:
<div id="app">
<div>當前時間{{now}}</div>
</div>
computed: {
now: function () {
return Date.now()
}
}
複製代碼
如今計算屬性now
的依賴項是Date.now()
,很顯然Date.now()
是一直改變的,但它並非響應式的數據。因此now
不會隨着Date now()
的值的改變而改變。所以now
的值是一開始就肯定了。
工做中經常使用的例子:
咱們知道Vue 是不建議 v-for & v-if
一塊兒使用的
items:[
{
name:'aa',
status:false
},
{
name:'bb',
status:true
},
{
name:'cc',
status:true
}
]
複製代碼
如今咱們須要循環 items
可是咱們只須要顯示status == true
的數據,通常咱們會這麼作。
<ul>
<li v-for="(item,index) in items" v-if="item.status" :key='index'>{{item.name}}</li>
</ul>
複製代碼
能夠說是很簡單了,可是上面提到了 不建議 v-for & v-if
一塊兒使用。這個時候咱們就用到了咱們的computed
。
<ul>
<li v-for="(item,index) in showItems" v-if="item.status" :key='index'>{{item.name}}</li>
</ul>
computed: {
// 定義一個計算屬性 showItems 返回一個 items過濾後的數組。
showItems: function () {
return this.items.filter(v => v.status)
}
}
複製代碼
偵聽屬性。簡單的理解:當你監聽的屬性改變的時候你想
do something
。這個時候的監聽的屬性就須要在data裏面定義或者是computed定義的屬性。
用法:監聽this.count
的改變,當this.count
改變的時候,會觸發watch
裏面的count
方法
<div id="app">
<div>{{count}}</div>
<button @click="add">點擊+1</button>
</div>
var app = new Vue({
el: '#app',
data(){
return {
count:1,
}
},
methods:{
add(num){
this.count ++;
}
},
watch:{
count(newVal,oldVal){
console.log(newVal); //改變以後的值
console.log(oldVal);//改變以前的值
}
}
})
複製代碼
那咱們還拿上面的例子:計算2倍的count。
<div id="app">
<div>{{count}}</div>
<div>{{doubleCount}}</div>
<button @click="add">點擊+1</button>
</div>
var app = new Vue({
el: '#app',
data(){
return {
count:1,
doubleCount:0
}
},
methods:{
add(num){
this.count ++;
}
},
watch:{
count(newVal,oldVal){
this.doubleCount = newVal*2;
}
}
})
複製代碼
當count
改變的時候咱們改變 this.doubleCount
的值。這裏跟computed
能實現一樣的效果。可是watch監聽的屬性,只有在屬性值改變的時候纔會觸發屬性對應的方法。也就是當this.count
改變的時候纔會觸發watch
裏面的count
方法。這個時候this.doubleCount
初始值就仍是 0。並非 2。
watch裏面的參數。上面說了 watch裏面的count
對應的方法,只有在this.count
改變的時候纔會觸發。這個時候immediate: true
就可讓他默認觸發。要使用immediate
就要改變watch
裏面的數據解構。
watch:{
count:{
handler(newVal,oldVal) {
this.doubleCount = newVal*2
},
immediate: true
}
}
複製代碼
這個時候只要watch監聽了count
。默認就會執行對應的 handler方法。這個時候this.doubleCount
就爲2。
watch裏面的參數。咱們都知道對象 {}
都指向一個內存地址。當其屬性改變的時候,對象的內存地址沒發生改變。故當watch監聽一個對象的時候,對象屬性發生改變,watch監聽不到。
例子:
<div id="app">
<div>{{count}}</div>
<div>{{doubleCount}}</div>
<button @click="add">點擊+1</button>
</div>
var app = new Vue({
el: '#app',
data(){
return {
obj:{
count:1,
},
doubleCount:0
}
},
methods:{
add(num){
this.obj.count ++;
}
},
watch:{
obj(newVal,oldVal){
this.doubleCount = newVal.count*2;
}
}
})
複製代碼
當改變obj.count
的時候並不會觸發watch裏對應的obj方法。這個時候就用到了deep
。
爲了發現對象內部值的變化,能夠在選項參數中指定 deep: true 。注意監聽數組的變更不須要這麼作。
<div id="app">
<div>{{count}}</div>
<div>{{doubleCount}}</div>
<button @click="add">點擊+1</button>
</div>
var app = new Vue({
el: '#app',
data(){
return {
obj:{
count:1,
},
doubleCount:0
}
},
methods:{
add(num){
this.obj.count ++;
}
},
watch:{
obj:{
handler(newVal,oldVal) {
console.log(newVal +'--'+ oldVal )
this.doubleCount = newVal.count*2;
},
immediate: true,//默認觸發 handler 方法
deep:true
}
}
})
複製代碼
這樣就完成了對一個對象的監聽。
咱們會發現 methods,computed,watch。會有一些相同之處,同一個效果用這三個都能實現。可是咱們在實際開發的時候仍是要讓它們各司其職,不要弄混了。