Vue2.0中的$watch、$set、$delete源码解析

本文详细解析Vue2.0中$watch、$set和$delete的实现原理,包括Watcher类的构造、依赖收集、深层监听(deep)以及$set如何使新增属性响应式,$delete在删除属性后的依赖通知。
$watch的实现就是对Watcher类的封装,在此基础上实现了{deep: true, immediate: true}可选参数。
在实际使用中,expOrFn这个参数可以是一个表达式或者是一个函数,表达式只接受以点分隔的路径,比如“a.b.c”。所以当参数是一个函数的时候,Watcher类的构造器里面会直接把该函数赋值给this.getter = expOrFn,否则,就用parsePath函数去解析表达式后赋值给getter。 值得注意的是,如果参数是函数,那么Watcher会同时观察这个函数里读取的实例上的数据,任一数据变动都会得到通知。
export default class Watcher{
  constructor(vm, expOrFn, cb){
    this.vm = vm;
    if(typeof expOrFn === 'function'){
      this.getter = expOrFn;
### `$` 符号在 Vue 中的作用 在 Vue 框架中,以 `$` 开头的属性和方法是 Vue 实例的内置 API,这些属性和方法不会与用户定义的数据、计算属性或方法发生命名冲突。通过这种方式,Vue 提供了一套清晰且统一的接口来操作实例和组件。 --- ### 常见的 `$` 开头的关键字及用途 #### 1. `$mount` 用于手动将 Vue 实例挂载到指定的 DOM 元素上。如果未传入参数,则可以在稍后调用 `$mount()` 完成挂载。 ```javascript new Vue({ template: `<div>Hello Vue!</div>` }).$mount('#app'); ``` #### 2. `$destroy` 用于销毁当前 Vue 实例。调用该方法后,实例会解除所有绑定,并移除所有事件监听器。 ```javascript this.$destroy(); ``` #### 3. `$emit` 用于触发自定义事件。通常用于子组件向父组件传递数据。 ```javascript this.$emit('update', newValue); ``` #### 4. `$on` 用于监听当前 Vue 实例上的自定义事件。 ```javascript this.$on('event-name', (data) => { console.log(data); }); ``` #### 5. `$once` 与 `$on` 类似,但只监听一次事件,在触发后自动解绑。 ```javascript this.$once('event-name', () => { console.log('This will only trigger once.'); }); ``` #### 6. `$off` 用于移除事件监听器。可以移除特定事件的所有监听器,也可以移除某个特定监听器。 ```javascript this.$off('event-name'); // 移除所有 event-name 监听器 this.$off('event-name', handler); // 移除指定监听器 ``` #### 7. `$set` 用于响应式地给对象添加新属性或修改数组的值,确保 Vue 能够检测到变化并更新视图。 ```javascript this.$set(this.obj, 'newKey', 'newValue'); ``` #### 8. `$delete` 用于从响应式对象中删除属性,同时保证 Vue 的响应式系统能够正确更新。 ```javascript this.$delete(this.obj, 'keyToRemove'); ``` #### 9. `$watch` 用于观察 Vue 实例上的数据变化,当数据发生变化时执行回调函数。 ```javascript this.$watch('someData', (newVal, oldVal) => { console.log(`someData changed from ${oldVal} to ${newVal}`); }); ``` #### 10. `$nextTick` 用于在下次 DOM 更新循环结束后执行回调函数,确保可以访问到更新后的 DOM。 ```javascript this.$nextTick(() => { console.log('DOM updated'); }); ``` #### 11. `$forceUpdate` 强制更新 Vue 实例,即使数据没有发生变化。通常不推荐使用,除非有特殊需求。 ```javascript this.$forceUpdate(); ``` #### 12. `$options` 包含当前 Vue 实例的初始化选项,可用于获取构造函数中的配置。 ```javascript console.log(this.$options); ``` #### 13. `$parent` 和 `$children` 分别用于访问当前组件的父组件和子组件实例。 ```javascript console.log(this.$parent); console.log(this.$children); ``` #### 14. `$root` 指向当前组件树的根 Vue 实例。 ```javascript console.log(this.$root); ``` #### 15. `$listeners` 包含作用域内父组件监听的事件,常用于组件通信。 ```javascript console.log(this.$listeners); ``` #### 16. `$props` 包含当前组件接收到的 `props` 数据。 ```javascript console.log(this.$props); ``` #### 17. `$scopedSlots` 用于访问组件的插槽内容,特别是作用域插槽。 ```javascript console.log(this.$scopedSlots); ``` #### 18. `$createElement`(`h` 函数) 用于创建虚拟 DOM 节点,在 `render` 函数中使用。 ```javascript render(h) { return h('div', 'Hello World'); } ``` #### 19. `$isServer` 用于判断当前是否运行在服务端(如 SSR 环境)。 ```javascript if (this.$isServer) { console.log('Running on server'); } ``` --- ### 示例代码:结合 `$emit` 和 `$on` 进行组件通信 ```javascript // Parent Component <template> <child-component @custom-event="handleEvent" /> </template> <script> export default { methods: { handleEvent(data) { console.log('Received:', data); } } }; </script> ``` ```javascript // Child Component <script> export default { mounted() { this.$emit('custom-event', 'Hello Parent'); } }; </script> ``` --- ### 总结 Vue 中带有 `$` 符号的属性和方法主要用于提供对 Vue 实例的底层操作能力,包括生命周期控制、事件管理、数据响应式处理以及组件通信等。合理使用这些 API 可以更灵活地控制 Vue 应用的行为,同时也避免了与用户自定义属性的命名冲突[^4]。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值