数据代理
响应式依赖于vue-next下面的reactivity包,这个包是独立于其他的包
-src文件夹
-vue3文件夹
-index.js(同级)
-index.html
-shared文件夹
-utils.js
-reactivity文件夹
-index.js
-reactive.js
-mutableHandle.js
-webpack.config.js
-package.json
index.js(同级)
import { reactive } from "./vue3/reactive"
// reactive =>es6 的proxy代理API
const state = reactive({
name:'小笨蛋',
age:21,
info:{
job:'student',
students:[
{
id:1,
name:'小'
},
{
id:2,
name:'笨'
}
]
},
hobby:['piano','film']
});
state.name;//响应式获取:小笨蛋
state.name = '元元儿'///响应式设置:name=元元儿
//因为只有第一层代理,所以取到里面的东西不行,比如:
//state.info.job
index.js
//导入reactive
import {reactive} from "./reactive";
export {
reactive
}
reactive.js
//导入shared下面的工具函数
import { isObject } from "../shared/utils"
import { mutableHandle } from "./mutableHandle"
/*
希望有一个函数去处理响应式的代理的转换
*/
function reactive(target) {
//target 是一个对象
/*传入两个参数
target
mutableHandle
*/
return createReactiveObject(target, mutableHandle);//执行的结果是observer 是一个被代理后的对象
//mutableHandle里面有很多东西,创建一个文件单独管理
}
function createReactiveObject(target, baseHandler) {
if (!isObject(target)) {
return target
}
const observer = new Proxy(target, baseHandler);//此处还需要关注target到底是不是一个对象,如果不是对象不需要代理
//所以在vue3下面创建一个shared文件夹 里面的utils.js文件判断
return observer;
}
//导出reactive
export {
reactive
}
utils.js
function isObject(value) {
return typeof value === 'object' && value !== null;
}
//target对象中到底存不存在key值,如果没有就是新增的
function hasOwnProperty(target, key) {
return Object.prototype.hasOwnProperty.call(target, key);
}
function isEqual(newValue, oldValue) {
return newValue === oldValue;
}
export {
isObject,
hasOwnProperty,
isEqual
}
mutableHandle.js
//handler下面有很多方法,为了将handler的方法能够单独的去完成
import { isObject } from "../shared/utils"
import { reactive } from "./reactive";
import {hasOwnProperty,isEqual} from "../shared/utils"
//可以去创建一个createGetter等方法
const get = createGetter();
const set = createSetter();
//刚开始说了get和set都含有几个参数,所以返回的时候也需要包含这些参数
function createGetter() {
return function get(target, key, receiver) {
const res = Reflect.get(target, key, receiver);
console.log('响应式获取' + target[key]);
//因为需要获取到对象里面的对象的属性
if (isObject(res)) {
return reactive(res);
}
return res;//等于return target[key]
}
}
function createSetter() {
return function set(target, key, value, receiver) {
const res = Reflect.set(target, key, value, receiver);
//则需要判断,在utils.js中
const isKeyExist = hasOwnProperty(target,key);
const oldValue = target[key];
//console.log('响应式设置' + key + '=' + value + ',' + target.length);//在设置的时候,需要把握是新增还是修改
//则需要判断,在utils.js中
if(!isKeyExist){
console.log('响应式新增:'+value);
}else if(!isEqual(value,oldValue)){//多个地方需要到这个判断
console.log('响应式修改:'+key + '='+vaule);
}
return res;
}
}
const mutableHandler = {
get,
set
}
export {
mutableHandler
}
webpack.config.js
const HtmlWebpackPlugin = require('html-webpack-plugin');
const { resolve } = require('path');
module.exports = {
entry: './src/index.js',
output: {
path: resolve(__dirname, 'dist'),
filename: 'bundle.js'
},
plugins: [
new HtmlWebpackPlugin({
template: resolve(__dirname, 'src/index.html')
})
],
devServer: {
contentBase: './'
}
}
菜鸟学习源码中,如有错误,请各位大佬指出,谢谢大家~~QAQ