[vue]5-计算属性/watch监听

计算属性

​ 前面的笔记提到了计算属性,这里单独讲一下计算属性

我们知道,在模板中可以直接通过插值语法显示一些data中的数据

但是在某些情况,我们可能需要对数据进行一些转化后再显示,或者需要将多个数据结合起来进行显示

  • 比如我们有firstName和lastName两个变量,我们需要显示完整的名称。
  • 但是如果多个地方都需要显示完整的名称,我们就需要写多个{{firstName}} {{lastName}}
    <div id="app">
        <h2>{{name}}:{{currentName}}</h2>
    </div>
    <script>
        let app = new Vue({
            el: '#app',
            data: {
                name: '姓名',
                currentName: 'Vue'
            }
        })
    </script>

这个场景下,计算属性就可以派上用上了,上面的代码可以这样写

    <div id="app">
        //这里的showName就是computed里面的showName
        <h2>{{showName}}</h2>
    </div>
    <script>
        let app = new Vue({
            el: '#app',
            data: {
                name: '姓名',
                currentName: 'Vue'
            },
            computed: {
                //这里的函数名类似于data里面的键名,return出来的类似于data里面的键值。
                showName: function () {
                    return this.name + ':' + this.currentName
                }
            }
        })
    </script>

上面的操作是计算属性最简单的操作,接下来继续看

  • 每个计算属性都包含一个getter和一个setter

  • 在上面的例子中,我们只是使用getter来读取。

  • 在某些情况下,你也可以提供一个setter方法(不常用)。

下面分别演示这两种情况

    <div id="app">
        <h2>书籍总价为:{{allPrice}}</h2>
    </div>
    <script>
        let app = new Vue({
            el: '#app',
            data: {
                bookList: [
                    { name: 'java编程思想', price: 99, count: 3 },
                    { name: 'unix编程艺术', price: 112, count: 2 },
                    { name: 'vueJs程序设计', price: 89, count: 4 },
                ],
                count: 0
            },
            computed: {
                // 这个名字为计算属性名,如果获取,就执行get函数,如果设置就执行set函数
                allPrice: {
                    get() {
                        let money = this.bookList.reduce((item, curItem) => {
                            item += curItem.price * curItem.count
                            return item
                        }, 0)
                        return money
                    },
                    set(newValue) {
                        console.log('触发我了', newValue)
                        let num1 = newValue / 2
                        this.count = num1
                    }
                }
            }
        })
    </script>

在这里插入图片描述

计算属性的缓存

    <div id="app">
        <h2>姓名:{{allName1}}</h2>
        <h2>姓名:{{allName1}}</h2>
        <h2>姓名:{{allName1}}</h2>
        <h2>姓名:{{allName2()}}</h2>
        <h2>姓名:{{allName2()}}</h2>
        <h2>姓名:{{allName2()}}</h2>
    </div>
    <script>
        let app = new Vue({
            el: '#app',
            data: {
                name1: '李明',
                name2: '韩梅梅',
            },
            computed: {
                allName1() {
                    console.log('执行了computed属性')
                    return this.name1 + '和' + this.name2
                }
            },
            methods: {
                allName2() {
                    console.log('执行了methods属性')
                    return this.name1 + '和' + this.name2
                }
            }
        })
    </script>

上面执行了多个计算属性,也执行了多个methods属性,可以看一下打印

在这里插入图片描述

可以到计算属性只执行了一个打印,这是因为计算属性具有缓存行

相关属性发生改变,计算属性会重新执行,无关属性发生改变,计算属性不会重新执行。

methods方法和计算属性其实是互补的,有的场景下,我们希望缓存数据,有的我们不需要,就可以分别来使用了两个属性了。

watch监听

watch基础用法

    <div id="app">
        <h2>{{value}}</h2>
    </div>
    <script>
        let app = new Vue({
            el: '#app',
            data: {
                value: '初始值'
            },
            watch: {
                //接收两个参数,第一个参数是修改后的值,第二个参数是修改前的值
                value(newValue, oldValue) {
                   console.log('value值改变了', newValue, oldValue)
               }
            }
        })
    </script>

watch的handler和immediate

    <div id="app">
        <h2>{{value}}</h2>
    </div>
    <script>
        let app = new Vue({
            el: '#app',
            data: {
                value: '初始值'
            },
            watch: {
                value: {
                    // 接收两个参数,第一个是新的值,第二个是老的值
                    //监听的数据后面写成对象形式,包含handler方法和immediate,之前我们写的函数其实就是在写这个handler方法;
                    handler(newValue, oldValue) {
                        console.log(newValue, oldValue)
                    },
                    // 第一次就开始监听,也就是value是'初始值'的时候就开始执行这个value函数。
                    immediate: true
                }
            }
        })
    </script>

在这里插入图片描述

另外,官网有说

注意,不应该使用箭头函数来定义 watcher 函数

例如 searchQuery: newValue => this.updateAutocomplete(newValue)

理由是箭头函数绑定了父级作用域的上下文

所以 this 将不会按照期望指向 Vue 实例,this.updateAutocomplete 将是 undefined。

当需要监听一个对象的改变时,普通的watch方法无法监听到对象内部属性的改变,只有data中的数据才能够监听到变化,此时就需要deep属性对对象进行深度监听。

首先看一下如果不加deep

    <div id="app">
        <h2>{{obj.name}}</h2>
    </div>
    <script>
        let app = new Vue({
            el: '#app',
            data: {
                obj: {
                    name: '李雷雷',
                    age: 18
                }
            },
            watch: {
                obj(newValue, oldValue) {
                    console.log('监听的是对象', newValue, oldValue)
                }
            }
        })
    </script>

在这里插入图片描述

可以看到并没有产生监听

    <div id="app">
        <h2>{{obj.name}}</h2>
    </div>
    <script>
        let app = new Vue({
            el: '#app',
            data: {
                obj: {
                    name: '李雷雷',
                    age: 18
                }
            },
            watch: {
                obj: {
                    handler(newValue, oldValue) {
                        console.log('监听的是对象', newValue, oldValue)
                    },
                    deep: true
                }
            }
        })
    </script>

在这里插入图片描述

可以看到,如果这样做就可以执行监听的属性了,但是oldValue拿不到修改前的值了。

当然也可以这样

    <div id="app">
        <h2>{{obj.name}}</h2>
    </div>
    <script>
        let app = new Vue({
            el: '#app',
            data: {
                obj: {
                    name: '李雷雷',
                    age: 18
                }
            },
            watch: {
                'obj.name': {
                    handler(newValue, oldValue) {
                        console.log('监听的是对象', newValue, oldValue)
                    },
                    deep: true
                }
            }
        })
    </script>

在这里插入图片描述

就可以拿到前后的值了

注意: 数组(一维、多维)的变化不需要通过深度监听,对象数组中对象的属性变化则需要deep深度监听。

当然,监听不仅可以监听到data里面的值,还可以监听到vuex里面值得变化,在开发中有通过网络请求下来的数据存到到vuex中,使用watch监听vuex中的数据,并获取到数据,然后渲染到界面上,这种情况在有的开发中有使用,当然也有其他的一些方式。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值