写进去data
const vm = new Vue({
data() {
return {
name: '坤坤',
age: 38,
address: {
detail: '老北京冰棍'
}
}
}
})
然后js
// 观察者
import { observe } from './observe/index.js'
function Vue(options) {
this._init(options)
}
// 初始化配置项
Vue.prototype._init = function (options) {
const vm = this
vm.$options = options
// 初始化状态
initStatus(vm)
}
function initStatus(vm) {
const opts = vm.$options
// 有data属性执行初始化data
if (opts.data) {
initData(vm)
}
}
// 初始化data
function initData(vm) {
let data = vm.$options.data
// 判断如果data是函数就执行并且绑定到实例中
data = typeof data === 'function' ? data.call(vm) : data
// 将data挂在到vm实例中用_data表示
vm._data = data
// 将vm._data.name 代理 到 vm.name 中
for (let key in data) {
proxy(vm, '_data', key);
}
// 观察者,所有数据
observe(data)
}
// 将vm._data.name 代理 到 vm.name 方法
function proxy(vm, target, key) {
Object.defineProperty(vm, key, {
get() {
return vm[target][key]
},
set(newValue) {
vm[target][key] = newValue
}
})
}
export default Vue
export function observe(data) {
// 劫持对象,如果data不是对象或者为空中止
if (typeof data !== 'object' || data == null) {
return
}
return new Observer(data)
}
class Observer {
constructor(data) {
this.walk(data)
}
walk(data) {
// 给每一个data的key双向绑定
Object.keys(data).forEach(key => defineReactive(data, key, data[key]))
}
}
export function defineReactive(target, key, value) {
// 如果data中有object,递归执行绑定
observe(value)
Object.defineProperty(target, key, {
get() {
return value
},
set(newValue) {
if (value == newValue) return
value = newValue
}
})
}
效果
const vm = new Vue({
data() {
return {
name: '坤坤',
age: 38,
address: {
detail: '老北京冰棍',
money: 1
}
}
}
})
console.log(vm)
console.log(vm.name)
vm.age = 13
console.log(vm.age)
console.log(vm.address.detail)
vm.address.money = 2
console.log(vm.address.money)