手写组合API

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
 },
}

/*
自定义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
/*
自定义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
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
/*
判断是否是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({})))

本文章由javascript技术分享原创和收集

推荐阅读

发表评论 (审核通过后显示评论):