㈠ vue的设计思想
vue是一个MVVM框架,将视图View的状态和行为抽象化成ViewModal层,让我们将视图 UI 和业务逻辑分开。
重点在ViewModal层,要实现数据绑定,数据绑定的核心是响应式,所以
MVVM的三要素是:数据响应式、模板引擎及渲染;
以上图片中的内容就是vue的实现思想,只不过是vue1中的实现思想;
vue2中的改变是
通过以上源码观察,尤其:
可以看出vue2中的 Object.defineProperty 消耗是非常大的,不仅要遍历自身的key,去添加响应式,并且还要去遍历子属性的key。
vue1中watcher颗粒度太小了,所以改成一个组件一个watcher;
使用vnode最重要的原因是:只有一个watcher,我改了值很多foo,bar,界面受影响很多,没办法精确知道谁负责谁,所以只能两个VNode进行遍历;
带来的好处:
规避真是dom操作,
如何针对不同平台实现不同patch的呢:
拿出核心的createPatchFunction工厂函数逻辑,根据传参返回一个真的patch函数
参数nodeOps是节点操作,
参数moles是属性更新操作,针对平台的platformMoles操作
简单说就是 把平台特有的 { nodeOps, moles } 节点操作和节点属性传进去,会得到平台特有的patch函数
㈡ Vue 组件创建的流程源码分析
注册组件第二个参数默认会调用extend,Vue.extend 使用Vue基础构造器 产生子类
Vue.extend() 中data必须是一个函数,继承与Vue,可以new和挂载
Vue.component("",Vue.extend({})) //传入的是对象
这样复用了同一个对象所以改写为,这样new的时候可以拿到全新的对象
因为new Fn的constructor指向的是Parent,所以Sub.prototype需要重写
———————————————— 分割线 ————————————————————
所以在createElement,需要对组件进行处理(要区分组件和普通元素去创建虚拟节点)
判断是不是原始的标签 还是组件的方法
㈢ 这种VUE代码 是怎么写的
应该是打包工具自动生成的吧。
像这种代码类似库源码,是挺难阅读的。
㈣ vuejs源码用了什么设计模式,具体点的
最简单的订阅者模式
// Observer
class Observer {
constructor (data) {
this.walk(data)
}
walk (data) {
// 遍历
let keys = Object.keys(data)
for(let i = 0; i < keys.length; i++){
defineReactive(data, keys[i], data[keys[i]])
}
}
}
function defineReactive (data, key, val) {
observer(val)
// dep 为什么要在这里实例化, 就是为了实现, 对象每一层的 每一个key都有自己的一个订阅实例, 比如 a.b 对应 dep1, a.c 对应dep2, 这里虽然都是let dep = new Dep()
// 但每次来到这个方法, dep都是独立的, 会一直保留在内存. 这样在每次调用set方法都能找到这个a.b对应的dep
// dep 这里会一直保存, 是因为闭包的关系, Object这个全局的函数, 引用了上层的作用域, 这个作用域包含了 dep, 除非Object = null, 或者退出浏览器, dep才会消失
//实例化之后, dep就有了被订阅, 和发布消息的功能, dep不写在这里也是可以的, 多定义一个全局函数, 每次obser的时候增加一个dep
let dep = new Dep()
Object.defineProperty(data, key, {
enumerable: true,
configurable: true,
get: function () {
//每次new Watch('a.b'), 都会先执行get方法, 进而来到这里, 触发 dep.depend(), 这个dep就是 a.b 对应的 订阅,
dep.depend()
return val
},
set: function (newVal) {
if(val === newVal){
return
㈤ vue源码 (1.初始化过程_init)
1.在init阶段inject 是比 provide更早,比initState(initProps、initMethods、initComputed、initWatch) 都要早,因为vue的组件层级创建父组件created后再去创建子组件,一层一层向下创建的模式,那么inject如果有在上级组件定义provide,那么都会拿得到,而methods、computed、watch也有可能会用到 inject的值,所以需要放在最先初始化。
2.initInjections 原理
3.beforeCreate生命周期为什么不能访问数据,能访问到什么
4.initEvents 事件是挂在父组件执行还是当前组件this.$emit的组件
5.有el选项为什么可以不需要$mount