目标

  1. it('nested reactive', () => {
  2. const original = {
  3. nested: {
  4. foo: 1,
  5. },
  6. array: [{ bar: 2 }],
  7. };
  8. const observed = reactive(original);
  9. expect(isReactive(observed.nested)).toBe(true);
  10. expect(isReactive(observed.array)).toBe(true);
  11. expect(isReactive(observed.array[0])).toBe(true);
  12. });
  1. it('nested readonly', () => {
  2. const original = { foo: 1, bar: { baz: 2 } };
  3. const wrapped = readonly(original);
  4. expect(isReadonly(wrapped.bar)).toBe(true);
  5. expect(isReadonly(original.bar)).toBe(false);
  6. });

实现

只需要看看 get 中返回出去的 res 是不是 Object,如果是再次调用 reactive 转换成响应性对象。
同理 readonly,只需要再判断不是 isReadonly,而再次调用 readonly 转换

  1. function createGetter(isReadonly = false) {
  2. return function get(target, key) {
  3. if (key === ReactiveFlags.IS_REACTIVE) {
  4. return !isReadonly;
  5. } else if (key === ReactiveFlags.IS_READONLY) {
  6. return isReadonly;
  7. }
  8. const res = Reflect.get(target, key);
  9. // 判断是不是 Object 可以抽离到公共工具方法
  10. if (isObject(res)) {
  11. return isReadonly ? readonly(res) : reactive(res);
  12. }
  13. if (!isReadonly) {
  14. track(target, key);
  15. }
  16. return res;
  17. };
  18. }
  1. export const isObject = (val) => {
  2. return val !== null && typeof val === 'object';
  3. };