文章仅用于记录自己在学习vue3.0过程中的理解,将分为多个版本来解读核心源码,有问题请多看vue3官方文档vue3.0-- 传送门
如果想要测试下面代码,直接通过官方cli 搭建vue3
把不要的东西删除之后的项目结构
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
}
}