computed(计算属性):https://codesandbox.io/s/recursing-rgb-61xi8?file=/src/main.js
watch撤销(自己添加一个inUndoMode):https://codesandbox.io/s/festive-fermat-pbb3v?file=/src/main.js
用watch模拟computed(用到immediate):https://codesandbox.io/s/practical-knuth-x5fd9?file=/src/main.js
watch监听范围(用到deep)https://codesandbox.io/s/distracted-robinson-7p3ml?file=/src/main.js

computed和watch的区别:

computed,计算属性,根据响应式依赖进行缓存。当依赖发生改变时会重新计算。
watch,侦听器,用于侦听数据,当数据发生变化时,执行异步或开销较大的操作

computed对应的属性值是一个对象
对象的键是一个字符串,值是一个函数(默认是getter)
[key: string]: Function
或者一个对象接受一个get函数和一个set函数。

[key: string]:{ get: Function, set: Function }

watch的对应的属性值是一个对象,对象的键是一个字符串,值是字符串或函数或对象或数组
watch里面的函数接收两个参数,第一个是新值,第二个是旧值
{ [key: string]: string | Function | Object | Array }

当watch里面的值为对象时,这个对象拥有两个属性:immediate和deep

immediate:

值为true;表示该回调将会在监听开始之后立刻被调用

deep:

值为true;表示该回调会在被侦听对象的任意属性发生改变时被调用,不论其被嵌套多深

注意:

watch 里面不要用箭头函数,箭头函数里的this是指向它作用域链上一层的this,这样this很难保证就是Vue的实例