目录结构:
一:安装如下插件:
"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')
效果: