zoukankan      html  css  js  c++  java
  • 手写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

  • 相关阅读:
    Java 获取指定日期的方法总结
    【Struts2+Spring3+Hibernate3】SSH框架整合实现CRUD_1.0
    struts2标签Iterator迭代时获取下标
    【转】svn 修改log信息
    pppoe移植到arm上 2.0
    镜像制作
    proc增加节点的一个例子
    libcurl库的使用
    sed & awk Manuals
    用一个函数保存文件
  • 原文地址:https://www.cnblogs.com/jing-zhe/p/14177581.html
Copyright © 2011-2022 走看看