你可能不知道Vue watch 有 5 种以上的写法

1,453 阅读1分钟

前言

今天在看Vue源码的时候,看到Watch这块的时候突然发现了新大陆 源码 如下:

function initWatch (vm: Component, watch: Object) {
  for (const key in watch) {
    const handler = watch[key]
    if (Array.isArray(handler)) {
      for (let i = 0; i < handler.length; i++) {
        createWatcher(vm, key, handler[i])
      }
    } else {
      createWatcher(vm, key, handler)
    }
  }
}

function createWatcher (
  vm: Component,
  expOrFn: string | Function,
  handler: any,
  options?: Object
) {
  if (isPlainObject(handler)) {
    options = handler
    handler = handler.handler
  }
  if (typeof handler === 'string') {
    handler = vm[handler]
  }
  return vm.$watch(expOrFn, handler, options)
}

看到Array.isArray时,watchwatch[key]还可以是数组???咱们watch最常用的就是下面这种情况

watch: {
    foo(v) {
        console.log(v)
    }
}

用的再深一点也就是一个对象啊

watch: {
    foo: {
        handler(v) {
            console.log(v)
        },
        deep: true,
        immediate: true
    }
}

难道还可以这样写???

watch: {
    foo: [...]
}

遂带着疑惑🤔继续看createWatcherhandler是一个普通对象的时候

if (isPlainObject(handler)) {
    options = handler
    handler = handler.handler
}
// 这个即对象的写法
foo: {
    handler(v) {
        console.log(v)
    },
    deep: true,
    immediate: true
}
if (typeof handler === 'string') {
    handler = vm[handler]
}

string??? 还可以是stirng

// 还可以这样???
watch: {
    foo: 'bar'
}

arraystring 这两种写法官网demo也没说啊。于是就自己测试了一下
这里推荐 EGOIST 开源的 codepan.net 在线编辑器,不用翻墙就可以快速测试,类似于JSBin/CodePen/JSFiddle
点击左上角的Boilerplates选择Vue自动生成 Vue模版如下:

🦐不测不知道,一测吓一跳🦐
我们就以监听模版中的count为例最终发现可以有以下几种写法:

<template>
    <script src="https://unpkg.com/vue"></script>
    
    <div id="app">
      <h2>{{ count }}</h2>
      <button @click="inc">inc</button>
      <button @click="dec">dec</button>
    </div>
</template>

new Vue({
  el: '#app',
  data: { count: 0 },
  methods: {
    inc() {
      this.count++
    },
    dec() {
      this.count--
    },
    foo() {
      console.log('foo')
    },
    bar() {
      console.log('bar')
    }
  },
  watch: {
    
    // 写法1 string, 即执行this.foo()
    count: 'foo'
    
    // 写法2 函数
    count(v) {
      console.log(v)
    },
    
    // 写法3 普通对象
    count: {
      handler(v) {
        console.log(v)
      },
      deep: true,
      immediate: true
    },
    
    // 写法4 数组里面放stirng,即执行 this.foo(),this.bar()
    count: [
      'foo',
      'bar'
    ],
    
    // 写法5 数组里面放普通对象或者stirng,自由组合
    count: [
      {
        handler(v) {
          console.log(v)
        },
        deep: true,
        immediate: true
      },
      {
        handler: 'foo'
      }
    ]
  }
})

总结

watch[key]的写法可以是string,function,object,array;array里面又可以stringobject混合。赶紧去 codepan.net 上面测试以下吧😊