doc
This commit is contained in:
259
docs/chapter4/03_手写组合API.md
Normal file
259
docs/chapter4/03_手写组合API.md
Normal file
@@ -0,0 +1,259 @@
|
||||
# 3. 手写组合API
|
||||
|
||||
## 1) shallowReactive 与 reactive
|
||||
|
||||
```js
|
||||
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
|
||||
},
|
||||
}
|
||||
|
||||
/*
|
||||
自定义shallowReactive
|
||||
*/
|
||||
function shallowReactive(obj) {
|
||||
return new Proxy(obj, reactiveHandler)
|
||||
}
|
||||
|
||||
/*
|
||||
自定义reactive
|
||||
*/
|
||||
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
|
||||
}
|
||||
|
||||
|
||||
/* 测试自定义shallowReactive */
|
||||
const proxy = shallowReactive({
|
||||
a: {
|
||||
b: 3
|
||||
}
|
||||
})
|
||||
|
||||
proxy.a = {b: 4} // 劫持到了
|
||||
proxy.a.b = 5 // 没有劫持到
|
||||
|
||||
|
||||
/* 测试自定义reactive */
|
||||
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
|
||||
|
||||
```js
|
||||
/*
|
||||
自定义shallowRef
|
||||
*/
|
||||
function shallowRef(target) {
|
||||
const result = {
|
||||
_value: target, // 用来保存数据的内部属性
|
||||
_is_ref: true, // 用来标识是ref对象
|
||||
get value () {
|
||||
return this._value
|
||||
},
|
||||
set value (val) {
|
||||
this._value = val
|
||||
console.log('set value 数据已更新, 去更新界面')
|
||||
}
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
/*
|
||||
自定义ref
|
||||
*/
|
||||
function ref(target) {
|
||||
if (target && typeof target==='object') {
|
||||
target = reactive(target)
|
||||
}
|
||||
|
||||
const result = {
|
||||
_value: target, // 用来保存数据的内部属性
|
||||
_is_ref: true, // 用来标识是ref对象
|
||||
get value () {
|
||||
return this._value
|
||||
},
|
||||
set value (val) {
|
||||
this._value = val
|
||||
console.log('set value 数据已更新, 去更新界面')
|
||||
}
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
/* 测试自定义shallowRef */
|
||||
const ref3 = shallowRef({
|
||||
a: 'abc',
|
||||
})
|
||||
ref3.value = 'xxx'
|
||||
ref3.value.a = 'yyy'
|
||||
|
||||
|
||||
/* 测试自定义ref */
|
||||
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
|
||||
|
||||
```js
|
||||
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
|
||||
},
|
||||
}
|
||||
|
||||
/*
|
||||
自定义shallowReadonly
|
||||
*/
|
||||
function shallowReadonly(obj) {
|
||||
return new Proxy(obj, readonlyHandler)
|
||||
}
|
||||
|
||||
/*
|
||||
自定义readonly
|
||||
*/
|
||||
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
|
||||
}
|
||||
|
||||
/* 测试自定义readonly */
|
||||
/* 测试自定义shallowReadonly */
|
||||
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
|
||||
|
||||
```js
|
||||
/*
|
||||
判断是否是ref对象
|
||||
*/
|
||||
function isRef(obj) {
|
||||
return obj && obj._is_ref
|
||||
}
|
||||
|
||||
/*
|
||||
判断是否是reactive对象
|
||||
*/
|
||||
function isReactive(obj) {
|
||||
return obj && obj._is_reactive
|
||||
}
|
||||
|
||||
/*
|
||||
判断是否是readonly对象
|
||||
*/
|
||||
function isReadonly(obj) {
|
||||
return obj && obj._is_readonly
|
||||
}
|
||||
|
||||
/*
|
||||
是否是reactive或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({})))
|
||||
```
|
||||
Reference in New Issue
Block a user