Vue3 — Composition API(其它部分一)

# shallowReactive 与 shallowRef

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

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

  • 什么时候用浅响应式呢?

    • 一般情况下使用ref和reactive即可,都是深度响应式
    • 如果有一个对象数据, 结构比较深, 但变化时只是外层属性变化 ===> shallowReactive
    • 如果有一个对象数据, 后面会产生新的对象来替换 ===> shallowRef
  1. shallowReactive 浅响应式:
    点击按钮时,只更新num.a不可以更新,更新name可以更新;

    <template>
      <h2>shallowReactive</h2>
      <h3>m:{{m}}</h3>
      <hr>
      <button @click="update">点击更新数据</button>
    </template>
    
    <script lang="ts">
    import { defineComponent, shallowReactive } from "vue";
    
    export default defineComponent({
      name: "App",
    
      setup() {
        // 浅响应式
        const m = shallowReactive({
          name: 'balance',
          age: 20,
          num: {
            a: "a",
            b: 2
          }
        })
        const update = () => {  
          // m.name += "+++" 
          m.num.a += "+++"
          console.log(m);
        }
        return {
          m, update
        };
      },
    });
    </script>
    
  2. shallowRef:name、num.a 都不更新

    <template>
      <h2>shallowRef</h2>
      <h3>m:{{ m }}</h3>
      <hr />
      <button @click="update">点击更新数据</button>
    </template>
    
    <script lang="ts">
    import { defineComponent, shallowRef } from "vue";
    
    export default defineComponent({
      name: "App",
    
      setup() {
        const m = shallowRef({
          name: "balance",
          age: 20,
          num: {
            a: "a",
            b: 2,
          },
        });
    
        const update = () => {
          m.value.num.a += "+++";
          m.value.name += "+++"
          console.log(m);
        };
        return {
          m,
          update,
        };
      },
    });
    </script>
    

在这里插入图片描述


# readonly 与 shallowReadonly

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

      <template>
        <h3>readonly:{{state1}}</h3>
        <h3>shallowReadonly:{{state1}}</h3>
        <hr>
        <button @click="update">更新数据</button>
      </template>
      
      <script lang="ts">
      import { defineComponent, reactive, readonly, shallowReadonly } from "vue";
      
      export default defineComponent({
        name: "App",
      
        setup() {
          const state = reactive({
            name: 'balance',
            num: {
              a: "1",
              b: 2
            }
          })
          const state1 = readonly(state)
          const state2 = shallowReadonly(state)
      
          function update() {
            state2.name += "==="
            state2.num.a += "===" // 可以修改
            state1.name += "==="
            state1.num.a += "==="
          }
          return {
            state, state1, update
          };
        },
      });
      </script>
      

      在这里插入图片描述


# toRaw 与 markRaw

toRaw可以将响应式数据还原成普通数据;markRaw进行标记,新增加的数据不再为响应式数据

  • toRaw
    • 返回由 reactivereadonly 方法转换成响应式代理的普通对象。
    • 这是一个还原方法,可用于临时读取,访问不会被代理/跟踪,写入时也不会触发界面更新。
  • markRaw
    • 标记一个对象,使其永远不会转换为代理。返回对象本身
    • 应用场景:
      • 有些值不应被设置为响应式的,例如复杂的第三方类实例或 Vue 组件对象。
      • 当渲染具有不可变数据源的大列表时,跳过代理转换可以提高性能。
      <template>
        <h2>{{ state }}</h2>
        <button @click="testToRaw">测试toRaw</button>
        <button @click="testMarkRaw">测试markRaw</button>
      </template>
      
      <script lang="ts">
      import {
        markRaw,
        reactive, toRaw,
      } from 'vue'
      export default {
        setup() {
          const state = reactive<any>({
            name: 'balance',
            age: 20,
          })
      
          const testToRaw = () => {
            const user = toRaw(state)
            user.age++  // 界面不会更新
            console.log(user); // 普通对象
            console.log(state); // 响应式对象
          }
      
          const testMarkRaw = () => {
            const likes = ['a', 'b']
            // state.likes = likes
            state.likes = markRaw(likes) // likes数组就不再是响应式的了
            setTimeout(() => {
              state.likes[0] += '--'
            }, 1000)
            console.log(state);
          }
      
          return {
            state,
            testToRaw,
            testMarkRaw,
          }
        }
      }
      </script>
      

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值