$watch 基本上可以视为 Watcher 的封装,一般情况下 expOrFn 为 exp

    1. Vue.prototype.$watch = function (
    2. expOrFn: string | Function,
    3. cb: any,
    4. options?: Object
    5. ): Function {
    6. const vm: Component = this
    7. // 不同写法的兼容性处理,最终还是回到 $watch
    8. if (isPlainObject(cb)) {
    9. return createWatcher(vm, expOrFn, cb, options)
    10. }
    11. // 初始化 options
    12. options = options || {}
    13. // 确认当前 watch 为开发者定义的
    14. options.user = true
    15. // 创建 Watcher 实例
    16. const watcher = new Watcher(vm, expOrFn, cb, options)
    17. // 如果当前的 Watcher 被设定为在属性或函数被侦听后立即执行回调,则直接执行回调
    18. if (options.immediate) {
    19. try {
    20. cb.call(vm, watcher.value)
    21. } catch (error) {
    22. handleError(error, vm, `callback for immediate watcher "${watcher.expression}"`)
    23. }
    24. }
    25. // 返回一个取消监听的函数
    26. return function unwatchFn () {
    27. watcher.teardown()
    28. }
    29. }