1. 程式人生 > >Vue 方法與計算屬性

Vue 方法與計算屬性

Vue2 方法與計算屬性

上一篇文章中總結了Vue中的建構函式,生命週期鉤子函式和資料的雙向繫結,本篇文章接著上一篇,總結Vue中的methods與computed。

(1)Vue例項中的方法——methods

瞭解Vue例項中的methods選項,就要先了解一下v-on指令。
指令是Vue.js模板中常用的一項功能,它們帶有v-字首,在前一篇文章中我們使用了v-html和v-pre,具體的關於指令的內容將會在接下來的文章中總結。在這之前,先來了解一下v-on指令,它主要用來繫結事件監聽器,下面是一個示例:

<div id="app">
    <
div
>
{{a}}</div> <div v-on:click="a='hello!'">點選這裡可以改變上面的文字</div> </div> <script> var app = new Vue({ el: "#app", data:{ a:"你好!" } }); </script>

v-on可以監聽原生的DOM事件,如click、dbclick、keyup、mouseover等。v-on:click=後面的表示式可以是內聯語句,如上面程式碼所示,點選之後改變了a的值。

表示式還可以是一個方法名,這個方法可以是一個函式,定義在Vue例項的methods選項中。函式中的this指向的是Vue例項,所以下面程式碼中this.a可以得到data中a的值。

<div id="app">
    <div v-on:click="alert">點選將會彈出提示框!</div>
</div>
<script>
    var app = new Vue({
        el: "#app",
        data:{
            a:"你好!"
        },
        methods:
{ alert:function(){ alert(this.a); } } });
</script>
在函式中通過this呼叫另一個函式

函式中的this指向的是Vue例項,可以通過this在函式中呼叫另一個函式:

<div id="app">
    <div v-on:click="click">點選將會彈出提示框!</div>
</div>
<script>
    var app = new Vue({
        el: "#app",
        data:{
            a:"你好!"
        },
        methods:{
            click:function(){
                this.alert();
            },
            alert:function(){
                alert(this.a);
            }
        }
    });
</script>
也可以在生命週期鉤子函式中、Vue例項外呼叫methods中的方法
   var app = new Vue({
        el: "#app",
        data: {
            a: "你好!"
        },
        methods: {
            init: function () {
                console.log(this.a);
            }
        },
        mounted: function () {
            this.init();
            //你好!
        }
    });
    app.init();
    //你好!
v-on的語法糖

語法糖指的是在不影響功能的前提下,新增某種方法,更加方便程式設計師使用,增加可讀性、減少出錯率等。
v-on中提供了語法糖,也就是縮寫:

  <div v-on:click="click">點選將會彈出提示框!</div>
  <div @click="click">點選將會彈出提示框!</div>

上面兩個的寫法是等價的,也就是說可以省略v-on:而用@代替。

(2)Vue例項中的計算屬性——computed

模版內的表示式非常便利,但是它們適用於簡單計算。不便在雙大括號內放過多的邏輯。
對於一些複雜邏輯,應該使用計算屬性:

<div id="app">
    <div>{{message}}</div>
    <div>如果right的值為true,message會增加10,否則會增加100</div>
    <div>{{judge}}</div>
</div>
<script>
    var app = new Vue({
        el: "#app",
        data: {
            message: 1,
            right: true
        },
        computed: {
            judge: function () {
                if (this.right) {
                   return this.message + 10;
                }
                else {
                    return this.message + 100;
                }
            }
        }
    })
</script>

在一個計算屬性裡,可以完成各種複雜的邏輯,包括運算、函式呼叫等,最終返回一個結果。計算屬性可以依賴多個Vue例項的資料,只要其中任何一個數據變化,計算屬性就會重新執行,檢視也會更新,例如:

<div id="app">
    <div>{{total}}</div>
    <div v-on:click="add1">點選這裡將data1增加1:{{data1}}</div>
    <div v-on:click="add2">點選這裡將data1增加1:{{data2}}</div>
</div>
<script>
    var app = new Vue({
        el: "#app",
        data: {
            data1: 1,
            data2: 2
        },
        methods: {
            add1: function () {
                this.data1++;
            },
            add2: function () {
                this.data2++;
            },
        },
        computed: {
            total: function () {
                return this.data1 + this.data2
            }
        }
    });
</script>

上面程式碼也使用v-on綁定了方法。因為計算屬性total依賴data1和data2,所以當通過點選將data1或者data2增加時,計算屬性會重新執行,檢視也會更新。

1.計算屬性的getter與setter

每個計算屬性都包含一個getter和setter,上面的兩個示例都是計算屬性的預設用法,只是利用了getter屬性。計算屬性預設只有 getter ,不過在需要時可以提供一個 setter,來修改計算屬性的值。
下面程式碼就是預設用法,只有getter,在這種情況下不能改變計算屬性的值,會報錯:

<div id="app">
    <div>{{total}}</div>
</div>
<script>
    var app = new Vue({
        el: "#app",
        data: {
            first: "a",
            last: "b"
        },
        computed: {
            total: function () {
                return this.first +" "+ this.last
            }
        }
    });
</script>

在這裡插入圖片描述
接下來為計算屬性加上setter,改變total的寫法,寫成物件的形式

<div id="app">
    <div>{{total}}</div>
</div>
<script>
    var app = new Vue({
        el: "#app",
        data: {
            first: "a",
            last: "b"
        },
        computed: {
            total: {
                get:function(){
                    return this.first +" "+ this.last
                },
                set:function(value){
                    var names=value.split(" ");
                    this.first=names[0];
                    this.last=names[1];
                }
            }
        }
    });
</script>

在這裡插入圖片描述
為計算屬性加上setter之後就可以改變計算屬性的值了。當執行app.total="c d"的時候,setter就被呼叫,資料first和last也會相應更新,檢視也會更新。
一般情況下,很少用到setter屬性,一般可以直接採用預設寫法。

2.計算屬性還可以依賴其他計算屬性
<div id="app">
    <div>{{add}}</div>
</div>
<script>
    var app = new Vue({
        el: "#app",
        data: {
            first: 1,
            last: 2
        },
        computed: {
            total: function(){
                    return this.first + this.last
            },
            add:function(){
                let a=this.total;
                return a+1;
            }
        }
    });
</script>
3.計算屬性還可以依賴其他例項的資料
<div id="app"></div>
<div id="app1">
    <div>{{total}}</div>
</div>
<script>
    var app=new Vue({
        el: "#app",
        data: {
            first: 1,
            last: 2
        },
    });
    var app1 = new Vue({
        el: "#app1",
        data: {
            first1: 3,
            last1: 3
        },
        computed: {
            total: function(){
                    return this.first1 + this.last1+app.first+app.last;
            },
        }
    });
</script>
4.方法與計算屬性在快取上的不同

注意到,我們將同一個函式定義為方法而不是計算屬性也可以達到相同的效果:

<div id="app">
    <div>{{message}}</div>
    <div>如果right的值為true,message會增加10,否則會增加100</div>
    <div>{{judge()}}</div>
</div>
<script>
    var app = new Vue({
        el: "#app",
        data: {
            message: 1,
            right: true
        },
        methods: {
            judge: function () {
                if (this.right) {
                   return this.message + 10;
                }
                else {
                    return this.message + 100;
                }
            }
        }
    })
</script>

然而,將函式定義為方法或者定義為計算屬性,兩者是不同的:
計算屬性是基於它們的依賴進行快取的,只在相關依賴發生改變時,它們才會重新求值,也就是說,對於上面的計算屬性中的函式,只要message沒有發生改變,多次訪問judge就會返回之前的計算結果,而不會再次執行函式。
方法則不是這樣,方法中的函式不會有快取。每次呼叫方法中的函式,都會重新計算。

參考:《Vue.js實戰》