实现 readonly 只读功能

shallowReadonly把对象表层转换成readonly类型,当项目太过庞大时,有些数据没必要全部转换响应式对象,从而实现一定的程序优化。

单测

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
//reactivity/__test__/shallowReadonly.spec.ts
import { isReadonly, shallowReadonly } from '../reactive'
describe('shallowReadonly', () => {
test('should not make non-reactive properties reactive', () => {
const props = shallowReadonly({ n: { foo: 1 } })
expect(isReadonly(props)).toBe(true)
expect(isReadonly(props.n)).toBe(false)
})
it('warn then call set', () => {
console.warn = jest.fn()
const user = shallowReadonly({
age: 10
})
user.age = 11
expect(console.warn).toBeCalled()
})
})

实现单测

1
2
//reactivity/reactive.ts
export const shallowReadonly = raw => createReactiveObject(raw, shallowReadonlyHandlers)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
//reactivity/baseHandler.ts
export const createGetter = (isReadonly = false, shallow = false) => {
return function get(target, key) {
if (key === ReactiveFlags.IS_REACTIVE) return !isReadonly
else if (key === ReactiveFlags.IS_READONLY) return isReadonly
const res = Reflect.get(target, key)
if (shallow) return res
/**判断res是否是复杂数据类型 */
if (isObject(res)) return isReadonly ? readonly(res) : reactive(res)
if (!isReadonly) track(target, key)
return res
}
}
const shallowReadonlyGet = createGetter(true, true)
export const shallowReadonlyHandlers = extend({}, readonlyHandler, {
get: shallowReadonlyGet
})