当我们需要对原数据(data)进行一些额外的操纵,希望在原数据的基础之上得到一些新数据,但同时又不希望改变原数据,这种情况下,我们会选择用计算属性。
首先,先用一段代码演示:
- <!DOCTYPE html>
- <html lang="en">
- <head>
- <meta charset="UTF-8">
- <meta http-equiv="X-UA-Compatible" content="IE=edge">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <title>计算属性</title>
- </head>
- <body>
- <div id="app">
- <p>{{cnum}}</p>
- <p>{{mnum()}}</p>
- <p>{{cnum}}</p>
- <p>{{mnum()}}</p>
- <p>{{cnum}}</p>
- <p>{{mnum()}}</p>
- </div>
- </body>
- <script src="js/vue.min.js"></script>
- <script>
- new Vue({
- el:'#app',
- data(){
- return {
- x:10,
- y:20
- }
- },
- // 计算属性
- computed: {
- cnum(){
- console.log('computed');
- return this.x+this.y*this.x-this.y;
- }
- },
- methods:{
- mnum(){
- console.log('methods');
- return this.x+this.y*this.x-this.y;
- }
- }
- })
- </script>
- </html>
运行结果:

从以上结果可以看出,计算属性的结果在第一次计算完成后会缓存下来,在后续的使用,只要原数据没有发生变化,计算属性就不会再重新计算。每一次的使用都是读取缓存中的结果。
一旦计算属性中依赖的原数据发生变化,计算属性就会重新计算,也就是说,计算属性所对应的方法会重新调用。
- <!DOCTYPE html>
- <html lang="en">
-
- <head>
- <meta charset="UTF-8">
- <meta http-equiv="X-UA-Compatible" content="IE=edge">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <title>购物车</title>
- <style>
- table {
- border-collapse: collapse;
- }
-
- th,
- td {
- width: 100px;
- height: 50px;
- text-align: center;
- }
- </style>
- </head>
-
- <body>
- <div id="app">
- <table>
- <thead>
- <tr>
- <th>商品编号</th>
- <th>商品名称</th>
- <th>商品单价</th>
- <th>商品数量</th>
- <th>商品总价</th>
- <th>商品操作</th>
- </tr>
- </thead>
- <tbody>
- <tr v-if="goodsData.every(item => item.count===0)">
- <td>购物车为空</td>
- </tr>
- <template v-for="(item,index) in filterGoodsData">
- <tr :key="item.id">
- <td>{{item.id}}</td>
- <td>{{item.name}}</td>
- <td>{{item.price}}</td>
- <td>
- <button @click="item.count--">-</button>
- <span>{{item.count}}</span>
- <button @click="item.count++">+</button>
- </td>
- <td>{{item.count*item.price}}</td>
- <td>
- <button @click="goodsData.splice(index,1)">删除</button>
- </td>
- </tr>
- </template>
- </tbody>
- </table>
- <p>合计:{{totalPrice}}</p>
- </div>
- </body>
- <script src="js/vue.min.js"></script>
- <script>
- new Vue({
- el: '#app',
- data() {
- return {
- goodsData: [
- { id: 1, name: '苹果', price: 20, count: 1 },
- { id: 2, name: '香蕉', price: 10, count: 2 },
- { id: 3, name: '橘子', price: 15, count: 4 }
- ]
- }
- },
- computed:{
- totalPrice(){
- return this.goodsData.reduce((sum,item)=>{
- return sum+item.price*item.count;
- },0)
- },
- filterGoodsData(){
- return this.goodsData.filter(item=>item.count>0);
- }
- }
-
- })
- </script>
-
- </html>
将数量不为0的商品放到新数组中,原数组不变。
实例:点击按钮改变值
- <!DOCTYPE html>
- <html lang="en">
-
- <head>
- <meta charset="UTF-8">
- <meta http-equiv="X-UA-Compatible" content="IE=edge">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <title>计算属性</title>
- </head>
-
- <body>
- <div id="app">
- <p>{{cnum}}</p>
- <button @click="cnum = 'Li Si'">修改</button>
- </div>
- </body>
- <script src="js/vue.min.js"></script>
- <script>
- new Vue({
- el: '#app',
- data() {
- return {
- xing:'Zhang',
- ming:'Ling'
- }
- },
- // 计算属性
- computed: {
- cnum: {
- get() {
- return this.xing +' '+ this.ming;
- },
- set(val) {
- this.xing = val.split(' ')[0];
- this.ming = val.split(' ')[1];
- }
- }
- },
- })
- </script>
-
- </html>
点击前: 点击后:
