Vue深入-23【Vue3.0源码重写『数据劫持』】

(1).了解VUE3源码管理方式、独立使用reactivity、搭建项目

1.了解VUE3源码管理方式、独立使用reactivity

npm init -y
npm i @vue/reactivity -D

src

index.js

这样就变成了响应式data 是基于proxy做的代理

import {reactive} from '@vue/reactivity';
const state = reactive({
    name:'zza',
    info:{
        job:'teacher',
        student:[
            {
                id:1,
                name:'小张'
            }
        ]
    },
    hobby:['pinao','travel','film']
})

npm i webpack@4.44.1 webpack-cli@3.3.12 webpack-dev-server@3.11.0
yarn add html-webpack-plugin@4.4.1

webpack.config.js

const path = require('path'),
      HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports={
    entry:'./src/index.js',
    output:{
        filename:'bundle.js',
        path:path.resolve(__dirname,'dist')
    },
    devtool:'source-map',
    resolve:{
        modules:[path.resolve(__dirname,''),path.resolve(__dirname,'node_modules')]
    },
    plugins:[
        new HtmlWebpackPlugin({
            template:path.resolve(__dirname,'public/index.html')
        })
    ]
}      

   

package.json

"scripts": {
    "dev":"webpack-dev-server",
    "build":"webpack"
  },

index.html

npm run dev

(2).认识Proxy与Reflect、实现基本得数据代理

src/vue3

reactivity/index.js

import {reactive} from 'src/vue3/reactivity'
const state = reactive({
    name:'zza',
    info:{
        job:'teacher',
        student:[
            {
                id:1,
                name:'小张'
            }
        ]
    },
    hobby:['pinao','travel','film']
})
state.name="lgx"

reactive.js

i

import {isObject} from '../shared/utils'
import {mutableHandler} from './mutableHandler'
function reactive(target){

    return createReactiveObject(target,mutableHandler);
}
function createReactiveObject(target,baseHandle){
    if(!isObject(target)){
        return target
    }
    const observer = new Proxy(target,baseHandle);
    return observer;
}
export{
    reactive
}

shared文件

utils.js

function isObject(value){
    return typeof value === 'object' && value !==null;
}
export{
    isObject
}

mutableHandler.js

const get = createGetter(),
      set = createSetter();
function createGetter(){
    return function get(target,key,receiver){
        const res = Reflect.get(target,key,receiver);
        console.log('响应式获取'+target[key]);
        return res;
    }
}      
function createSetter(){
    return  function set(target,key,value,receiver){
        const res = Reflect.set(target,key,value,receiver);
        console.log('响应式设置'+key+'='+value);
        return res;
    }
}
const mutableHandler={
    get,set
}
export {
    mutableHandler
}

reactive.js

import {isObject} from '../shared/utils'
import {mutableHandler} from './mutableHandler'
function reactive(target){

    return createReactiveObject(target,mutableHandler);
}
function createReactiveObject(target,baseHandle){
    if(!isObject(target)){
        return target
    }
    const observer = new Proxy(target,baseHandle);
    return observer;
}
export{
    reactive
}

index.js

state.name="lgx"

(3).递归操作、新增与修改得区分

对象中的对象的操作是不可以的

state.hobby[0] = 'conding'

mutableHandler.js

import {isObject} from '../shared/utils';
import {reactive} from './reactivity';
import {hasOwnProperty,isEaual} from '../shared/utils'

const get = createGetter(),
      set = createSetter();
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;
    }
}      
function createSetter(){
    return  function set(target,key,value,receiver){
        const isKeyExist = hasOwnProperty(target,key),
              oldValue = target[key],
              res = Reflect.set(target,key,value,receiver);
          
        if(!isKeyExist){
            console.log('响应式新增'+value);
        }else if(!isEaual(value,oldValue)){
            console.log('响应式修改'+key+'='+value);
        }      
        
        return res;
    }
}
const mutableHandler={
    get,set
}
export {
    mutableHandler
}

utils

function isObject(value){
    return typeof value === 'object' && value !==null;
}
function hasOwnProperty(target,key){
    return Object.prototype.hasOwnProperty.call(target,key)
}
function isEaual(newValue,oldValue){
    return newValue === oldValue
}
export{
    isObject,hasOwnProperty,isEaual
}

index.js

import {reactive} from 'src/vue3/reactivity'
const state = reactive({
    name:'zza',
    info:{
        job:'teacher',
        student:[
            {
                id:1,
                name:'小张'
            }
        ]
    },
    hobby:['pinao','travel','film']
})
state.name="lgx"
state.hobby[0] = 'conding'

(3).总结

vue,proxy代理底层就是重写了get set方法,传入道proxy中,set中判断是否存在,和是否与之前的值一致,来鉴别新增和修改操作。对数组操作方法也有了响应,性能更高了,不是一上来全部递归劫持

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值