手写vue-数据拦截

目录结构:

 

一:安装如下插件:

 "dependencies": {
    "html-webpack-plugin": "^3.2.0",
    "webpack": "^4.42.0",
    "webpack-cli": "^3.3.11",
    "webpack-dev-server": "^3.10.3"
  }

:配置webpack.config.js

const path = require('path');
const HtmlWebpackPlugins = require("html-webpack-plugin") ;
module.exports= {
    //模块入口
    entry:'./src/index.js',
    output:{
        filename:'bundle.js',
        path:path.resolve(__dirname,'dist')
    },
    resolve:{
        //模块查找先找source,再找node-modules
        modules:[path.resolve(__dirname,'source'),path.resolve(__dirname,'node_modules')]
    },
    plugins:[
       new HtmlWebpackPlugins({
        template:path.resolve(__dirname,'public/index.html')
       })
    ]
}

三:source/vue/index.js:(项目中实际要找的vue文件)

import { initState } from "./observe";
function Vue(options){
this._init(options)
}
Vue.prototype._init = function(options){
let vm = this;
//把options放在vm的实例对象中
vm.$options = options;

//初始化
initState(vm);
}
export default Vue;

:observe/index.js

import Observer from './Observer'

export function initState(vm){
    let opts = vm.$options;
    if(opts.data){
        initData(vm)
    }
}

function initData(vm){
  let data = vm.$options.data;
  data = vm._data = typeof data === 'function' ? data.call(vm) : data || {};
  //将data中每个数据重新代理
  for (const i in data) {
    Proxy(vm,"_data",i)
  }
  console.log(vm._data,'vm._data')
  //数据拦截
  observe(vm._data);
}
//数据拦截观察
export function observe(data){
  if(typeof(data) !== 'object' || data == null){
      return;
  }

  //如果是对象就监听
  return new Observer(data)
}

function Proxy(vm,source,key){
     Object.defineProperty(vm,key,{
        get(){
            return vm[source][key]
        },
        set(newval){
            vm[source][key] = newval
        }
     })
}

五:实现数据响应式的核心文件(Observe.js)

import {observe} from './index'
//观察类
class Observer{
    constructor(data){
      this.walk(data)
    }
    walk(data){
        let keys = Object.keys(data);
        for(let i=0;i<keys.length;i++){
            let key = keys[i];
            let value = data[key];

            //属性-------》响应式
            definReactive(data,key,value)
        }
    }
}

// 定义响应式属性的核心方法(对属性进行拦截处理)
function definReactive(data,key,value){
    // 若value还是对象
    observe(value);
    // debugger
    Object.defineProperty(data,key,{
        //在data上动态添加key
        get(){
            console.log('get.........')
            return value
        },
        set(newvalue){
            console.log('set.........')
            if(value == newvalue) return;
            value = newvalue;
        }
    })
}


export default Observer;

六:主入口文件:(src/index.js)

import Vue from 'vue'

let vm = new Vue({
    el:"#app",
    data:{
        msg:'holle',
        father:{
            name:'jack'
        }
    }
})

// console.log(vm._data.msg)
console.log(vm.msg,'vm1111')
vm.msg = 'holle vue'
console.log(vm.msg,'vm111')

效果:

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值