Vue.js中的methods,computed,watch。

寫這篇文章好像有點多餘了,可是我以爲仍是有多數新手搞不懂它們的區別。數組

那咱們從字面意思來看它們:bash

  • methods: 方法。組件或者實例聲明方法的地方。
  • computed: 計算。用來計算(監聽)屬性的變化。
  • watch 觀察。用來觀察(監聽)屬性的變化。

咱們下面分解學習它們。app


methods

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

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)
  }
}
複製代碼

watch

偵聽屬性。簡單的理解:當你監聽的屬性改變的時候你想 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。

immediate [ɪˈmiːdiət]

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。

deep [diːp]

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。會有一些相同之處,同一個效果用這三個都能實現。可是咱們在實際開發的時候仍是要讓它們各司其職,不要弄混了。

這篇文章較淺。若是你以爲有用,就點個贊~~~

相關文章
相關標籤/搜索