vue 源码分析
题记
这是 vue 源码分析的第一节,学习 vue 有接近两年时间了,入手的第一份工作,就是从 vue 开始,本着自我驱动能力,渡人渡己。现在分析一下vue源码。组里老大经常说不管做什么事先想清楚,哪怕你一天只做一件事也好,所以文章可能出的比较慢,敬请耐心等待。本系列采用周更形式,每周三准时发车。 分析课会按照以下大纲来: 每周一篇的形式(算是立了个 flag 吗😂)。
[TOC]
├── vue.extend
├── vue.nextTick
├── vue.set
├── vue.delete
├── vue.directive
├── vue.filter
├── vue.use
├── vue.mixin
├── vue.compile
├── vue.observable
├── vue.version
├── [data](#data)
├── [props](#props)
├── propsData
├── [computed](#computed)
├── methods
└── watch双向绑定
实现双向绑定的方式有很多。
监听者(observer): 对数据增加 getter 和 setter,以及往观察者列表中增加观察者,当数据变动时去通知观察者列表。 观察者列表(Dep): 这个模块的主要作用是维护一个属性的观察者列表,当这个属性触发getter时将观察者添加到列表中,当属性触发setter造成数据变化时通知所有观察者, 观察者(watch):这个对数据进行观察,一旦收到数据变化的通知就会去改变视图.
为什么data必须是函数呢
new 的时候, 它首先需要创建一个个组件构造器,然后注册组件。注册组件的本质其实就是建立一个组件构造器的引用。使用组件才是真正创建一个组件实例。所以,注册组件其实并不产生新的组件类,但会产生一个可以用来实例化的新方式。
理解这点后, 在理解 js 的原型链
如果两个实例同时引用同一个对象,那么当你修改其中一个属性的时候, 另外一个实例也会跟着改。
Vue-组件的data属性为什么必须是函数? return 为什么返回的是函数不是对象 JS中的实例是通过构造函数来创建的,每个构造函数可以new出很多个实例,那么每个实例都会继承原型上的方法或属性。
vue的data数据其实是vue原型上的属性,数据存在于内存当中
vue为了保证每个实例上的data数据的独立性,规定了必须使用函数,而不是对象。
因为使用对象的话,每个实例(组件)上使用的data数据是相互影响的,这当然就不是我们想要的了。对象是对于内存地址的引用,直接定义个对象的话组件之间都会使用这个对象,这样会造成组件之间数据相互影响。
一般在公司环境使用中,各种前端框架都会用一下,因为不同框架理念和使用场景有些许区别,有的重规模化,有的追求轻便易上手;有的模块化程度很高,有的通常全部写一起;有的规则安排的明明白白,有的又需要各种语法糖……虽然最近几个月工作特别忙,但是还是拿出了一点点时间来扩充一下Vue的背景知识。
为什么组件的data属性必须是函数? 在自定义模块的新手上路部分,Vue文档是这么写的
通过 Vue 构造器传入的各种选项大多数都可以在组件里用。data 是一个例外,它必须是函数。如果定义了一个对象,那么 Vue 会停止,并在控制台发出警告,告诉你在组件中 data 必须是一个函数。
有一点觉得很奇怪,明明new Vue()的时候,data是可以传入一个对象的,为什么在组件这里,data就必须为函数了呢?
简而言之,组件的配置(options)和实例(instance)是需要分开的。最根本原因是js对于对象(以及数组等)是传引用的,因为如果直接写一个对象进去,那么当依此配置初始化了多个实例之后,这个对象必定是多个实例共享的。
举两个例子就明白了
例子1
例子2
为了加深印象,还是把相关部分都扯一点。
组件(Component)定义方式 写完hello world的同学都知道,组件在定义的时候,可以全局(Vue.component())或者局部注册
两种方法并没有本质区别,都需要在data属性里传入对象。局部注册只是放在了new Vue的options处理部分,仍然是Vue.extend(definition)里判断。
下面以全局注册为例过一遍Vue源码。
前面说的报错位置在这里
这个函数简单来说,是负责data字段内容处理的,不管是new Vue的参数里data还是组件初始化的data,都要经过这里。
简单起见,从这个位置往上倒(二声)到开头:
{ data: function () {...}, "template": "<button v-on:click="count++">You clicked me {{ count }} times.", "name": "button-counter" } 写入组件的配置:
这一步就是前面报错的那一步,会判断 data 是否为函数,是则执行并挂载函数方法。否则返回父级属性。
vue-component-config
组件挂载结果 看起来3个_assetTypes加了s,是在代码里搞的
初始化Vue实例时的处理
new Vue的时候,也会调用mergeOptions,不同的是这时候传入了vm实例。这时在mergeField('data')里走了另外一条路线:
最后更新于
这有帮助吗?