在使用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模板语法封装的模板解析函数

贴代码容易被转义,直接上案例模板解析