您当前的位置:首页 > 计算机 > 编程开发 > JavaScript

计算属性和监听器

时间:12-11来源:作者:点击数:

1 计算属性 computed

  • computed 选项定义计算属性
  • 计算属性 类似于 methods 选项中定义的函数
计算属性 会将数据进行缓存,只在相关响应式依赖数据发生改变时它们才会重新求值。而函数 每次都会执行函数体进行计算。

下面来看一个小demo,分析计算属性和方法函数的区别

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>

<div id="app">
    姓:<input type="text" v-model="firstName"><br>
    名:<input type="text" v-model="lastName"><br>
    姓名1(方法):<input type="text" v-model="fullNameByMethods()"><br>
    姓名2(计算属性单向):<input type="text" v-model="fullNameByComputed"><br>
</div>

<script src="../js/vue.js"></script>

<script>
    const vm = new Vue({
        el: '#app',
        data: {
            firstName: 'A',
            lastName: 'B',
        },
        methods: {
            //methods 什么时候执行: 页面初始化/相关的数据发生改变
            fullNameByMethods: function () {
                console.log('方法的fullNameByMethods方法被调用了...')
                return this.firstName + this.lastName
            }
        },
        computed: {
            //computed 什么时候执行: 页面初始化/相关的数据发生改变
            fullNameByComputed: function () {
                console.log('计算属性的fullNameByComputed方法被调用了...')
                return this.firstName + this.lastName
            }
        }
    })
</script>

</body>
</html>
在这里插入图片描述

由上运行观察:

当我们一打开页面/初始化页面的时候,发现计算属性和方法都会调用

我们修改相关响应式依赖数据 ‘姓’ ‘名’时发现计算属性和方法也都会调用

我们再来看一下计算属性缓存的情况

在这里插入图片描述

1 首先我们在浏览器控制台上多次输入

vm.fullNameByMethods()

表示调用fullNameByMethods()方法,可以观察到控制台打印输出的相关信息

方法的fullNameByMethods方法被调用了...

"AB"

说明使用方法来获取姓名每次都会调用方法,每次都会执行方法里的逻辑代码。

2 而当我们在浏览器控制台上多次输入

vm.fullNameByComputed

表示调用fullNameByComputed计算属性,可以观察到控制台打印输出的相关信息

“AB”

就很奇怪,调用计算属性,那为什么控制台上就不打印

计算属性的fullNameByComputed方法被调用了...

其实,这就是计算属性缓存的原因,当我们第一次初始化页面的时候,计算属性执行了一次,就会把该计算属性返回的结果进行缓存,缓存结果为“AB”

所以再调用这个计算属性的时候,就不会在控制台上打印计算属性的fullNameByComputed方法被调用了...,也就是再次调用计算属性了,而是直接将缓存当中的数据返回,其实计算属性存在缓存, 多次读取只执行一次getter计算,至于getter方法后面案例提及,其实上面案例的fullNameByComputed默认就是getter方法

但是当我们修改了 相关响应式依赖数据,也就是 ‘姓’ ‘名’ 的时候,计算属性就会再一次执行,一旦再一次执行,就又会把计算属性的结果保存在缓存当中,所以再一次调用的时候,就又从缓存当中获取数据

下面我们再来看一个案例:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>

<div id="app">
    姓:<input type="text" v-model="firstName"><br>
    名:<input type="text" v-model="lastName"><br>
    姓名1(计算属性单向):<input type="text" v-model="fullNameByComputed"><br>
    姓名2(计算属性双向):<input type="text" v-model="fullNameByGetAndSet"><br>
</div>

<script src="../js/vue.js"></script>

<script>
    const vm = new Vue({
        el: '#app',
        data: {
            firstName: 'A',
            lastName: 'B',
        },
        computed: {
            
            fullNameByComputed: function () {
                return this.firstName + ' ' + this.lastName
            },

            fullNameByGetAndSet: {
                get() {
                    return this.firstName + ' ' + this.lastName
                }
            }
        },
    })
</script>

</body>
</html>

以上案例

计算属性当中fullNameByComputed方法

fullNameByComputed: function () {
                return this.firstName + ' ' + this.lastName
            },

等价于(默认就是get方法):

fullNameByGetAndSet: {
                get() {
                    return this.firstName + ' ' + this.lastName
                }
            }

computed 选项内的计算属性fullNameByComputed默认是 getter 函数,所以上面只支持单向绑定,我们改变姓或名,计算属性就会对项目进行同步更新,但是我们修改姓名,控制台就会报错

在这里插入图片描述

计算属性(双向绑定)

计算属性默认只有 getter ,不过在需要时你也可以提供一个 setter,setter方法从字面上理解就是设置值,使用setter就能解决修改姓名同步修改姓或名的值

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>

<div id="app">
    姓:<input type="text" v-model="firstName"><br>
    名:<input type="text" v-model="lastName"><br>
    姓名1(计算属性单向):<input type="text" v-model="fullNameByComputed"><br>
    姓名2(计算属性双向):<input type="text" v-model="fullNameByGetAndSet"><br>
</div>

<script src="../js/vue.js"></script>

<script>
    const vm = new Vue({
        el: '#app',
        data: {
            firstName: 'A',
            lastName: 'B',
        },
        computed: {
            //计算属性 默认 getter 只支持单向绑定
            fullNameByComputed: function () {
                return this.firstName + ' ' + this.lastName
            },

            //指定 getter/setter 双向绑定
            fullNameByGetAndSet: {
                // 当获取当前属性值时自动调用, 将返回值(根据相关的其它属性数据)作为属性值
                get() {
                    return this.firstName + ' ' + this.lastName
                },
                // 当属性值发生了改变时自动调用, 监视当前属性值变化, 同步更新相关的其它属性值
                set: function (newValue) {  //value为更新后的值 也就是姓名
                    // 更新firstName和lastName
                    const names = newValue.split(' ') //根据 ‘ ’ 进行拆分
                    //重新对 姓 和 名 进行赋值
                    this.firstName = names[0]
                    this.lastName = names[1]
                }
            }
        },
    })
</script>

</body>
</html>

效果:

在这里插入图片描述

2 监听器 watch的使用

下面我们同样看一个案例,修改姓或名,更新姓名的demo

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>

<div id="app">
    姓:<input type="text" v-model="firstName"><br>
    名:<input type="text" v-model="lastName"><br>
    姓名(监听):<input type="text" v-model="fullNameByWatch"><br>
</div>

<script src="../js/vue.js"></script>

<script>
    const vm = new Vue({
        el: '#app',
        data: {
            firstName: 'A',
            lastName: 'B',
            fullNameByWatch:''
        },
        //监听器方式1:watch选项
        watch: {
            //对firstName 姓 进行监听
            firstName: function(newValue,oldValue) {
                console.log('watch监听器执行.....')
                console.log(newValue) //新值
                console.log(oldValue) //旧值
                //更新姓名
                this.fullNameByWatch = newValue + this.lastName
            }
        }
    })

    //监听器方式2:通过vm对象调用
    //第1个参数为监听的属性名  lastName 名 ,第2个回调函数
    vm.$watch('lastName',function (newValue) {
        //newValue 就是新输入的值
        //更新姓名
        this.fullNameByWatch = this.firstName + newValue
    })
</script>

</body>
</html>

效果演示:

在这里插入图片描述
方便获取更多学习、工作、生活信息请关注本站微信公众号城东书院 微信服务号城东书院 微信订阅号
推荐内容
相关内容
栏目更新
栏目热门