Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

第 146 题:Vue 中的 computed 和 watch 的区别在哪里 #304

Open
yygmind opened this issue Oct 29, 2019 · 18 comments
Open

第 146 题:Vue 中的 computed 和 watch 的区别在哪里 #304

yygmind opened this issue Oct 29, 2019 · 18 comments

Comments

@yygmind
Copy link
Contributor

yygmind commented Oct 29, 2019

No description provided.

@yygmind yygmind added the 虾皮 label Oct 29, 2019
@seho-dev
Copy link

watch监听一个实例上的变量的变化,可以接受2个参数(newValue, oldValue),即变化的最新值和上一次变化的旧值
computed是计算属性,即示例上的数据不改变会有缓存,当下一次遇到的属性如果之前使用过,就会把缓存中的值放上去

@JaniceDong
Copy link

computed:计算属性

计算属性是由data中的已知值,得到的一个新值。
这个新值只会根据已知值的变化而变化,其他不相关的数据的变化不会影响该新值。
计算属性不在data中,计算属性新值的相关已知值在data中。
别人变化影响我自己。
watch:监听数据的变化

监听data中数据的变化
监听的数据就是data中的已知值
我的变化影响别人

1.watch擅长处理的场景:一个数据影响多个数据

2.computed擅长处理的场景:一个数据受多个数据影响

@GuoYuFu123
Copy link

说一下个人见解,
1、watch就是单纯的是监听某个数据的变化,支持深度监听
2、computed是计算属性,是依赖于某个或者某些属性值,只有当依赖的数据发生变化时,才会发生变化;

@ypf0088
Copy link

ypf0088 commented Oct 29, 2019

计算属性,实质就是将变量的get属性重写成了你所定义的那个函数,也就是说实现了数据劫持那一步,无所谓data还是props,都可以作为计算属性函数的依赖值。

属性监听,其实也就是观察者模式将变量丢进了观察者收集器当中,变化可以被通知到。

@gongshun
Copy link

计算属性是定义变量的get和set,对于复杂数据类型,引用地址不变,则不会触发set,get会缓存,不会重复计算。watch是变量变化时做点什么(触发一些函数),数组的一些变异的方法(push/splice/shift等)不会触发set,只能触发watch。

@Wetoria
Copy link

Wetoria commented Oct 29, 2019

computed:计算,顾名思义就是根据相关数据的变化得到一个新值。
watch:看,发现观察的东西有变更了,进行一系列的操作。
计算属性相当于一个变量,由一个方法构成,里面涉及到的data数据,就是相关数据。通常只做“计算结果”的逻辑,不改变数据。
watch则是需要根据观察的“对象”,在其变动时执行相关逻辑。

@HCLQ
Copy link

HCLQ commented Oct 29, 2019

watch 会生成一个watcher对象,在监视的属性每次变动时都会触发回调
computed 则是生成一个惰性的watcher,只有在取值操作(getter触发)时收集依赖且计算值
当有依赖变动时仅将 dirty 置为 true,不做计算操作
当有取值操作时,根据自身标记 dirty 属性返回上一次计算结果/重新计算值

@1727738828
Copy link

Watch
    watch用于观察和监听页面上的vue实例,当你需要在数据变化响应时,执行异步操作,或高性能消耗的操作,那么watch为最佳选择

computed
    可以关联多个实时计算的对象,当这些对象中的其中一个改变时都会触发这个属性
    具有缓存能力,所以只有当数据再次改变时才会重新渲染,否则就会直接拿取缓存中的数据。

@chenchangwen
Copy link

vue:2.6.10

<template>
    <div class="container" id="home">
        <p>{{a}}</p>
        <p>{{b}} </p>
        <p>{{d}}</p>
        <button @click="change">改变a</button>
    </div>
</template>
<script>

    export default {
        data() {
            return {
                a: 1,
                b: 2
            }
        },
        methods: {
            change() {
                this.a = 5;
            }
        },
        watch: {
            a() {
                console.log('watch a');
            }
        },
        computed:{
            d() {
                console.log('computed');
                return this.a + this.b;
            }
        }
    }
</script>

watch: a属性变化时打印.
computed: (a|b)属性变化时打印.

这个例子change一直都是5,实际上不会一直执行打印,都有缓存.

@spongege
Copy link

spongege commented Nov 4, 2019

没看过这方面的源码,但是据说computed的依赖变化的时候如果没对computed里面的值进行使用,好像是不会触发computed的。

@ypf0088
Copy link

ypf0088 commented Nov 5, 2019

没看过这方面的源码,但是据说computed的依赖变化的时候如果没对computed里面的值进行使用,好像是不会触发computed的。

因为computed没有对观察者进行实现,只是做了数据劫持

@Hunterang
Copy link

computed 是在Dep.update(),执行之后,数据更新之前,对新数据从新改造。

watch 是在set刚开始发生的时候添加的回调,可以监听数据的变化情况

@yygmind yygmind added the Vue label Dec 16, 2019
@tywei90
Copy link

tywei90 commented Feb 7, 2020

我总结了下,有如下几点:

  • 功能上:computed是计算属性,也就是依赖其它的属性计算所得出最后的值。watch是去监听一个值的变化,然后执行相对应的函数

  • 使用上:computed中的函数必须要用return返回;watch的回调里面会传入监听属性的新旧值,通过这两个值可以做一些特定的操作,不是必须要用return

  • 性能上:computed中的函数所依赖的属性没有发生变化,那么调用当前的函数的时候会从缓存中读取,而watch在每次监听的值发生变化的时候都会执行回调

  • 场景上:computed:当一个属性受多个属性影响的时候,例子:购物车商品结算;watch:当一条数据影响多条数据的时候,例子:搜索框

@lianlilin
Copy link

我总结了下,有如下几点:

  • 功能上:computed是计算属性,也就是依赖其它的属性计算所得出最后的值。watch是去监听一个值的变化,然后执行相对应的函数
  • 使用上:computed中的函数必须要用return返回;watch的回调里面会传入监听属性的新旧值,通过这两个值可以做一些特定的操作,不是必须要用return
  • 性能上:computed中的函数所依赖的属性没有发生变化,那么调用当前的函数的时候会从缓存中读取,而watch在每次监听的值发生变化的时候都会执行回调
  • 场景上:computed:当一个属性受多个属性影响的时候,例子:购物车商品结算;watch:当一条数据影响多条数据的时候,例子:搜索框

感觉总结的挺好的,赞

@Littledevil7
Copy link

最直接的:computed中定义的是变量,是可展示的,可操作的值,而watch只是一个工具,服务于变量

@boboyangmoumou
Copy link

  • computed是有缓存的,只有相关依赖没有改变,多次访问都是取缓存中的值,不会多次执行,比如有个性能开销很大的属性Value,有一个巨大的数据在遍历的时候里面的值会依赖到属性Value,会多次出发Value的getter,但是有了缓存就之间在缓存里面查。还有使用上必须有return返回值。
  • watch观察和相应Vue实例上的变动,用于观察某一个值取完成较大的业务逻辑,支持对属性的深度遍历监听和立刻执行,

@wangtunan
Copy link

共同点:都是经过依赖收集和派发更新的流程
不同点:
1、计算属性依赖computed watcher、watch监听依赖的是user watcher。
2、定义方式不同,计算属性本质上是get/set形式,即使写成函数形式,Vue底层也会规范化为get/set形式。而watch提供的是一个回调函数。
3、可取消性不同,计算属性一旦依赖,无法取消,也就是说定义后无法更改其get函数,而使用$watch方法实现的监听它返回一个unwatch可随时取消,取消后当数据再次发生变动时,不会再执行我们的回调函数。
4、时效性不同,计算属性属于惰性求值,当依赖的响应式变量更新时,只要我们不主动触发计算属性的getter,它可能永远都不会重新求值。对于watch而言,只要我们的响应式变量发生了变化,就会执行回调函数。
5、依赖变化性,计算属性的依赖可能不固定,每次求值时会重新进行依赖收集,依赖清除,而watch监听的依赖是固定的。

@yyjiugui
Copy link

yyjiugui commented Aug 11, 2021

一、
Computed 的响应是 deep 的响应,即在计算过程中用到的对象的属性发生变化,是可以被监听到的。
watch的响应默认是非deep的,deep: false默认。
immediate同理

computed: {
  fullName: function () {
    // this.name 的属性 firstName/lastName 变化时 fullName 会响应。
    return this.name.firstName + ' ' + this.name.lastName
  }
},
watch: {
  name: function () {
    // this.name 的属性 firstName/lastName 变化时不会触发。
  },
  deep: false, // 默认是false
}

二、
watch支持异步设置数据, computed不支持异步计算数据。

三、
watch不支持缓存,监听的数据改变,直接会触发会setter,computed支持

四、watch主要用来监听某些特定数据的变化,从而进行某些具体的业务逻辑操作,可以看作是 computed 和 methods 的结合体;

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests