美文网首页
VUE3 Composition API

VUE3 Composition API

作者: WangLizhi | 来源:发表于2021-06-10 10:25 被阅读0次

    1. Composition API(常用部分)

    文档:

    https://vue3js.cn/docs/zh/

    setup

    • 新的option, 所有的组合API函数都在此使用, 只在初始化时执行一次
    • 函数如果返回对象, 对象中的属性或方法, 模板中可以直接使用

    ref

    • 作用: 定义一个数据的响应式
    • 语法: const xxx = ref(initValue):
      • 创建一个包含响应式数据的引用(reference)对象
      • js中操作数据: xxx.value
      • 模板中操作数据: 不需要.value
    • 一般用来定义一个基本类型的响应式数据
    <template>
      <h2>{{count}}</h2>
      <hr>
      <button @click="update">更新</button>
    </template>
    
    <script>
    import {
      ref
    } from 'vue'
    export default {
    
      /* 在Vue3中依然可以使用data和methods配置, 但建议使用其新语法实现 */
      // data () {
      //   return {
      //     count: 0
      //   }
      // },
      // methods: {
      //   update () {
      //     this.count++
      //   }
      // }
    
      /* 使用vue3的composition API */
      setup () {
    
        // 定义响应式数据 ref对象
        const count = ref(1)
        console.log(count)
    
        // 更新响应式数据的函数
        function update () {
          // alert('update')
          count.value = count.value + 1
        }
    
        return {
          count,
          update
        }
      }
    }
    </script>
    
    

    3) reactive

    • 作用: 定义多个数据的响应式
    • const proxy = reactive(obj): 接收一个普通对象然后返回该普通对象的响应式代理器对象
    • 响应式转换是“深层的”:会影响对象内部所有嵌套的属性
    • 内部基于 ES6 的 Proxy 实现,通过代理对象操作源对象内部数据都是响应式的
    <template>
      <h2>name: {{state.name}}</h2>
      <h2>age: {{state.age}}</h2>
      <h2>wife: {{state.wife}}</h2>
      <hr>
      <button @click="update">更新</button>
    </template>
    
    <script>
    /* 
    reactive: 
        作用: 定义多个数据的响应式
        const proxy = reactive(obj): 接收一个普通对象然后返回该普通对象的响应式代理器对象
        响应式转换是“深层的”:会影响对象内部所有嵌套的属性
        内部基于 ES6 的 Proxy 实现,通过代理对象操作源对象内部数据都是响应式的
    */
    import {
      reactive,
    } from 'vue'
    export default {
      setup () {
        /* 
        定义响应式数据对象
        */
        const state = reactive({
          name: 'tom',
          age: 25,
          wife: {
            name: 'marry',
            age: 22
          },
        })
        console.log(state, state.wife)
    
        const update = () => {
          state.name += '--'
          state.age += 1
          state.wife.name += '++'
          state.wife.age += 2
        }
    
        return {
          state,
          update,
        }
      }
    }
    </script>
    
    

    shallowRef and shallowReactive

    shallowReactive : 只处理了对象内最外层属性的响应式(也就是浅响应式)

    shallowRef: 只处理了value的响应式, 不进行对象的reactive处理

    什么时候用浅响应式呢?

    一般情况下使用ref和reactive即可
    如果有一个对象数据, 结构比较深, 但变化时只是外层属性变化 ===> shallowReactive
    如果有一个对象数据, 后面会产生新的对象来替换 ===> shallowRef

    <template>
      <div>
        <div>
          <p>{{ counter.name }}</p>
          <button @click="handleCounter">add</button>
        </div>
        <div>
          <p>{{ user.name }}</p>
          <p>{{ user.age }}</p>
          <p>{{ user.hobby }}</p>
          <p>{{ user.child.value }}</p>
          <button @click="updateUser">update</button>
        </div>
      </div>
    </template>
    
    <script lang="ts">
    import { defineComponent, shallowReactive, shallowRef } from 'vue';
    
    export default defineComponent({
      setup() {
        // const counter = shallowRef(0);
        const counter = shallowRef({
          name: 'wanglizhi'
        });
        const user = shallowReactive({
          name: 'wanglizhi',
          age: 18,
          child: {
            id: 1,
            value: '11',
          },
          hobby: ['唱歌', '跳舞'],
        });
    
        function handleCounter() {
          counter.value.name = 'Leo';
          console.log(counter)
        }
    
        function updateUser() {
          // user.name = 'Leo';
          // user.age = 20;
          user.hobby[0] = '吃饭';
          user.child.value = '222';
          console.log(user)
        }
    
        return {
          counter,
          user,
          handleCounter,
          updateUser,
        };
      },
    });
    </script>
    
    <style></style>
    
    

    readonly and shallowReadonly

    readonly:
    深度只读数据
    获取一个对象 (响应式或纯对象) 或 ref 并返回原始代理的只读代理。
    只读代理是深层的:访问的任何嵌套 property 也是只读的。
    shallowReadonly
    浅只读数据
    创建一个代理,使其自身的 property 为只读,但不执行嵌套对象的深度只读转换
    应用场景:
    在某些特定情况下, 我们可能不希望对数据进行更新的操作, 那就可以包装生成一个只读代理对象来读取数据, 而不能修改或删除

    <template>
      <div>
        <div>
          <p>{{ JSON.stringify(state) }}</p>
          <button @click="update">update</button>
        </div>
      </div>
    </template>
    
    <script lang="ts">
    import { defineComponent, readonly, shallowReadonly } from 'vue';
    
    export default defineComponent({
      setup() {
        const state = shallowReadonly({
          name: 'wanglizhi',
          age: 18,
          child: {
            name: 'xiaowang',
            age: 10,
            child: {
              name: 'wang',
              age: 1
            }
          }
        })
    
        function update() {
          state.name = 'Leo';
          state.child.name = 'Leo1';
          state.child.child.name = 'Leo2';
          console.log(state)
        }
        return {
          state,
          update,
        };
      },
    });
    </script>
    
    <style></style>
    
    

    toRaw and markRaw

    toRaw
    返回由 reactive 或 readonly 方法转换成响应式代理的普通对象。
    这是一个还原方法,可用于临时读取,访问不会被代理/跟踪,写入时也不会触发界面更新。
    markRaw
    标记一个对象,使其永远不会转换为代理。返回对象本身
    应用场景:
    有些值不应被设置为响应式的,例如复杂的第三方类实例或 Vue 组件对象。
    当渲染具有不可变数据源的大列表时,跳过代理转换可以提高性能。

    <template>
      <div>
        <h2>toRaw and markRow</h2>
        <div>
          <p>{{ JSON.stringify(state) }}</p>
          <button @click="update">update</button>
        </div>
        <hr>
      </div>
    </template>
    
    <script lang="ts">
    import { defineComponent, toRaw, markRaw, reactive } from 'vue';
    
    export default defineComponent({
      setup() {
        const obj = {
          name: 'wanglizhi',
          age: 18,
          child: {
            name: 'xiaowang',
            age: 10,
            child: {
              name: 'wang',
              age: 1,
            },
          },
        };
        const obj3 = markRaw(obj);
        const state = reactive(obj3);
        const obj2 = toRaw(state);
    
        function update() {
          state.name = 'Leo';
          state.child.name = 'Leo1';
          state.child.child.name = 'Leo2';
          console.log('obj', obj);
          console.log('state', state);
          console.log('obj2', obj2);
          console.log(obj === state)
             console.log(obj2 === obj2)
        }
        return {
          state,
          update,
        };
      },
    });
    </script>
    
    <style></style>
    
    

    toRef 、toRefs、 isRef and unref

    toRef
    为源响应式对象上的某个属性创建一个 ref对象, 二者内部操作的是同一个数据值, 更新时二者是同步的
    区别ref: 拷贝了一份新的数据值单独操作, 更新时相互不影响
    应用: 当要将 某个prop 的 ref 传递给复合函数时,toRef 很有用
    toRefs
    将响应式对象转换为普通对象,其中结果对象的每个 property 都是指向原始对象相应 property 的ref
    isRef
    判断是否为ref
    unref
    如果参数为 ref,则返回内部值,否则返回参数本身。这是 val = isRef(val) ? val.value : val

    <template>
      <div>
        <h2>toRef and toRefs</h2>
        <div>
          <p>{{ JSON.stringify(state) }}</p>
          <button @click="update">update</button>
        </div>
        <hr>
      </div>
    </template>
    
    <script lang="ts">
    import { defineComponent, reactive, toRef, toRefs, isRef, unref } from 'vue';
    
    export default defineComponent({
      setup() {
        const obj = {
          name: 'wanglizhi',
          age: 18,
          child: {
            name: 'xiaowang',
            age: 10,
            child: {
              name: 'wang',
              age: 1,
            },
          },
        };
        const state = reactive(obj);
        const obj2 = toRef(state, 'name');
        const obj3 = toRefs(state)
    
        function update() {
          // state.name = 'Leo';
          // state.child.name = 'Leo1';
          // state.child.child.name = 'Leo2';
          // obj2.value = 'haha'
          obj3.name.value = 'hehe'
          console.log('obj', obj);
          console.log('state', state);
          console.log('obj2', obj2);
          console.log('obj3', obj3);
          console.log(isRef(state))
          // console.log(isRef(obj2))
          // console.log(isRef(obj3))
          // console.log(isRef(obj3.name))
          // console.log(unref(state))
          // console.log(unref(obj2))
        }
        return {
          state,
          update,
        };
      },
    });
    </script>
    
    <style></style>
    
    

    customRef

    相关文章

      网友评论

          本文标题:VUE3 Composition API

          本文链接:https://www.haomeiwen.com/subject/gxkleltx.html