Vue内部运行机制剖析-模拟Vue的响应式原理

  • Vue.js 是一款 MVVM 框架:核心实现就是响应式系统;理解这里的响应式指的是数据的响应式

模拟视图更新

  • 使用Object.defineProperty 封装方法
function cb(val) { /* 渲染视图 */
	console.log("视图更新啦~");
}

function defineReactive(obj, key, val) {
	Object.defineProperty(obj, key, {
		enumerable: true,
		/* 属性可枚举 */
		configurable: true,
		/* 属性可被修改或删除 */
		get: function reactiveGetter() {
			console.log(val)
			return val; /* 实际上会依赖收集,下一小节会讲 */
		},
		set: function reactiveSetter(newVal) {
			if (newVal === val) return;
			console.log(newVal)
		}

	});
}
上面的Object.defineProperty()用法解读
  • 功能:方法会直接在一个对象上定义一个新属性,或者修改一个对象的现有属性, 并返回这个对象。如果不指定configurable, writable, enumerable ,则这些属性默认值为false,如果不指定value, get, set,则这些属性默认值为undefined
  • 语法:Object.defineProperty(obj, prop, descriptor)
    • obj: 需要被操作的目标对象
    • prop: 目标对象需要定义或修改的属性的名称
    • descriptor: 将被定义或修改的属性的描述符
var obj = new Object();

Object.defineProperty(obj, 'name', {
    configurable: false,
    writable: true,
    enumerable: true,
    value: '张三'
})

console.log(obj.name)  //张三
另一种相似的Object.defineProperties()
  • 功能:方法直接在一个对象上定义一个或多个新的属性或修改现有属性,并返回该对象。
  • 语法: Object.defineProperties(obj, props)
    • obj: 将要被添加属性或修改属性的对象
    • props: 该对象的一个或多个键值对定义了将要为对象添加或修改的属性的具体配置
var obj = new Object();
Object.defineProperties(obj, {
    name: {
        value: '张三',
        configurable: false,
        writable: true,
        enumerable: true
    },
    age: {
        value: 18,
        configurable: true
    }
})

console.log(obj.name, obj.age) // 张三, 18

封装一层observer

  • 这个函数传入一个 value(需要「 响应式」化 的对象),通过遍历所有属性的方式对该对象的每一个属性都通过defineReactive方法
function cb(val) { /* 渲染视图 */
	console.log("调用set方法视图更新啦~");
}

function defineReactive(obj, key, val) {
	Object.defineProperty(obj, key, {
		enumerable: true,
		/* 属性可枚举 */
		configurable: true,
		/* 属性可被修改或删除 */
		get: function reactiveGetter() {
			console.log("调用get方法,打印值为:"+val);
			return val; 
		},
		set: function reactiveSetter(newVal) {
			if (newVal === val) return;
			cb(newVal)
		}

	});
}

function observer(value) {
	if (!value || (typeof value !== 'object')) {
		return;
	}
	Object.keys(value).forEach((key) => {
		defineReactive(value, key, value[key]);
	});
}

// 定义一个对象
var aobj = {
	'name': 'wyh',
	'sex': 'man',
};

// 观察aobj
observer(aobj)


// 查看数据调用get方法
aobj.name

// 修改调用set 方法
aobj.name = '123';

以上浏览器的打印:
在这里插入图片描述

模拟封装成VUE的方式

  • 在 Vue 的构造函数中,对 的 进行处理,这里的 想必大家很熟悉,就是平时我们在写 Vue 项目时组件中的 属性(实际上是一个函数,这里当作一个对象来简单处理)。
class Vue {
	/* Vue 构造类 */
	constructor(options) {
		console.log(options)
		this._data = options.data;
		observer(this._data);
	}
}

let vue = new Vue({
	data: {
		test: "I am test."
	},
	methods:"function list"
});
// 修改test的值 等价于vue的this.XXX=XXX;
vue._data.test = "hello,world."; /* 视图更新啦~ */

// 打印值
console.log(vue._data.test)

在这里插入图片描述

此文为最近学习小册“剖析VueJS内部运行机制”的学习总结;

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Vue.js 是一款轻量级的前端框架,采用 MVVM 架构,本质上是一个响应式的系统,通过观察者模式的方式,实现了数据与视图之间的双向绑定。Vue.js 的实现原理主要包括以下几个方面: 1. 数据响应式 Vue.js 基于 ES5 的 Object.defineProperty() 方法,实现了双向绑定的核心机制。当一个 Vue 实例被创建后,Vue 会遍历这个实例的 data 对象属性,将这些属性通过 Object.defineProperty() 方法转化为 getter 和 setter,并在 getter 方法中建立一个依赖收集的机制,记录所有依赖这个属性的 Watcher,当属性值发生变化时,依赖收集器会通知相关的 Watcher, Watcher 会更新视图。 2. 模板解析与生成虚拟 DOM Vue.js 的模板采用了类 HTML 的语法结构,Vue 的编译器会将其转换成虚拟 DOM,并将其与 Vue 实例进行绑定,当 Vue 实例数据发生变化时,Vue 会重新生成虚拟 DOM,并与之前的虚拟 DOM 进行比较,得出需要更新的部分,最终通过真实 DOM 更新视图。这个过程需要用到 diff 算法,用来尽可能地复用页面已有的元素,减少重绘重排的开销。 3. 组件化开发 Vue.js 将页面抽象成一个一个的组件,每个组件都有自己的作用域、模板、数据等属性。当组件数据发生变化时,Vue.js 会重新生成组件对应的虚拟 DOM,并对比之前的虚拟 DOM,最终只更新变化的部分,通过这种方式提供了组件级别的性能优化。 总之,Vue.js 实现了一种基于数据响应式机制,通过虚拟DOM进行DOM操作,最终生成所需要显示的页面。Vue.js组件化开发的方式可以提高代码的可维护性和可扩展性,框架底层的实现优化可以提高页面的性能。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值