实现Vue响应式原理 之 vue.js部分
结构介绍
Vue 功能
- 负责接收初始化的参数(选项)
- 负责把 data 中的属性注入到 Vue 实例,转换成 getter/setter
- 负责调用 observer 监听 data 中所有属性的变化
- 负责调用 compiler 解析指令/插值表达式
Vue 结构
代码实现
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Mini Vue</title>
</head>
<body>
<div id="app">
<h1>差值表达式</h1>
<h3>{{msg}}</h3>
<h3>{{count}}</h3>
<h1>v-text</h1>
<div v-text="msg"></div>
<h1>v-model</h1>
<input type="text" v-model="msg">
<input type="text" v-model="count">
</div>
<script src="./js/vue.js"></script>
<script>
let vm = new Vue({
el: '#app',
data: {
msg: 'Hello Vue',
count: 100
}
});
</script>
</body>
</html>
vue.js
底层执行主要使用Object.defineProperty来实现将data注入到Vue实例
class Vue {
constructor(options) {
// 1. 通过属性保存选项的数据
this.$options = options || {}
this.$data = options.data || {}
const el = options.el
// options传入的el可能是字符串的形式,如果是字符串就是一个选择器,也可能就是一个DOM对象
this.$el = typeof options.el === 'string' ? document.querySelector(el)
: el
// 2. 把data中的成员转换成getter和setter,注入到 Vue 实例
this._proxyData(this.$data)
// 3. 调用 Observer 对象,监听数据的变化,实现数据劫持
// 4. 调用 Compiler 对象,解析指令/插值表达式等
}
// 代理数据,Vue代理data中的属性
_proxyData(data) {
// 遍历 data 的所有属性
Object.keys(data).forEach(key => {
// 把 data 的属性注入到 Vue实例中
// 这里的 this 就是Vue实例
Object.defineProperty(this, key, {
enumerable: true, // 是否可遍历
configurable: true, // 是否可配置
get() {
return data[key]
},
set(newValue) {
if (data[key] === newValue) {
return
}
data[key] = newValue
}
})
})
}
}
打开浏览器 F12 打印模拟的Vue,查看Vue实例