关于vue.js:VUE-props-实现原理源码解析

36次阅读

共计 1492 个字符,预计需要花费 4 分钟才能阅读完成。

VUE props 实现原理(源码解析)

前言

咱们在应用组件的时候,都会给组件传入一些属性,然而在应用时,却只是关注了它传递数据的性能,没有想过它是怎么的一个原理,具体是怎么实现的。

其实咱们平时写进去的组件,实质上就是一个 template 模板,而这个 template 模板在 vue 中,会通过 render 函数解析,最终生成一个 VNode。那咱们通过源码来看一下在生成VNode 后,组件属性是怎么实现传递的。

源码解析

生成虚构节点源码

在生成虚构节点这,咱们能够看到这样一段代码,而这段代码中,propsData则是所有属性的一个定义,而这个对象的放在了虚构节点上,那咱们能够看看组件初始化时,这个 propsData 对象经验了怎么的操作。

 const vnode = new VNode(`vue-component-${Ctor.cid}${name ? `-${name}` : ''}`,
    data, undefined, undefined, undefined, context,
    {Ctor, propsData, listeners, tag, children},
    asyncFactory
  )
组件初始化源码

在下段代码中,咱们能够看到 propsData 对象是被赋值到了以后实例上的 $optionspropsData属性中,那咱们能够看一下初始化 props 时,这个 propsData 对象又通过了怎么的一个过程。

const opts = vm.$options = Object.create(vm.constructor.options)、const parentVnode = options._parentVnode
  opts._parentVnode = parentVnode
  const vnodeComponentOptions = parentVnode.componentOptions
  opts.propsData = vnodeComponentOptions.propsData
初始化 props 源码

在这里,从 $options 拿到 $options 对象后,申明了一个叫 _props 的空对象。

const propsData = vm.$options.propsData || {}
 const props = vm._props = {}

上面通过 vm.$parent 判断一下是不是根元素,如果是根元素,属性则须要设置为响应式的,如果不是则不须要。

const isRoot = !vm.$parent 
 if (!isRoot) {// 如果是根元素  属性须要定义成响应式
    toggleObserving(false)
 }

循环用户定义了的 propsOptions 选项,它会依据用户定义的对象来和用户传入的值通过 validateProp 办法来进行一个校验,并且拿到最终的后果value

而后将以后 key 和 value 值,通过 defineReactive 定义到咱们后面的 _props 中。

最终,将 _props 对象定义到咱们的实例下来,这样咱们就能够通过实例,间接拿取到属性了。

 for (const key in propsOptions) {keys.push(key)  // 校验用户定义的属性和传入的属性
    const value = validateProp(key, propsOptions, propsData, vm)
    if (process.env.NODE_ENV !== 'production') { } else {defineReactive(props, key, value)
    }
    if (!(key in vm)) {proxy(vm, `_props`, key)
    }
  }

总的来说,就是 将父组件传给它的属性,定义到了它本人的实例 上了。

正文完
 0