Vue学习笔记(三) 计算属性和侦听属性

简介: Vue学习笔记(三) 计算属性和侦听属性


1、计算属性(computed)


(1)计算属性


模板的设计初衷是为了处理简单的逻辑(声明式逻辑),在模板中加入过多的逻辑会使模板难以阅读和维护

<!DOCTYPE html>
<html>
<head>
    <title>Demo</title>
    <script src="https://unpkg.com/vue/dist/vue.js"></script>
</head>
<body>
    <div id="app">
        <p>原始字符串:{{ message }}</p>
        <!-- 比如说,在模板中对 message 进行复杂的字符串反转操作 -->
        <p>反转字符串:{{ message.split('').reverse().join('') }}</p>
    </div>
    <script>
        var vm = new Vue({
            el: '#app',
            data: {
                message: 'hello'
            }
        })
    </script>
</body>
</html>


这时,我们就应该考虑使用计算属性,以代替复杂的模板逻辑

<!DOCTYPE html>
<html>
<head>
    <title>Demo</title>
    <script src="https://unpkg.com/vue/dist/vue.js"></script>
</head>
<body>
    <div id="app">
        <p>原始字符串:{{ message }}</p>
        <!-- 在模板中直接使用计算属性 -->
        <p>反转字符串:{{ reversedMessage }}</p>
    </div>
    <script>
        var vm = new Vue({
            el: '#app',
            data: {
                message: 'hello'
            },
            // computed 是 Vue 实例的计算属性
            // 它可以是一个对象,其中每一项的键是计算属性的名称,值是计算属性对应的函数
            computed: {
                // 这里,我们声明计算属性 reversedMessage,用于储存反转之后的字符串
                // 所提供的函数默认作为计算属性的 getter 函数(事实上还可以提供 setter 函数)
                // 这里的计算属性 reversedMessage 依赖于 message
                // 也就是说,当 message 发生变化时,reversedMessage 会自动更新
                reversedMessage: function () {
                    return this.message.split('').reverse().join('')
                }
            }
        })
    </script>
</body>
</html>


(2)computed & methods


不知道大家还记不记得,我们在之前的文章中有一个例子,使用 methods 实现反转字符串的效果

<!DOCTYPE html>
<html>
<head>
    <title>Demo</title>
    <script src="https://cdn.jsdelivr.net/npm/vue"></script>
</head>
<body>
    <div id="app">
        <p>原始字符串:{{ message }}</p>
        <!-- 在模板中显示方法的返回结果 -->
        <p>反转字符串:{{ reversedMessage() }}</p>
    </div>
    <script type="text/javascript">
        var vm = new Vue({
            el: '#app',
            data: {
                message: "Hello Vue"
            },
            methods: {
                // 定义方法 reversedMessage(),返回反转之后的字符串
                reversedMessage: function () {
                    return this.message.split('').reverse().join('')
                }
            }
        })
    </script>
</body>
</html>


可以看到,使用 computed 和 methods 实现的功能大体相同,但是它们的不同之处在于:

  1. computed 是 属性调用,而 methods 是方法调用
  2. computed 是 基于缓存,而 methods 不是


对于计算属性而言,计算结果将会被缓存,如果某个依赖在该实例范畴之外,那么计算属性是不会被更新的

但是对于方法而言,调用方法总会再次执行代码,我们可以从一个简单的例子看出它们之间的区别:

<!DOCTYPE html>
<html>
<head>
    <title>Demo</title>
    <script src="https://cdn.jsdelivr.net/npm/vue"></script>
</head>
<body>
    <div id="app">
        <!-- 注意,这里是属性调用 -->
        <p>第一次调用 computed:{{ msg_in_computed }}</p>
        <p>第二次调用 computed:{{ msg_in_computed }}</p>
        <br/>
        <!-- 注意,这里是方法调用 -->
        <p>第一次调用 methods:{{ msg_in_methods() }}</p>
        <p>第二次调用 methods:{{ msg_in_methods() }}</p>
    </div>
    <script>
        var cnt_for_computed = 0;
        var cnt_for_methods = 0;
        var vm = new Vue({
            el: '#app',
            computed: {
                // 定义计算属性 msg_in_computed,多次调用不会更新数据
                // 因为它的依赖 cnt_for_computed 是非响应式属性,不在实例范畴之内
                msg_in_computed: function () {
                    cnt_for_computed += 1;
                    return cnt_for_computed
                }
            },
            methods: {
                // 定义方法 msg_in_methods(),每次调用总会执行代码
                msg_in_methods: function () {
                    cnt_for_methods += 1;
                    return cnt_for_methods
                }
            }
        })
    </script>
</body>
</html>
<!-- 输出结果
第一次调用 computed:1
第二次调用 computed:1
第一次调用 methods:1
第二次调用 methods:2
-->


(3)getter & setter


计算属性默认只有 getter 函数

<!DOCTYPE html>
<html>
<head>
    <title>Demo</title>
    <script src="https://cdn.jsdelivr.net/npm/vue"></script>
</head>
<body>
    <div id="app">
        <p>fullName: {{ fullName }}</p>
        <p>firstName: {{ firstName }}</p>
        <p>lastName: {{ lastName }}</p>
    </div>
    <script>
        var vm = new Vue({
            el: '#app',
            data: {
                firstName: 'Steve',
                lastName: 'Jobs'
            },
            computed: {
                // 若为计算属性提供一个函数,则该函数默认作为计算属性的 getter 函数
                fullName: function () {
                    return this.firstName + ' ' + this.lastName
                }
            }
        })
        // 修改计算属性依赖的值时,会自动调用计算属性的 getter 函数
        vm.firstName = 'Stephen'
    </script>
</body>
</html>
<!-- 输出结果
fullName: Stephen Jobs
firstName: Stephen
lastName: Jobs
-->


但是,在需要的时候我们也可以提供一个 setter 函数

<!DOCTYPE html>
<html>
<head>
    <title>Demo</title>
    <script src="https://cdn.jsdelivr.net/npm/vue"></script>
</head>
<body>
    <div id="app">
        <p>fullName: {{ fullName }}</p>
        <p>firstName: {{ firstName }}</p>
        <p>lastName: {{ lastName }}</p>
    </div>
    <script>
        var vm = new Vue({
            el: '#app',
            data: {
                firstName: 'Steve',
                lastName: 'Jobs'
            },
            computed: {
                fullName: {
                    // getter 函数
                    get: function () {
                        return this.firstName + ' ' + this.lastName
                    },
                    // setter 函数
                    set: function (newValue) {
                        var names = newValue.split(' ')
                        this.firstName = names[0]
                        this.lastName = names[names.length - 1]
                    }
                }
            }
        })
        // 修改计算属性的值时,会自动调用计算属性的 setter 函数
        vm.fullName = 'Tim Cook'
    </script>
</body>
</html>
<!-- 输出结果
fullName: Tim Cook
firstName: Tim
lastName: Cook
-->


2、侦听属性(watch)


侦听属性是一个对象,键是需要观察的表达式,值是 对应的回调函数 或者是 包含选项的对象

  • 对应的回调函数
<!DOCTYPE html>
<html>
<head>
    <title>Demo</title>
    <script src="https://cdn.jsdelivr.net/npm/vue"></script>
</head>
<body>
    <div id="app">
        <p>计数器: {{ counter }}</p>
        <button @click="counter++">点我</button>
    </div>
    <script type="text/javascript">
        var vm = new Vue({
            el: '#app',
            data: {
                counter: 1
            },
            watch: {
                // 当 counter 发生变化时,会自动调用其对应的回调函数打印一条信息
                counter: function(val, oldVal){
                    alert('计数器从 ' + val + ' 变为 ' + oldVal);
                }
            }
        });
    </script>
</body>
</html>


  • 包含选项的对象
var vm = new Vue({
    el: '#app',
    data: {
        counter: 1
    },
    watch: {
        // 使用对象可以为监听属性添加更多的配置信息
        counter: {
            handler: function (val, oldVal) {
                alert('计数器从 ' + val + ' 变为 ' + oldVal);
            },
            deep: true, // 当监听对象的属性发生变化时(不管嵌套的深度),触发回调
            immediate: true // 在侦听开始之后,立即触发回调
        },
    }
});



文章知识点与官方知识档案匹配,可进一步学习相关知识

目录
相关文章
|
2月前
|
存储 缓存 JavaScript
如何在大型 Vue 应用中有效地管理计算属性和侦听器
在大型 Vue 应用中,合理管理计算属性和侦听器是优化性能和维护性的关键。本文介绍了如何通过模块化、状态管理和避免冗余计算等方法,有效提升应用的响应性和可维护性。
|
3月前
|
监控 JavaScript 开发者
在 Vue 中,子组件为何不可以修改父组件传递的 Prop,如果修改了,Vue 是如何监控到属性的修改并给出警告的
在 Vue 中,子组件不能直接修改父组件传递的 Prop,以确保数据流的单向性和可预测性。如果子组件尝试修改 Prop,Vue 会通过响应式系统检测到这一变化,并在控制台发出警告,提示开发者避免这种操作。
|
3月前
|
JavaScript 前端开发 开发者
VUE学习一:初识VUE、指令、动态绑定、计算属性
这篇文章主要介绍了Vue.js的基础知识,包括初识Vue、指令如v-for、v-on的使用、动态属性绑定(v-bind)、计算属性等概念与实践示例。
70 1
|
3月前
|
缓存 JavaScript Serverless
vue中computed计算属性、watch侦听器、methods方法的区别以及用法
vue中computed计算属性、watch侦听器、methods方法的区别以及用法
192 0
|
3月前
|
缓存 JavaScript 前端开发
深入理解Vue.js中的计算属性与侦听属性
【10月更文挑战第5天】深入理解Vue.js中的计算属性与侦听属性
43 0
|
12天前
|
JavaScript
vue使用iconfont图标
vue使用iconfont图标
78 1
|
22天前
|
JavaScript 关系型数据库 MySQL
基于VUE的校园二手交易平台系统设计与实现毕业设计论文模板
基于Vue的校园二手交易平台是一款专为校园用户设计的在线交易系统,提供简洁高效、安全可靠的二手商品买卖环境。平台利用Vue框架的响应式数据绑定和组件化特性,实现用户友好的界面,方便商品浏览、发布与管理。该系统采用Node.js、MySQL及B/S架构,确保稳定性和多功能模块设计,涵盖管理员和用户功能模块,促进物品循环使用,降低开销,提升环保意识,助力绿色校园文化建设。
|
2月前
|
JavaScript 前端开发 开发者
vue学习第一章
欢迎来到我的博客!我是瑞雨溪,一名热爱前端的大一学生,专注于JavaScript与Vue,正向全栈进发。博客分享Vue学习心得、命令式与声明式编程对比、列表展示及计数器案例等。关注我,持续更新中!🎉🎉🎉
52 1
vue学习第一章
|
2月前
|
JavaScript 前端开发 索引
vue学习第三章
欢迎来到瑞雨溪的博客,一名热爱JavaScript与Vue的大一学生。本文介绍了Vue中的v-bind指令,包括基本使用、动态绑定class及style等,希望能为你的前端学习之路提供帮助。持续关注,更多精彩内容即将呈现!🎉🎉🎉
49 1
|
2月前
|
缓存 JavaScript 前端开发
vue学习第四章
欢迎来到我的博客!我是瑞雨溪,一名热爱JavaScript与Vue的大一学生。本文介绍了Vue中计算属性的基本与复杂使用、setter/getter、与methods的对比及与侦听器的总结。如果你觉得有用,请关注我,将持续更新更多优质内容!🎉🎉🎉
41 1
vue学习第四章