vue源码分析-响应式系统(一)

本文深入探讨Vue响应式系统,从数据初始化、props处理、methods、data和computed的响应式化,到最后构建一个简化的响应式系统。通过分析,为后续源码细节解析奠定基础。
摘要由CSDN通过智能技术生成

从这一小节开始,正式进入Vue源码的核心,也是难点之一,响应式系统的构建。这一节将作为分析响应式构建过程源码的入门,主要分为两大块,第一块是针对响应式数据props,methods,data,computed,wather初始化过程的分析,另一块则是在保留源码设计理念的前提下,尝试手动构建一个基础的响应式系统。有了这两个基础内容的铺垫,下一篇进行源码具体细节的分析会更加得心应手。

7.1 数据初始化

回顾一下之前的内容,我们对Vue源码的分析是从初始化开始,初始化_init会执行一系列的过程,这个过程包括了配置选项的合并,数据的监测代理,最后才是实例的挂载。而在实例挂载前还有意忽略了一个重要的过程,数据的初始化(即initState(vm))。initState的过程,是对数据进行响应式设计的过程,过程会针对props,methods,data,computedwatch做数据的初始化处理,并将他们转换为响应式对象,接下来我们会逐步分析每一个过程。

function initState (vm) {
   
  vm._watchers = [];
  var opts = vm.$options;
  // 初始化props
  if (opts.props) {
    initProps(vm, opts.props); }
  // 初始化methods
  if (opts.methods) {
    initMethods(vm, opts.methods); }
  // 初始化data
  if (opts.data) {
   
    initData(vm);
  } else {
   
    // 如果没有定义data,则创建一个空对象,并设置为响应式
    observe(vm._data = {
   }, true /* asRootData */);
  }
  // 初始化computed
  if (opts.computed) {
    initComputed(vm, opts.computed); }
  // 初始化watch
  if (opts.watch && opts.watch !== nativeWatch) {
   
    initWatch(vm, opts.watch);
  }
}

7.2 initProps

简单回顾一下props的用法,父组件通过属性的形式将数据传递给子组件,子组件通过props属性接收父组件传递的值。

// 父组件
<child :test="test"></child>
var vm = new Vue({
   
  el: '#app',
  data() {
   
    return {
   
      test: 'child'
    }
  }
})
// 子组件
Vue.component('child', {
   
  template: '<div>{
   {test}}</div>',
  props: ['test']
})

因此分析props需要分析父组件和子组件的两个过程,我们先看父组件对传递值的处理。按照以往文章介绍的那样,父组件优先进行模板编译得到一个render函数,在解析过程中遇到子组件的属性,:test=test会被解析成{ attrs: {test: test}}并作为子组件的render函数存在,如下所示:参考Vue3源码视频讲解:进入学习

with(){
   ..._c('child',{
   attrs:{
   "test":test}})}

render解析Vnode的过程遇到child这个子占位符节点,因此会进入创建子组件Vnode的过程,创建子Vnode过程是调用createComponent,这个阶段我们在组件章节有分析过,在组件的高级用法也有分析过,最终会调用new Vnode去创建子Vnode。而对于props的处理,extractPropsFromVNodeData会对attrs属性进行规范校验后,最后会把校验后的结果以propsData属性的形式传入Vnode构造器中。总结来说,props传递给占位符组件的写法,会以propsData的形式作为子组件Vnode的属性存在。下面会分析具体的细节。

// 创建子组件过程
function createComponent() {
   
  // props校验
  var propsData = extractPropsFromVNodeData(data, Ctor, tag);
  ···
  // 创建子组件vnode
  var vnode = new VNode(
    ("vue-component-" + (Ctor.cid) + (name ? ("-" + name) : '')),
    data, undefined, undefined, undefined, context,
    {
    Ctor: Ctor, propsData: propsData, listeners: listeners, tag: tag, children: children },
    asyncFactory
  );
}

7.2.1 props的

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值