前言
我们先来了解一下Vue类
- 功能
- 负责接受初始化的参数
- 负责把data中的属性注入到Vue实例中,转化成getter/setter
- 负责调用 observer监听data中所有属性的变化
- 扶着调用 complier解析指令/差值表达式
- 结构
目标
<!DOCTYPE html>
<html lang="cn">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no, viewport-fit=cover">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
</head>
<body>
<div id="app">
<h1>差值表达式</h1>
<h3>{{ msg }}</h3>
<h3>{{ count }}</h3>
<h1> v-text </h1>
<h3 v-text="msg"></h3>
<h1> v-model </h1>
<input type="text" v-model="msg">
<input type="text" v-model="count">
</div>
</body>
</html>
可以实现以上的项目内容
创建类的结构
class Vue {
constructor (options) {
}
_proxyData (data) {
}
}
就这么简单constructor
接受实例化的内容;_proxyData
接受vue中的数据
接下来我们需要对constructor
中做出如下的动作:
- 通过属性保存选项的数据
- 把data中的成员转换成getter和setter,注入到vue实例中
- 调用observer对象,监听数据的变化
- 调用compiler对象,解析指令和差值表达式
我们先来实现前两件事情,后面的事情我们需要依赖 observer 对象,所以我们之后进行实现
通过属性保存选项的数据
class Vue {
constructor (options) {
// 1.通过属性保存选项的数据
this.$options = options || {}
this.$data = options.data || {}
// 这里我们需要进行一些判断,判断 options.el 是字符串对象还是一个dom实例
this.$el = typeof options.el === 'string' ? document.querySelector(options.el) : options.el
}
}
2. 把data中的成员转换成getter和setter,注入到vue实例中
class Vue {
constructor (options) {
this.$data = options.data || {}
// 2.把data中的成员转换成getter和setter,注入到vue实例中, 利用 _proxyData
this._proxyData(this.$data)
}
_proxyData(data) {
// 遍历data中的所有属性
// 注意这里我们是使用的箭头函数,这里我们使用的话this实例是指向vue
// 但是我们如果使用的是 function 的话,那么this指向就是 Window, 严格模式下 undefined
Object.keys(data).forEach(key => {
// 把data中的属性注入到vue实例中
Object.defineProperty(this, key, {
enumerable: true,
configurable: true,
get() {
return data[key]
},
// 这里需要进行判断值是否发生变化了,如果发生了变化在进行处理
set(newValue) {
if (newValue === data[key]) {
return
}
data[key] = newValue
}
})
})
}
}
ok 到这里我们的两个小点就结束了,接下来我们要进行Vue响应式原理模拟了!!!
请点击收藏追番吧!!!