Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Vue源码-双向数据绑定原理(一) #3

Open
7kyun opened this issue May 9, 2022 · 0 comments
Open

Vue源码-双向数据绑定原理(一) #3

7kyun opened this issue May 9, 2022 · 0 comments

Comments

@7kyun
Copy link
Owner

7kyun commented May 9, 2022

initData

这段代码主要是初始化data中的数据,将数据进行Observer,监听数据的变化,其他的监视原理一致,这里以data为例
相关源码

function initData (vm: Component) {
  // 获取data数据
  let data = vm.$options.data
  data = vm._data = typeof data === 'function'
    ? getData(data, vm)
    : data || {}

  // 判断数据结构
  if (!isPlainObject(data)) {
    data = {}
    process.env.NODE_ENV !== 'production' && warn(
      'data functions should return an object:\n' +
      'https://vuejs.org/v2/guide/components.html#data-Must-Be-a-Function',
      vm
    )
  }
  // proxy data on instance
  const keys = Object.keys(data)
  const props = vm.$options.props
  const methods = vm.$options.methods
  let i = keys.length
  // 遍历数据
  while (i--) {
    const key = keys[i]
    // method 属性命名冲突判断
    if (process.env.NODE_ENV !== 'production') {
      if (methods && hasOwn(methods, key)) {
        warn(
          `Method "${key}" has already been defined as a data property.`,
          vm
        )
      }
    }
    // props 属性命名冲突判断 优先props 
    if (props && hasOwn(props, key)) {
      process.env.NODE_ENV !== 'production' && warn(
        `The data property "${key}" is already declared as a prop. ` +
        `Use prop default value instead.`,
        vm
      )
    } else if (!isReserved(key)) {
      // 非保留字段
      // 代理到vm实例
      proxy(vm, `_data`, key)
    }
  }
  // observe data
  // 遍历结束 开始监听数据
  // asRootData:true 代表此处监听为根数据 根数据会进行计数(vmCount++) 后续设值的时候会对 vmCount进行判断
  observe(data, true /* asRootData */)
}

这段代码主要做了两件事,一是将_data上面的数据代理到vm实例上,另一件事通过observe将所有数据变成observable。

Proxy

接下来看一下proxy代理。
相关源码

export function proxy (target: Object, sourceKey: string, key: string) {
  sharedPropertyDefinition.get = function proxyGetter () {
    return this[sourceKey][key]
  }
  sharedPropertyDefinition.set = function proxySetter (val) {
    this[sourceKey][key] = val
  }
  Object.defineProperty(target, key, sharedPropertyDefinition)
}

这里比较好理解,通过proxy函数将data上面的数据代理到vm上
以实现 this.xxx 进行获取及赋值 data 内的数据

下一篇会先说一下 defineReactiveobserve 这两个比较重要的方法

@7kyun 7kyun changed the title Vue 数据绑定原理(一) Vue 响应式原理(一) May 11, 2022
@7kyun 7kyun removed the 置顶 label May 12, 2022
@7kyun 7kyun changed the title Vue 响应式原理(一) Vue源码-双向数据绑定原理(一) Jul 14, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant