Vue之计算属性

一,计算属性

1.1什么是计算属性

计算属性需要定义在computed选项中。当计算属性以来的数据发生变化时,这个属性的值会自动更新,所有依赖该属性的数据绑定也会同步进行更新

在一个计算属性中可以实现各种复杂的罗伊,包括运算,函数调用等。示例代码如下

<div id="app">
        <p>原字符串:{{str}}</p>
        <p>新字符串:{{newstr}}</p>
    </div>
    <script>
        new Vue({
            el: '#app',
            data: {
                str: 'HTML*JavaScript*Vue.js'
            },
            computed: {
                newstr: function () {
                    return this.str.split('*').join('+');//对字符串进行分割并重新连接
                }
            },
            methods: {}
        })
    </script>

运行结果如图 

上述代码中定义了一个计算属性newstr, 并在模板中绑定了该计算属性。newstr 属性的值依赖于str属性的值。当str属性的值发生变化时,newstr 属性的值也会自动更新。

除了上述简单的用法,计算属性还可以依赖Vue实例中的多个数据,只要其中任一数据发生变化,计算属性就会随之变化,视图也会随之更新。
 

例:应用计算属性统计购物车中的上品总价,代码如下:

<!DOCTYPE html>
<html lang="en">
<script src="https://cdn.jsdelivr.net/npm/vue@2.7.14/dist/vue.js"></script>


<head>
    <meta charset="UTF-8">
    <title>统计商品总价</title>
    <style>
        body {
            font-family: 微软雅黑;
            font-size: 14px
        }

        .title {
            background: #f6f6f6;
            font-size: 18px;
        }

        .title,
        .content {
            width: 400px;
            height: 36px;
            line-height: 36px;
            border: 1px solid #dddddd;
        }

        .title:not(:first-child),
        .content {
            border-top: none;
        }

        .title div {
            width: 100px;
            text-align: center;
            float: left
        }

        .content {
            clear: both
        }

        .content div {
            width: 100px;
            text-align: center;
            float: left
        }

        p {
            width: 380px;
            text-align: right;
        }
    </style>
    <script src="../JS/vue.js"></script>
</head>

<body>
    <div id="example">
        <div class="title">
            <div>商品名称</div>
            <div>单价</div>
            <div>数量</div>
            <div>金额</div>
        </div>
        <div class="content" v-for="value in shop">
            <div>{{value.name}}</div>
            <div>{{value.price | twoDecimal}}</div>
            <div>{{value.count}}</div>
            <div>{{value.price*value.count | twoDecimal}}</div>
        </div>
        <p>合计:{{totalprice | formatPrice("¥")}}</p>
    </div>
    <script type="text/javascript">
        var exam = new Vue({
            el: '#example',
            data: {
                shop: [{//定义商品信息数组
                    name: 'OPPO R15',
                    price: 2999,
                    count: 3
                }, {
                    name: '华为P20',
                    price: 3699,
                    count: 2
                }]
            },
            computed: {
                totalprice: function () {
                    var total = 0;
                    this.shop.forEach(function (s) {
                        total += s.price * s.count;//计算商品总价
                    });
                    return total;
                }
            },
            filters: {
                twoDecimal: function (value) {
                    return value.toFixed(2);//保留两位小数
                },
                formatPrice: function (value, symbol) {
                    return symbol + value.toFixed(2);//添加人民币符号并保留两位小数
                }
            }
        })
    </script>
</body>

</html>

运行结果如图所示: 

1.2getter和setter 

每一个计算属性都包括一个getter和一个setter。当没有指明方法时,默认使用getter来读取数据。示例代码如下:

<div id="app">
        <p>姓名:{{fullname}}</p>
    </div>
    <script>
        new Vue({
            el: '#app',
            data: {
                surname: '韦',
                name: '小宝'
            },
            computed: {
                fullname: function () {
                    return this.surname + this.name;//连接字符串
                }
            }
            ,
            methods: {}
        })
    </script>

运行结果如下:

 上述代码中定义了一个计算属性sum,为该属性提供的函数将默认作为sum属性的getter,因此,上述代码也可以写成如下代码:

<div id="app">
        <p>姓名:{{fullname}}</p>
    </div>
    <script>
        new Vue({
            el: '#app',
            data: {
                surname: '韦',
                name: '小宝'
            },
            computed: {
                fullname: {
                    //getter
                    get: function () {
                        return this.surname + this.name;//连接字符串
                    }
                }
            }
            ,
            methods: {}
        })
    </script>

 除了getter,还可以设置计算属性的setter。getter用来执行读取值的操作,而setter用来执行设置值的操作。当手动更新计算属性的值时,就会触发setter,执行一些自定义的操作。示例代码如下:

<div id="app">
        <p>姓名:{{fullname}}</p>
    </div>
    <script>
        var exam = new Vue({
            el: '#app',
            data: {
                surname: '韦',
                name: '小宝'
            },
            computed: {
                fullname: {
                    //getter
                    get: function () {
                        return this.surname + this.name;//连接字符串
                    },
                    // setter
                    set: function (value) {
                        this.surname = value.substr(0, 1);
                        this.name = value.substr(1)
                    }
                }
            }
            ,

        })
        exam.fullname = '张无忌'
    </script>

运行结果如图:

 上述代码中定义了一个计算属性fullname, 在为其重新赋值时,Vue.js会自动调用setter,并将新值作为参数传递给set()方法,surname属性和name属性会相应进行更新,模板中绑定的fullname属性的值也会随之更新。如果在未设置setter的情况下为计算属性重新赋值,是不会触发模板更新的。

1.3计算属性缓存 

通过上面的示例可以发现,除了使用计算属性外,在表达式中调用方法也可以实现同样的效果。使用方法实现同样效果的示例代码如下:

<div id="app">
        <p>姓名:{{fullname()}}</p>
    </div>
    <script>
        var exam = new Vue({
            el: '#app',
            data: {
                surname: '韦',
                name: '小宝'
            },
            methods: {
                fullname: function () {
                    return this.surname + this.name
                }
            }

        })

    </script>

将相同的操作定义为一个方法, 或者定义为一个计算属性,两种方式的结果完全相同。然而,不同的是计算属性是基于它们的依赖进行缓存的。使用计算属性时,每次获取的值是基于依赖的缓存值。当页面重新渲染时,如果依赖的数据未发生改变,使用计算属性获取的值就一直是缓存值。只有依赖的数据发生改变时才会重新执行getter。

下面通过一个示例来说明计算属性的缓存。代码如下:

<div id="app">
        <input v-model="message">
        <p>{{message}}</p>
        <p>{{getTimeC}}</p>
        <p>{{getTimeM()}}</p>
    </div>
    <script>
        var vm = new Vue({
            el: '#app',
            data: {
                message: '',
                time: '当前时间:'
            },
            computed: {
                getTimeC: function () {
                    var hour = new Date().getHours();
                    var minute = new Date().getMinutes();
                    var second = new Date().getSeconds();
                    return this.time + hour + ':' + minute + ':' + second;

                }
            },
            methods: {
                getTimeM: function () {
                    var hour = new Date().getHours();
                    var minute = new Date().getMinutes();
                    var second = new Date().getSeconds();
                    return this.time + hour + ':' + minute + ':' + second;
                }
            }

        })

    </script>

        运行上述代码,在页面中会输出一个文本框,以及分别通过计算属性和方法获取的当前时间,结果如图1所示。在文本框中输入内容后,页面进行了重新谊染,这时,通过计算属性获取的当前时间是缓存的时间,而通过方法获取的当前时间是最新的时间。结果如图2所示。
        在该示例中,getTimeC 计算属性依赖于time属性。当页面重新谊染时,只要time属性未发生改变,多次访问getTimeC计算属性会立即返回之前的计算结果,而不会再次执行函数,因此会输出缓存的时间。相比之下,每当触发页面重新谊染时,调用getTimeM()方法总是会再次执行函数,因此会输出最新的时间。

图一:

  图二:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值