实现 readonly 只读功能
readonly
顾名思义就是一个只读功能,不能修改
单测
1 2 3 4 5 6 7 8 9 10
| import { readonly } from '../reactive' describe('readonly', () => { it('happy path', () => { const original = { foo: 1, bar: { baz: 2 } } const wrapped = readonly(original) expect(wrapped).not.toBe(original) expect(wrapped.foo).toBe(1) }) })
|
实现单测
1 2 3 4 5 6 7 8 9 10 11 12 13
| ... export const readonly = raw => { return new Proxy(raw, { get: (target, key) => { const res = Reflect.get(target, key) return res }, set: (target, key, value) => { return true } }) }
|
重构代码抽离到公共文件
1 2 3
| ... export const isObject = val => val !== null && typeof val === 'object'
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57
| ... import { isObject } from '../shared/index' import { mutableHandler, readonlyHandler } from './baseHandlers'
export const createReactiveObject = (raw, baseHandlers) => { if (!isObject(raw)) { console.warn(`target ${raw} 必须是一个对象`) return raw } return new Proxy(raw, baseHandlers) }
export const reactive = raw => createReactiveObject(raw, mutableHandler) export const readonly = raw => createReactiveObject(raw, readonlyHandler) ```k
```ts
... import { track, trigger } from './effect' import { isObject, extend } from '../shared/index' import { reactive, readonly } from './reactive'
export const createGetter = (isReadonly = false) => { return function get(target, key) { const res = Reflect.get(target, key) if (isObject(res)) { return isReadonly ? readonly(res) : reactive(res) } if (!isReadonly) { track(target, key) } return res } }
export const createSetter = () => { return function set(target, key, value) { const res = Reflect.set(target, key, value) trigger(target, key) return res } }
const get = createGetter() const set = createSetter() const readonlyGet = createGetter(true)
export const readonlyHandler = { get: readonlyGet, set(target, key) { console.warn(`${key} set失败,因为target是readonly`, target) return true } }
|