← 返回首页
Vue基础教程(十三)
发表时间:2020-04-14 12:40:33
讲解Vue的计算属性和监听器

1.计算属性

计算属性(computed),可以直接拿来当做属性使用,不需要进行显示调用即可返回参与计算后的属性值。

例如:

使用计算属性。

<div id="example">
  <p>{{ now }}</p>
</div>

<script>
var vm = new Vue({
  el: '#example',
  data: {
    message: 'Hello'
  },
  computed: {
    now: function () {
      return Date.now()
    }
  }
})
</script>

使用方法。

<div id="example">
  <p>{{ now() }}</p>
</div>

<script>
var vm = new Vue({
  el: '#example',
  methods: {
    now: function () {
      return Date.now()
    }
  }
})
</script>

计算属性与方法的对比:

在控制分别执行以下代码观察,计算属性将总会返回相同值,而方法则不会。

vm.now
vm.now()

实例: 使用计算属性实现统计购物车总金额功能。

<!DOCTYPE html>
<html lang="zh">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document Title</title>
    <style>
        #app {
            width: 580px;
            margin: 0px auto;
        }

        table {
            width: 560px;
            border: 1px solid #ccc;
            border-collapse: collapse;
        }

        td {
            text-align: center;
        }

        input {
            width: 20px;
        }

        .numSpan {
            cursor: pointer;
        }
    </style>
</head>

<body>
<div id="app">
    <table>
        <tr>
            <th>编号</th>
            <th>名称</th>
            <th>单价</th>
            <th>数量</th>
        </tr>
        <tr v-for="(item,index) in itemsList" :key="index">
            <td>{{item.id}}</td>
            <td>{{item.name}}</td>
            <td>{{item.price}}</td>
            <td><span class="numSpan" @click="sub(index)">-</span>
                <input type="text" name="number" v-model="item.num"/>
                <span class="numSpan" @click="add(index)">+</span>
            </td>
        </tr>
        <tr>
            <td colspan="4">总金额:{{totalPrice}} 元</td>
        </tr>
    </table>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
    new Vue({
        el: '#app',
        data: {
            itemsList: [
                {id: '001', name: '康师傅红烧牛肉面', price: 4, num: 10},
                {id: '002', name: '农夫山泉', price: 2, num: 5},
                {id: '003', name: '清风卫生纸', price: 10, num: 2},
                {id: '004', name: '洽洽瓜子', price: 12, num: 3}
            ]
        },
        computed: {
            //总价格计算属性
            totalPrice: function () {
                let total = 0;
                for (let i of this.itemsList) {
                    total += i.price * i.num;
                }
                return total;
            }
        },
        methods: {
            sub(index) {
                if (this.itemsList[index].num > 1) {
                    this.itemsList[index].num--;
                }
            },
            add(index) {
                if (this.itemsList[index].num < 100) {
                    this.itemsList[index].num++;
                }
            }
        }
    })
</script>
</body>
</html>

运行效果:

2.监听器 watch监听器的用法相当于是我们监视一个数据的变化,在这个数据变化时执行一些操作,这个操作可以是任何操作。

监听者里面有三个参数: 1)handler :function(newVal,oldVal){} 操作者 代表这个数据改变的时候执行什么操作 有两个参数 newVal (改变后的数据)oldVal(改变前的数据) 2)deep:false,如果监听的是一个引用类型的数据(对象/数组),需要深度监听,true是深度监听,false是浅监听,默认是false 3)immediate:true, 实例创建的时候是否执行watch 为true时代表 监听的数据第一次被绑定的时候就开始监听。

实例:

<!DOCTYPE html>
<html lang="zh-cmn-Hans">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document Title</title>
</head>

<body>
<div id="app">
    <input type="text" v-model="content">
    <div>{{showcontent}}</div>
    <button @click="obj.name='小红'">改变name属性</button>
    <button @click="changeCar">改变car属性</button>
</div>
<script src="https://cdn.bootcdn.net/ajax/libs/vue/2.6.13/vue.min.js"></script>
<script>
    let vm = new Vue({
        el: '#app',
        data: {
            content: "",
            obj: {
                age: 12,
                name: "小明",
                car: {
                    brand: 'BMW',
                    price: 20000
                }
            },
            num: 0
        },
        computed: {
            showcontent: function () {
                return "输入的内容是" + this.content;
            }
        },
        watch: { //监听input框的变化情况
            //在input框每次输入内容的时候,这一行在后台都会打印值:改变后的数据---改变前的数据
            'content': { //定义在watch里的conten代表监控数据content
                handler: function (newVal, oldVal) { //操作者
                    console.log(newVal, "---", oldVal)
                },
            },
            //监听对象中name属性
            'obj.name': {
                //刚刚进入页面时 数据没有改变,默认undefined,后台打印 小明 # undefined
                //当点击改变数据的时候,后台打印  小红 # 小明
                handler: function (newVal, oldVal) {
                    console.log(newVal, '#', oldVal)
                },
                deep: false, //深度监听,可以监听这个对象的某个属性比如说监听 'obj.name'
                immediate: true, //监听的数据第一次被绑定的时候就开始监听
            },

            'obj.car': {
                handler: function (newVal, oldVal) {
                    console.log("旧品牌:" + oldVal.brand)
                    console.log("新品牌:" + newVal.brand)
                },
                deep: true, //深度监听,可以监听这个对象的某个属性比如说监听 'obj.name'
                immediate: false, //监听的数据第一次被绑定的时候就开始监听
            }
        },
        methods: {
            changeCar() {
                this.obj.car.brand = 'TOYOTA';
                /*
                this.obj.car = {
                    brand: 'TOYOTA',
                    price: 12000
                }*/
            }
        }
    })
</script>
</body>
</html>

运行效果: