• 1.9 watch选项合并

    1.9 watch选项合并

    在使用Vue进行开发时,我们有时需要自定义侦听器来响应数据的变化,当需要在数据变化时执行异步或者开销较大的操作时,watch往往是高效的。对于 watch 选项的合并处理,它类似于生命周期钩子,只要父选项有相同的观测字段,则和子的选项合并为数组,在监测字段改变时同时执行父类选项的监听代码。处理方式和生命钩子选项的区别在于,生命周期钩子选项必须是函数,而watch选项最终在合并的数组中可以是包含选项的对象,也可以是对应的回调函数,或者方法名。

    1. strats.watch = function (parentVal,childVal,vm,key) {
    2. //火狐浏览器在Object的原型上拥有watch方法,这里对这一现象做了兼容
    3. // var nativeWatch = ({}).watch;
    4. if (parentVal === nativeWatch) { parentVal = undefined; }
    5. if (childVal === nativeWatch) { childVal = undefined; }
    6. // 没有子,则默认用父选项
    7. if (!childVal) { return Object.create(parentVal || null) }
    8. {
    9. // 保证watch选项是一个对象
    10. assertObjectType(key, childVal, vm);
    11. }
    12. // 没有父则直接用子选项
    13. if (!parentVal) { return childVal }
    14. var ret = {};
    15. extend(ret, parentVal);
    16. for (var key$1 in childVal) {
    17. var parent = ret[key$1];
    18. var child = childVal[key$1];
    19. // 父的选项先转换成数组
    20. if (parent && !Array.isArray(parent)) {
    21. parent = [parent];
    22. }
    23. ret[key$1] = parent
    24. ? parent.concat(child)
    25. : Array.isArray(child) ? child : [child];
    26. }
    27. return ret
    28. };

    下面结合具体的例子看合并结果:

    1. var Parent = Vue.extend({
    2. watch: {
    3. 'test': function() {
    4. console.log('parent change')
    5. }
    6. }
    7. })
    8. var Child = Parent.extend({
    9. watch: {
    10. 'test': {
    11. handler: function() {
    12. console.log('child change')
    13. }
    14. }
    15. },
    16. data() {
    17. return {
    18. test: 1
    19. }
    20. }
    21. })
    22. var vm = new Child().$mount('#app');
    23. vm.test = 2;
    24. // 输出结果
    25. parent change
    26. child change

    简单总结一下:对于watch选项的合并,最终和父类选项合并成数组,并且数组的选项成员,可以是回调函数,选项对象,或者函数名。