小言_互联网的博客

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

546人阅读  评论(0)

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

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


  
  1. npm init -y
  2. npm i @vue/reactivity -D

src

index.js

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


  
  1. import {reactive} from '@vue/reactivity';
  2. const state = reactive({
  3. name: 'zza',
  4. info:{
  5. job: 'teacher',
  6. student:[
  7. {
  8. id: 1,
  9. name: '小张'
  10. }
  11. ]
  12. },
  13. hobby:[ 'pinao', 'travel', 'film']
  14. })


  
  1. npm i webpack@ 4.44 .1 webpack-cli@ 3.3 .12 webpack-dev-server@ 3.11 .0
  2. yarn add html-webpack-plugin@ 4.4 .1

webpack.config.js


  
  1. const path = require( 'path'),
  2. HtmlWebpackPlugin = require( 'html-webpack-plugin');
  3. module.exports={
  4. entry: './src/index.js',
  5. output:{
  6. filename: 'bundle.js',
  7. path:path.resolve(__dirname, 'dist')
  8. },
  9. devtool: 'source-map',
  10. resolve:{
  11. modules:[path.resolve(__dirname, ''),path.resolve(__dirname, 'node_modules')]
  12. },
  13. plugins:[
  14. new HtmlWebpackPlugin({
  15. template:path.resolve(__dirname, 'public/index.html')
  16. })
  17. ]
  18. }

   

package.json


  
  1. "scripts": {
  2. "dev": "webpack-dev-server",
  3. "build": "webpack"
  4. },

index.html

npm run dev

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

src/vue3

reactivity/index.js


  
  1. import {reactive} from 'src/vue3/reactivity'
  2. const state = reactive({
  3. name: 'zza',
  4. info:{
  5. job: 'teacher',
  6. student:[
  7. {
  8. id: 1,
  9. name: '小张'
  10. }
  11. ]
  12. },
  13. hobby:[ 'pinao', 'travel', 'film']
  14. })
  15. state.name= "lgx"

reactive.js

i


  
  1. import {isObject} from '../shared/utils'
  2. import {mutableHandler} from './mutableHandler'
  3. function reactive(target){
  4. return createReactiveObject(target,mutableHandler);
  5. }
  6. function createReactiveObject(target,baseHandle){
  7. if(!isObject(target)){
  8. return target
  9. }
  10. const observer = new Proxy(target,baseHandle);
  11. return observer;
  12. }
  13. export{
  14. reactive
  15. }

shared文件

utils.js


  
  1. function isObject(value){
  2. return typeof value === 'object' && value !== null;
  3. }
  4. export{
  5. isObject
  6. }

mutableHandler.js


  
  1. const get = createGetter(),
  2. set = createSetter();
  3. function createGetter(){
  4. return function get(target,key,receiver){
  5. const res = Reflect.get(target,key,receiver);
  6. console.log( '响应式获取'+target[key]);
  7. return res;
  8. }
  9. }
  10. function createSetter(){
  11. return function set(target,key,value,receiver){
  12. const res = Reflect.set(target,key,value,receiver);
  13. console.log( '响应式设置'+key+ '='+value);
  14. return res;
  15. }
  16. }
  17. const mutableHandler={
  18. get,set
  19. }
  20. export {
  21. mutableHandler
  22. }

reactive.js


  
  1. import {isObject} from '../shared/utils'
  2. import {mutableHandler} from './mutableHandler'
  3. function reactive(target){
  4. return createReactiveObject(target,mutableHandler);
  5. }
  6. function createReactiveObject(target,baseHandle){
  7. if(!isObject(target)){
  8. return target
  9. }
  10. const observer = new Proxy(target,baseHandle);
  11. return observer;
  12. }
  13. export{
  14. reactive
  15. }

index.js

state.name="lgx"

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

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

state.hobby[0] = 'conding'

mutableHandler.js


  
  1. import {isObject} from '../shared/utils';
  2. import {reactive} from './reactivity';
  3. import {hasOwnProperty,isEaual} from '../shared/utils'
  4. const get = createGetter(),
  5. set = createSetter();
  6. function createGetter(){
  7. return function get(target,key,receiver){
  8. const res = Reflect.get(target,key,receiver);
  9. console.log( '响应式获取'+target[key]);
  10. if(isObject(res)){
  11. return reactive(res);
  12. }
  13. return res;
  14. }
  15. }
  16. function createSetter(){
  17. return function set(target,key,value,receiver){
  18. const isKeyExist = hasOwnProperty(target,key),
  19. oldValue = target[key],
  20. res = Reflect.set(target,key,value,receiver);
  21. if(!isKeyExist){
  22. console.log( '响应式新增'+value);
  23. } else if(!isEaual(value,oldValue)){
  24. console.log( '响应式修改'+key+ '='+value);
  25. }
  26. return res;
  27. }
  28. }
  29. const mutableHandler={
  30. get,set
  31. }
  32. export {
  33. mutableHandler
  34. }

utils


  
  1. function isObject(value){
  2. return typeof value === 'object' && value !== null;
  3. }
  4. function hasOwnProperty(target,key){
  5. return Object.prototype.hasOwnProperty.call(target,key)
  6. }
  7. function isEaual(newValue,oldValue){
  8. return newValue === oldValue
  9. }
  10. export{
  11. isObject,hasOwnProperty,isEaual
  12. }

index.js


  
  1. import {reactive} from 'src/vue3/reactivity'
  2. const state = reactive({
  3. name: 'zza',
  4. info:{
  5. job: 'teacher',
  6. student:[
  7. {
  8. id: 1,
  9. name: '小张'
  10. }
  11. ]
  12. },
  13. hobby:[ 'pinao', 'travel', 'film']
  14. })
  15. state.name= "lgx"
  16. state.hobby[ 0] = 'conding'

(3).总结

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


转载:https://blog.csdn.net/Yesterday_Tomorrow/article/details/114195736
查看评论
* 以上用户言论只代表其个人观点,不代表本网站的观点或立场