1.简述功能
我们实现的一个带有响应式功能的简单Vue框架。
功能:
- 负责接收初始化的参数(options)
- 负责把data中的属性注入到Vue实例,转换成getter/setter
- 负责调用observer监听data属性中的变化
- 负责调用compiler解析指令/差值表达式
Vue类的结构:
前三个是Vue的属性,最后一个是Vue的方法,用于将data设置为setter/getter,并纳入Vue实例中。
项目初始结构:
2.创建Vue
index.html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>手写Vue响应式</title>
</head>
<body>
<div id="app">
<h1>差值表达式</h1>
<h3>{
{msg}}</h3>
<h3>{
{count}}</h3>
<h1>Vue指令(v-text)</h1>
<div v-text="msg"></div>
<h1>Vue指令(v-model)</h1>
<label for="msg">msg:</label><input type="text" v-model="msg">
<label for="count">count:</label><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:11
}
})
console.log(vm);
</script>
</body>
</html>
vue.js:
class Vue{
constructor(options){
//1.通过属性保存选项的数据
this.$options=options||{
},
this.$data=options.data||{
},
this.$el=typeof options.el ==="string" ? document.querySelector(options.el):options.el,
//2.把data中的属性转换成getter和setter,注入到vue实例中
this._proxyData(this.$data)
}
_proxyData(data){
Object.keys(data).forEach((key)=>{
//这里使用箭头函数,可以不改变this的指针,这里的this指向Vue实例,因为上面是使用this._proxyData调用
//确保第一个参数this指向Vue实例
//Object.defineProperty() 方法会直接在一个对象上定义一个新属性,或者修改一个对象的现有属性,并返回此对象。
//下面就是将data属性注入到vue实例中
Object.defineProperty(this,key,{
configurable:true,
enumerable:true,
set(newValue){
if(data[key]===newValue){
return
}else{
data[key]=newValue;
}
},
get(){
return data[key];
}
})
}