Vue3.0源码学习之一手撸reactive

文章仅用于记录自己在学习vue3.0过程中的理解,将分为多个版本来解读核心源码,有问题请多看vue3官方文档vue3.0-- 传送门

如果想要测试下面代码,直接通过官方cli 搭建vue3
把不要的东西删除之后的项目结构

使用cli大家之后的项目结构

main.js
	// import {reactive,effect,computed,ref } from '@vue/reactivity' //官方包,可以用作自己手撸代码的标准
	// 引入自己的包,手写reactive 分析其原理
	import { reactive, effect, computed, ref } from './assets/js/index'
	
	// 注:reactive 仅代理对象类型数据
	// 例:
	const state = reactive({name:'god',age:'20',arr:[1,2,3]})
	// reactive 执行后,将会由 Proxy进行代理和拦截 
	// 试验一:
	// console.log(state) 
	// 结果:
	// Proxy {name: "god", age: "20"}
	
	// 试验二:
	// console.log(state.name) // 对代理对象取值
	// state.name='fery' // 对代理对象设置值
	// 结果:
	// 	用户对这个对象取值了 {name: "god", age: "20"} name
	//  当前操作为修改操作,对应的key为  name
	
	// 试验三:
	// 代理的对象增加复杂程度增加了arr
	 state.arr.push(4)
	// 结果:
	// 用户对这个对象取值了 {name: "god", age: "20", arr: Array(3)} arr
	// 用户对这个对象取值了 (3) [1, 2, 3] push
	// 用户对这个对象取值了 (3) [1, 2, 3] length
	// 当前为属性新增操作 3
	state.arr[0]=1 // 设置一样值的时候提
	// 用户对这个对象取值了 {name: "god", age: "20", arr: Array(3)} arr

reactive.js
	import { isObject } from "./utils" // 工具类函数
	import { mutableHandler } from "./mutableHandler" // 抽离的get,set
	export function reactive(target){
		// 使用高阶函数,创建一个Proxy代理	 
		// mutableHandler 是一个对象,数据格式为{ get(){},set(){} }
		return createReactiveObject(target,mutableHandler)
	}
	
	function createReactiveObject(target,baseHandler){
		// 如果不是对象,就不用代理 
		// 暂不考虑对象已经是被代理过的情况,目前只是基础版
		if(!isObject(target)) return target
		const observed = new Proxy(target,baseHandler)
		return observed
	}
mutableHandler.js
import { reactive } from "./reactive"  //响应式方法,用于递归代理对象中有其它对象
import { hasOwn, isObject,hasChange } from "./utils" // 工具类函数
// 抽离 get,set
const get = createGetter()
const set = createSetter()
export const mutableHandler={
		get,
		set
	}
// 创建get--代理取值	高阶函数返回get
function createGetter(){
		// target, key, receiver  为Proxy 默认给get传的值
		return function get(target, key, receiver){
			//返回取的值 target[key] 用 Reflect 来配合反射
			const res = Reflect.get(target, key, receiver)
			console.log('用户对这个对象取值了', target, key)
			// 如果返回的值依旧是一个对象,则再次进行代理
			if(isObject(res)){
				return reactvie(res)
			}
			return res
		}
	}
// 创建set--代理设置值 高阶函数返回set函数
function createSetter(){
	 // target, key, value, receiver 为Proxy 默认给set传的值
	return function set(target, key, value, receiver){
			const hadKey =hasOwn(target,key) //对象中是否有设置的key
			const oldValue =target[key]  // 旧值
			// 设置值 target[key]=value 用Reflect 来配黑反射
			const res = Reflect.set(target, key, value, receiver)
			// 判断是修改还是新增属性 ,如果修改新值和旧值是一样,不做任何操作
			// 如果有key
			if(!hadKey){
				console.log('当前操作为新增操作,对应的key为',key)
			}else if(hasChange(vaule,oldValue)){
				console.log('当前操作为修改操作,对应的key为',key)
			}
			return res
		}
	}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值