3. 手写组合API
1) shallowReactive 与 reactive
const reactiveHandler = {
get (target, key) {
if (key==='_is_reactive') return true
return Reflect.get(target, key)
},
set (target, key, value) {
const result = Reflect.set(target, key, value)
console.log('数据已更新, 去更新界面')
return result
},
deleteProperty (target, key) {
const result = Reflect.deleteProperty(target, key)
console.log('数据已删除, 去更新界面')
return result
},
}
function shallowReactive(obj) {
return new Proxy(obj, reactiveHandler)
}
function reactive (target) {
if (target && typeof target==='object') {
if (target instanceof Array) {
target.forEach((item, index) => {
target[index] = reactive(item)
})
} else {
Object.keys(target).forEach(key => {
target[key] = reactive(target[key])
})
}
const proxy = new Proxy(target, reactiveHandler)
return proxy
}
return target
}
const proxy = shallowReactive({
a: {
b: 3
}
})
proxy.a = {b: 4}
proxy.a.b = 5
const obj = {
a: 'abc',
b: [{x: 1}],
c: {x: [11]},
}
const proxy = reactive(obj)
console.log(proxy)
proxy.b[0].x += 1
proxy.c.x[0] += 1
2) shallowRef 与 ref
function shallowRef(target) {
const result = {
_value: target,
_is_ref: true,
get value () {
return this._value
},
set value (val) {
this._value = val
console.log('set value 数据已更新, 去更新界面')
}
}
return result
}
function ref(target) {
if (target && typeof target==='object') {
target = reactive(target)
}
const result = {
_value: target,
_is_ref: true,
get value () {
return this._value
},
set value (val) {
this._value = val
console.log('set value 数据已更新, 去更新界面')
}
}
return result
}
const ref3 = shallowRef({
a: 'abc',
})
ref3.value = 'xxx'
ref3.value.a = 'yyy'
const ref1 = ref(0)
const ref2 = ref({
a: 'abc',
b: [{x: 1}],
c: {x: [11]},
})
ref1.value++
ref2.value.b[0].x++
console.log(ref1, ref2)
3) shallowReadonly 与 readonly
const readonlyHandler = {
get (target, key) {
if (key==='_is_readonly') return true
return Reflect.get(target, key)
},
set () {
console.warn('只读的, 不能修改')
return true
},
deleteProperty () {
console.warn('只读的, 不能删除')
return true
},
}
function shallowReadonly(obj) {
return new Proxy(obj, readonlyHandler)
}
function readonly(target) {
if (target && typeof target==='object') {
if (target instanceof Array) {
target.forEach((item, index) => {
target[index] = readonly(item)
})
} else {
Object.keys(target).forEach(key => {
target[key] = readonly(target[key])
})
}
const proxy = new Proxy(target, readonlyHandler)
return proxy
}
return target
}
const objReadOnly = readonly({
a: {
b: 1
}
})
const objReadOnly2 = shallowReadonly({
a: {
b: 1
}
})
objReadOnly.a = 1
objReadOnly.a.b = 2
objReadOnly2.a = 1
objReadOnly2.a.b = 2
4) isRef, isReactive 与 isReadonly
function isRef(obj) {
return obj && obj._is_ref
}
function isReactive(obj) {
return obj && obj._is_reactive
}
function isReadonly(obj) {
return obj && obj._is_readonly
}
function isProxy (obj) {
return isReactive(obj) || isReadonly(obj)
}
console.log(isReactive(reactive({})))
console.log(isRef(ref({})))
console.log(isReadonly(readonly({})))
console.log(isProxy(reactive({})))
console.log(isProxy(readonly({})))