zoukankan      html  css  js  c++  java
  • data 和 computed 的区别

    data 和 computed 的区别

     

    这样看来,data 和 computed 在功能上似乎没有任何区别。

    data 和 computed 最核心区别

    先一言以蔽之,data 和 computed 最核心的区别在于 data 中的属性并不会随赋值变量的改动而改动,而computed 会。(赋值变量类似:num: aaa.bbb,直接赋值是 num: 123)。下面有两个例子来佐证。

    第一个例子

    <div id="app">
        <h2>num1是data中的变量,其初始值为:{{num1}}</h2>
     <h2>点击按钮后,data中的num1变化为:{{num1}}</h2>
        <h2>点击按钮后,computed中的c_num1变化为:{{c_num}}</h2>
        <button @click="outerNumChange">给num1+10</button>
        <hr>
        <h1>1.data定义的属性不会因为它的赋值变量的变化而变化</h1>
        <h1>2.computed定义的属性会随它的赋值变量的变化而变化</h1>
    </div>
    <script>
        let outer_obj = {num: 30}
        let app = new Vue({
            el: "#app",
            data: {
                temp: outer_obj, // 这一句一定要加,必须在 data 对象上存在才能让 Vue 将它转换为响应式的,见下图官方文档
                num1: outer_obj.num
            },
            computed: {
                c_num () {
                    return outer_obj.num
                }
            },
            methods: {
                outerNumChange () {
                    outer_obj.num += 10
                }
            },
        })
    </script>

    第二个例子

    1. 父组件改变 props,子组件如果直接使用 props,会触发子组件更新

    2. 父组件改变 props,子组件如果将 props 放进 data 中 再使用,不会触发子组件更新

    3. 父组件改变 props,子组件如果将 props 放进 computed 中再使用,会触发子组件更新

    代码的例子如下

    <div id="app">
        <h2>父组件的 msg---{{msg}}</h2>
        <button @click="handleClick">父组件改变 props</button>
        <temp-comp :father-msg="msg"></temp-comp>
    </div>
    
    <script>
        Vue.component('temp-comp', {
            template: `
    <div>
    <h2>直接使用 props---{{fatherMsg}}</h2>
    <h2>将 props 放进 data 再使用---{{dataFatherMsg}}</h2>
    <h2>将 props 放进 computed 再使用---{{computedFatherMsg}}</h2>
        </div>
    `,
            props: ['fatherMsg'],
            data () {
                return {
                    dataFatherMsg: this.fatherMsg
                }
            },
            computed: {
                computedFatherMsg () {
                    return this.fatherMsg
                }
            }
        })
        let app = new Vue({
            el: "#app",
            data: {
                msg: "hello"
            },
            methods: {
                handleClick () {
                    this.msg += " world"
                }
            }
        })
    </script>

    再回到第一张图,这里 data 里声明函数的话,其实就和 methods 一模一样了,根据官网的描述,计算属性是基于它们的响应式依赖进行缓存的。这句话比较抽象,意思就是只要计算属性依赖的那个数据不变,计算属性就不会重新计算,而 methods 是只要页面有任何数据变化导致数据的更新,methods 就会重新计算。官网没有给出实例,这里给出一个简短的例子。

    <div id="app">
        {{now()}}-----{{now2}}-----{{num}}
        <br>
        <button @click="hancleClick">改变 num</button>
    </div>
    <script>
        let app = new Vue({
            el: "#app",
            data: {
                num: 10,
                now () {
                    return Date.now()
                }
            },
            computed: {
                now2 () {
                    return Date.now()
                }
            },
            methods: {
                hancleClick () {
                    this.num += 10
                }
            }
        })
    </script>

    换一个角度来理解 data 和 computed 之间的区别

    考虑一下特殊情况

    data: {
        foo () {
            return this.bar() + 1
        },
        bar () {
            return this.foo() + 1
        }
    }
    // 这样的话就是循环引用,无解
    

    为了解决这个问题,Vue 把数据抽象成了两层,第一层就是简单的数据(data),第二层就是 computed (依赖于 data,也就是依赖于前一层)。第二层可以引用第一层的数据,而第一层却不能引用第二层的数据。这也是为什么在 data 中不能引用 computed 中的数据的原因。

    其实归根结底就是一个 Vue 实例在渲染的时候数据解析的顺序问题,结论是props->methods->data->computed->watch->created。官网的源码也写的很清楚,见下图

    源码的链接在这里Vue源码

  • 相关阅读:
    Python批量删除字符串中两个字符中间值
    2020年大三下学期第十周学习心得
    2020年大三下学期第九周学习心得
    2020.2.4
    2020.2.3
    2020.2.2
    2020.2.1
    签到六(开发)
    签到五(开发)
    签到四(开发)
  • 原文地址:https://www.cnblogs.com/xuzhenlei/p/12523449.html
Copyright © 2011-2022 走看看