手写Vue3.0 API(B站李南江)

一、Vue3.0响应式

  1.在Vue2.x中是通过defineProperty来实现响应式数据的

  2.在Vue3.x中是通过Proxy来实现响应式数据的

  

let obj = { name: 'lng', age: 18 }     // 原始对象

let state = new Proxy(obj, {    // 拦截原始对象进行操作
  get (obj, key) {
    console.log(obj, key)  // { name: 'lng', age: 18 }  "name"
    return obj[key]
  },
  set (obj, key, value) {
    obj[key] = value
    console.log(obj, key, value)    //  {name: "jz", age: 18} "name" jz
    // return true   // 更新UI
  }
})

console.log(state.name) // get--lng
state.name = 'jz'     // set

 

二、shallowReactive和shallowRef

function shallowRef(val) {  // shallowRef本质还是shallowReactive
    return shallowReactive({ value: val })
}
  
function shallowReactive(obj) {
    return new Proxy(obj, {
        get(obj, key) {
            return obj[key]
        },
        set(obj, key, value) {
            obj[key] = value
            console.log('更新UI界面')
            return true
        }
    })
}
  
  let obj = {
    a: 'a',
    gf: {
      b: 'b',
      f: {
        c: 'c',
        s: {
          d: 'd'
        }
      }
    }
  }
  /*
  let state = shallowReactive(obj)
  // state.a = 1 // 更新UI界面
  state.gf.b = 2
  state.gf.f.c = 3
  state.gf.f.s.d = 4
  */
  let state = shallowRef(obj)
  // state.value.a = 1
  // state.value.gf.b = 2
  // state.value.gf.f.c = 3
  // state.value.gf.f.s.d = 4
  state.value = {
    a: '1',
    gf: {
      b: '2',
      f: {
        c: '3',
        s: {
          d: '4'
        }
      }
    }
  }
  console.info(state.value)

 

三、reactive和ref

  function ref(val) {   
    return reactive({value: val})   
  }
  
  function reactive(obj) {
    if(typeof obj === 'object') {
      if (obj instanceof Array) {
        // 如果是一个数据,那么取出数组中的每一个元素
        // 判断每一个元素是否又是一个对象,如果又是一个对象,那么也需要包装成 Proxy
        obj.forEach((item, index) => {
          if(typeof item === 'object') {
            obj[index] = reactive(item)
          }
        })
      } else {
        // 如果是一个对象,那么去除对象属性的取值
        // 判断对象属性的取值是否又是一个对象,如果又是一个对象,那么也需要包装成 Proxy
        for (let key in  obj) {
          let item = obj[key]
          if (typeof item === 'object') {
            obj[key] = reactive(item)
          }
        }
      }
    } else {
      console.warn(`${JSON.stringify(obj)} is not object`)
    }
    return new Proxy(obj, {
      get(obj, key) {
        return obj[key]
      },
      set(obj, key, value) {
        obj[key] = value
        console.log('更新UI界面')
        return true
      }
    })
  }
  
  let obj = {
    a: 'a',
    gf: {
      b: 'b',
      f: {
        c: 'c',
        s: {
          d: 'd'
        }
      }
    }
  }
  
  // let state = reactive(obj)
  // state.a = 1 // 更新UI界面
  // state.gf.b = 2 // 更新UI界面
  // state.gf.f.c = 3 // 更新UI界面
  // state.gf.f.s.d = 4 // 更新UI界面
  
  let arr = [{id: 1, name: '鲁班'}, {id: 2, name: '虞姬'}]
  let state = reactive(arr)
  state[0].name = '张三' // 更新UI界面
  state[0].age = 666 // 更新UI界面
  state[1].id = 3 // 更新UI界面

 

四、readonly和shallowReadonly

  function readonly(obj) {  // readonly递归只读
    if(typeof obj === 'object') {
      if (obj instanceof Array) {
        // 如果是一个数据,那么取出数组中的每一个元素
        // 判断每一个元素是否又是一个对象,如果又是一个对象,那么也需要包装成 Proxy
        obj.forEach((item, index) => {
          if(typeof item === 'object') {
            obj[index] = readonly(item)
          }
        })
      } else {
        // 如果是一个对象,那么去除对象属性的取值
        // 判断对象属性的取值是否又是一个对象,如果又是一个对象,那么也需要包装成 Proxy
        for (let key in  obj) {
          let item = obj[key]
          if (typeof item === 'object') {
            obj[key] = readonly(item)
          }
        }
      }
    } else {
      console.warn(`${JSON.stringify(obj)} is not object`)
    }
    return new Proxy(obj, {
      get(obj, key) {
        return obj[key]
      },
      set(obj, key, value) {
        console.warn(`${key}是只读的,不能赋值`)
        return true
      }
    })
  }
  
  function shallowReadonly(obj) {   // shallowReadonly只读,但不是递归只读
  
    return new Proxy(obj, {
      get(obj, key) {
        return obj[key]
      },
      set(obj, key, value) {
        console.warn(`${key}是只读的,不能赋值`)
      }
    })
  }
  
  let obj = {
    a: 'a',
    gf: {
      b: 'b',
      f: {
        c: 'c',
        s: {
          d: 'd'
        }
      }
    }
  }
  
  // let state = shallowReadonly(obj)
  // state.a = 1 // a是只读的,不能赋值
  // state.gf.b = 2 // 空行
  
  let state1 = readonly(obj)
  state1.a = 1 // a是只读的,不能赋值
  state1.gf.b = 2 // b是只读的,不能赋值

 

reactive, ref

posted @ 2020-12-23 11:23  惊蛰丶  阅读(183)  评论(0编辑  收藏  举报