Vue之计算属性和侦听器

更新日期: 2019-11-11阅读: 2.2k标签: 属性

概述

vue开发中,模板内的表达式非常便利,但是设计它们的初衷是用于简单运算的。在模板中放入太多的逻辑会让模板过重且难以维护。当你想要在模板中多次引用相同表达式时,就会更加难以处理。所以,对于任何复杂逻辑,你都应当使用计算属性。本文主要讲解Vue中的计算属性和侦听器,仅供学习分享使用。


计算属性

计算属性步骤:

1. 在computed属性中增加reverseMsg方法,如下所示:

<script type="text/javascript">
    var vm = new Vue({
        el: '#app',
        data: {
            msg: 'welcome to vue world!!!'

        },
        computed: {
            reverseMsg: function() {
                // `this` 指向 vm 实例
                return this.msg.split('').reverse().join('');
            }
        }
                
    });
</script>

2. 在html中进行引用,你可以像绑定普通属性一样在模板中绑定计算属性。

Vue 知道 vm.reverseMsg 依赖于 vm.msg,因此当 vm.msg 发生改变时,所有依赖 vm.reverseMsg 的绑定也会更新。如下所示:

<p>原始信息: {{ msg }}</p>
<p>计算属性反转信息: {{ reverseMsg }}</p>

采用表达式的方式 ,则是如下所示:

<span>{{ msg.split('').reverse().join('') }}</span>

在这个地方,模板不再是简单的声明式逻辑。你必须看一段时间才能意识到,这里是想要显示变量 msg 的翻转字符串。此处对比一下,采用计算属性的方式,则更加简洁明了。


计算属性缓存 vs 方法

你可能已经注意到我们可以通过在表达式中调用方法来达到同样的效果,我们可以将同一函数定义为一个方法而不是一个计算属性。两种方式的最终结果确实是完全相同的。

如下所示,声明一个方法:

<script type="text/javascript">
    var vm = new Vue({
        el: '#app',
        data: {
            msg: 'welcome to vue world!!!'
        },
        methods: {
            reversedMsg: function() {
                return this.msg.split('').reverse().join('');
            }
        }

    });
</script>

在Html中进行引用,如下所示:

<p>Reversed message: "{{ reversedMsg() }}"</p>

差异:不同的是计算属性是基于它们的响应式依赖进行缓存的。 只在相关响应式依赖发生改变时它们才会重新求值。 这就意味着只要 msg 还没有发生改变,多次访问 reversedMsg计算属性会立即返回之前的计算结果,而不必再次执行函数。 即:计算属性只有当依赖属性发生改变时,才重新计算,而函数需要每次都重新计算。
也同样意味着下面的计算属性将不再更新,因为 Date.now() 不是响应式依赖:  相比之下,每当触发重新渲染时,调用方法将总会再次执行函数。 

<script type="text/javascript">
    var vm = new Vue({
        el: '#app',
        data: {
            msg: 'welcome to vue world!!!'

        },
        computed: {
            now: function() {
                return Date.now().toString();
            }

        });
</script>

如下所示,将不会随着时间的改变而触发。

<p>{{now}}</p>

如果你不希望有缓存,请用方法来替代。


计算属性 vs 侦听属性

如下所示:有两个data属性,firstName和lastName,fullName依赖说前两个变化而变化。如果需要采用侦听属性,需要对firstName和lastName进行侦听。

<script type="text/javascript">
    var vm = new Vue({
        el: '#app',
        data: {
            firstName: 'Foo',
            lastName: 'Bar',
            fullName: 'Foo Bar',
        },
        computed: {
            fullName2: function() {
                return this.firstName + ' ' + this.lastName;
            }
        },
        watch: {
            firstName: function(val) {
                this.fullName = val + ' ' + this.lastName;
            },
            lastName: function(val) {
                this.fullName = this.firstName + ' ' + val;
            }
        }
    });
</script>

上面代码是命令式且重复的。将它与计算属性的版本进行比较。

<div id="demo">{{ fullName }}</div>
<div id="demo">{{ fullName2 }}</div>

如上所示:fullName采用侦听属性,fullName2采用计算属性,对比一下,好得多了,不是吗?


计算属性的 setter

计算属性默认只有 getter ,不过在需要时你也可以提供一个 setter :如下所示:

fullName3: {
    //getter
    get: function() {
        return this.firstName + ' ' + this.lastName;
    },
    //setter
    set: function(newValue) {
        console.log('newValue=' + newValue);
        var names = newValue.split(' ');
        this.firstName = names[0];
        this.lastName = names[names.length - 1];
    }
}

在UI中引用的方式是一样的。当fullName3的值发生改变时,将更新firstName和lastName。

<p>{{fullName3}}</p>


侦听器

虽然计算属性在大多数情况下更合适,但有时也需要一个自定义的侦听器。这就是为什么 Vue 通过 watch 选项提供了一个更通用的方法,来响应数据的变化。当需要在数据变化时执行异步或开销较大的操作时,这个方式是最有用的。如下所示:

<script type="text/javascript">
    var vm = new Vue({
        el: '#app',
        data: {
            question: '',
            answer: 'I cannot give you an answer until you ask a question!'

        },
        watch: {
            // 如果 `question` 发生改变,这个函数就会运行
            question: function(newQuestion, oldQuestion) {
                if (newQuestion == '') {
                    this.answer = 'Waiting for you to stop typing...';
                } else {
                    this.answer = '请回答';
                }
            }
        }
    });
</script>

在页面中绑定属性

<p>Ask a yes/no question:
    <input v-model="question">
</p>
<p>{{ answer }}</p>

在这个示例中,使用 watch 选项允许我们执行异步操作 (访问一个 api),限制我们执行该操作的频率,并在我们得到最终结果前,设置中间状态。这些都是计算属性无法做到的。

在本示例中用的全部代码 ,如下所示:

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title>一起学Vue之计算属性和侦听器</title>
        <!-- 开发环境版本,包含了有帮助的命令行警告 -->
        <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    </head>
    <body>
        <div id="app">
            <span>{{msg}}</span>
            <h2>计算属性</h2>
            <!-- 
             模板内的表达式非常便利,但是设计它们的初衷是用于简单运算的。在模板中放入太多的逻辑会让模板过重且难以维护。例如:
             -->
            <br />
            <span>
                {{ msg.split('').reverse().join('') }}
            </span>
            <!-- 
            在这个地方,模板不再是简单的声明式逻辑。你必须看一段时间才能意识到,这里是想要显示变量 msg 的翻转字符串。
            当你想要在模板中多次引用此处的翻转字符串时,就会更加难以处理。
            所以,对于任何复杂逻辑,你都应当使用计算属性
             -->
            <p>原始信息: {{ msg }}</p>
            <p>计算属性反转信息: {{ reverseMsg }}</p>
            <!-- 
            这里我们声明了一个计算属性 reverseMsg。我们提供的函数将用作属性 vm.reverseMsg 的 getter 函数: 
             -->
            <!-- 
             你可以像绑定普通属性一样在模板中绑定计算属性。Vue 知道 vm.reverseMsg 依赖于 vm.msg,
             因此当 vm.msg 发生改变时,所有依赖 vm.reverseMsg 的绑定也会更新。
              -->
            <h2>计算属性缓存 vs 方法</h2>
            <p>Reversed message: "{{ reversedMsg() }}"</p>
            <!-- 
            你可能已经注意到我们可以通过在表达式中调用方法来达到同样的效果: 
            -->
            <!-- 
            我们可以将同一函数定义为一个方法而不是一个计算属性。两种方式的最终结果确实是完全相同的。
            然而,不同的是计算属性是基于它们的响应式依赖进行缓存的。 
            只在相关响应式依赖发生改变时它们才会重新求值。
            这就意味着只要 msg 还没有发生改变,多次访问 reversedMsg 计算属性会立即返回之前的计算结果,而不必再次执行函数。
            即:计算属性只有当依赖属性发生改变时,才重新计算,而函数需要每次都重新计算。
             -->
            <!-- 
            也同样意味着下面的计算属性将不再更新,因为 Date.now() 不是响应式依赖: 
            相比之下,每当触发重新渲染时,调用方法将总会再次执行函数。
            如果你不希望有缓存,请用方法来替代
             -->
            <p>{{now}}</p>
            <h2>计算属性 vs 侦听属性</h2>
            <div id="demo">{{ fullName }}</div>
            <!-- 
             上面代码是命令式且重复的。将它与计算属性的版本进行比较:
             -->
            <div id="demo">{{ fullName2 }}</div>
            <!-- 
             好得多了,不是吗?
             -->
            <h2>计算属性的 setter</h2>
            <!-- 
             计算属性默认只有 getter ,不过在需要时你也可以提供一个 setter :
             -->
            <p>{{fullName3}}</p>
            <h2>侦听器</h2>
            <!-- 
             虽然计算属性在大多数情况下更合适,但有时也需要一个自定义的侦听器。
             这就是为什么 Vue 通过 watch 选项提供了一个更通用的方法,来响应数据的变化。
             当需要在数据变化时执行异步或开销较大的操作时,这个方式是最有用的。
             -->
            <p>Ask a yes/no question:
                <input v-model="question">
            </p>
            <p>{{ answer }}</p>
            <!-- 
             在这个示例中,使用 watch 选项允许我们执行异步操作 (访问一个 API),
             限制我们执行该操作的频率,并在我们得到最终结果前,设置中间状态。
             这些都是计算属性无法做到的。
             -->
        </div>
        <script type="text/javascript">
            var vm = new Vue({
                el: '#app',
                data: {
                    msg: 'welcome to vue world!!!',
                    firstName: 'Foo',
                    lastName: 'Bar',
                    fullName: 'Foo Bar',
                    question: '',
                    answer: 'I cannot give you an answer until you ask a question!'


                },
                methods: {
                    reversedMsg: function() {
                        return this.msg.split('').reverse().join('')
                    }
                },
                computed: {
                    reverseMsg: function() {
                        // `this` 指向 vm 实例
                        return this.msg.split('').reverse().join('');
                    },
                    now: function() {
                        return Date.now().toString();
                    },
                    fullName2: function() {
                        return this.firstName + ' ' + this.lastName;
                    },
                    fullName3: {
                        //getter
                        get: function() {
                            return this.firstName + ' ' + this.lastName;
                        },
                        //setter
                        set: function(newValue) {
                            console.log('newValue=' + newValue);
                            var names = newValue.split(' ');
                            this.firstName = names[0];
                            this.lastName = names[names.length - 1];
                        }
                    }
                },
                watch: {
                    firstName: function(val) {
                        this.fullName = val + ' ' + this.lastName;
                    },
                    lastName: function(val) {
                        this.fullName = this.firstName + ' ' + val;
                    },
                    // 如果 `question` 发生改变,这个函数就会运行
                    question: function(newQuestion, oldQuestion) {
                        if (newQuestion == '') {
                            this.answer = 'Waiting for you to stop typing...';
                        } else {
                            this.answer = '请回答';
                        }
                    }

                }

            });
        </script>
    </body>
</html>

原文:https://www.cnblogs.com/hsiang/p/12020120.html

链接: https://fly63.com/article/detial/6821

display: none;与visibility: hidden;的区别

display:none;会让元素完全从渲染树中消失,渲染的时候不占据任何空间;visibility: hidden;不会让元素从渲染树消失,渲染师元素继续占据空间,只是内容不可见,display: none;是非继承属性,子孙节点消失由于元素从渲染树消失造成,通过修改子孙节点属性无法显示;

属性设置百分比时的计算参考汇总

元素宽高width,min-width,max-width等元素宽度设置百分比,以包含块的宽度为标准进行计算;height,min-height,max-height等元素宽度设置百分比,以包含块的高度为标准进行计算;

readonly与disabled的区别

readonly 只对 <input> 和 <textarea> 标签有效;disabled 对所有表单元素都有效, 包括:<input>, <textarea>, <button>, <label>, <option>, <select>等

css的overflow属性

事实上我挺长一段时间都没弄清楚overflow:scroll与overflow:auto的差别,今天测试了一下,总算是明白了。visible: 不剪切内容。hidden: 将超出对象尺寸的内容进行裁剪,将不出现滚动条。scroll: 将超出对象尺寸的内容进行裁剪,并以滚动条的方式显示超出的内容。

Vue Prop属性功能与用法实例

这篇文章主要介绍了Vue Prop属性功能与用法,结合实例形式较为详细的分析了vue.js中Prop属性的功能、原理、使用方法及相关操作注意事项,写的十分的全面细致,具有一定的参考价值

深入剖析z-index属性

层叠顺序的大小比较;层叠顺序级别高的元素覆盖级别低的元素。首先要注意,z-index:auto 虽然可以看作z-index:0 ,但是这仅仅是在层叠顺序的比较上;从层叠上下文上讲,二者有本质差别:auto 不会创建层叠上下文,z-index:0 会创建层叠上下文。

Vue.js-计算属性和class与style绑定

所有的计算属性都以函数的形式写在Vue实例中的computed选项内,最终返回计算后的结果。在一个计算属性中可以完成各种复杂的逻辑,包括运算、函数调用等,只要最终返回一个结果即可。

css属性分类介绍

CSS分类目录 文本/字体/颜色 文本相关 字体相关 颜色相关 背景相关 大小/布局 大小属性 margin 外边距 padding 内边距 border 边框 position 定位 列表/表格 多列属性 可伸缩框属性 列表属性 Grid属性 Table属性 动画属性 Animation 动画属性 Transition 过渡属性

css中word-wrap white-space word-break textoverflow的使用

word-wrap正常来说,在一行文本中,如果出现这一行已经放不下的单词,浏览器会自动将该文字转入下一行。white-space规定段落中的文本不进行换行。

css使用到的border边框属性

border 在一个声明中设置所有的边框属性。 border-bottom在一个声明中设置所有的下边框属性。border-bottom-color设置下边框的颜色。border-bottom-style设置下边框的样式。

点击更多...

内容以共享、参考、研究为目的,不存在任何商业目的。其版权属原作者所有,如有侵权或违规,请与小编联系!情况属实本人将予以删除!