在使用vue时觉得比较棒的一个是vue的模板语法,还有一个当然就是数据驱动,有时写原生插件时就会想能不能也像vue那样来实现呢?于是对这两个功能进行了分析提取。 (PS: 模板解析的函数是根据vue模板语法逆推新写的,目前实现了v-for、v-if(v-else-if|v-else)、:属性="xxxx"、:class="{xx: true, xxx: false}" 的解析)
vue主要通过两点来实现数据监听
1、使用 Object.defineProprety实现响应式原理
2、 data属性代理到Vue实例上
关于 Object.defineProperty
Object.defineProperty是ES5中定义的方法,通过该方法可以给一个对象上定义一个新属性,或者修改一个对象的现有属性。定义属性主要有两种形式:数据描述符和存取描述符,数据描述符即直接定义属性的value值、是否可删除、是否可遍历等,存取描述符即拦截属性的get()和set()方法并重新定义。vue中用到的就是存取描述符, 循环data返回的对象,把对象的每个属性绑定到vue实例上,并且在绑定时重新定义属性的get和set方法。当我们给属性赋值时触发set方法,这时就可以比较数据是否变化了
案例代码
class Vue {
constructor (opt) {
// 监听数据变化
this.watch = {
zoom: (newVal, oldVal) => {
console.log('zoom数据有变化')
}
}
this.watchData(this.data());
}
// 绑定 监听数据 事件
watchData (obj) {
for (const key in obj) {
if (!obj.hasOwnProperty(key)) continue;
Object.defineProperty(this, key, {
get: () => {
return obj[key]
},
set: newVal => {
let oldVal = obj[key]
obj[key] = newVal
oldVal != newVal && this.watch[key] && this.watch[key](newVal, oldVal)
}
})
}
}
// 对象需要用到的数据
data () {
return {
zoom: 1
}
}
}
仿vue模板语法封装的模板解析函数
贴代码容易被转义,直接上案例模板解析