• vue3 中 ref、toRef、toRefs 和 reactive 的区别



    一、ref——定义任意类型响应式数据

    • ref 能定义“任何类型”的响应式数据(ref 在 vue3 中指响应式数据)。
    • 参数可以传入任意数据类型。
    • 使用 ref 定义的属性必须通过 .value 的形式才能修改其值。属性的值一旦被修改就会触发模板的重新渲染以显示最新的值。
    • 对于在 setup 返回的 refs(return 出的对象里的属性),因为在模板中访问它们时,它们会被自动浅解包,所以在 template 中使用时无需加 .value

    1、对于在 setup 中手动返回的响应式数据,在 template 中使用时无需加 .value

    例如:

    <template>
      <div>{{ count }}</div>
    </template>
    <script>
      import { ref } from 'vue'
    
      export default {
        setup(props) {
          const count = ref(0)
          // 暴露给 template 的属性,可以直接在 template 中使用
          return {
            count
          }
        }
      }
    </script>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    2、ref 能定义“任何类型”的响应式数据

    如果将 setup 写在 <script> 标签里,则该标签里的脚本都是执行在 setup 里的,并且里面声明数据均会默认地暴露给 template,在 template 中使用时无需加 .value

    例如:

    <template>
      <div>{{ name }} : {{ state.age }}</div>
    </template>
    <script setup>
      import { ref } from 'vue'
    
      // 为基本数据类型添加响应式状态
      const name = ref('Marry')
      // 为复杂数据类型添加响应式状态
      const state = ref({
        age: 18
      })
      // 打印name的值
      console.log(name.value)
      // 打印count的值
      console.log(state.value.age)
    </script>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    二、reactive——定义响应式对象

    • 用来定义“对象类型”的响应式数据。
    • 参数只能传入对象类型,返回一个具有响应式状态的副本。
    • 使用 reactive 定义的属性可以直接使用,不需要加 .value
    • 不要直接解构使用 reactive 定义的响应式对象,否则会造成该对象脱离 ref 响应式。需要用 toRefs 将其转化为响应式数据对象,然后再解构返回。

    例如:

    <template>
      <div>{{ obj.count }}</div>
    </template>
    <script setup>
      import { reactive } from 'vue'
      
      const obj = reactive({
        count: 0
      })
      // 使用 reactive 定义的属性可以直接使用,不需要加 .value
      console.log(state.count)
    </script>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    三、toRef——将一个 reactive 转化为一个 ref

    • 针对一个响应式对象(reactive 封装)的 prop(属性)创建一个 ref,且保持响应式两者 保持引用关系。
    • 接收两个参数:源响应式对象 和 属性名,返回一个 ref 数据。
    • 获取数据值的时候需要加 .value
    • 使用 toRef 转化后生成的 ref 数据如果是引用类型数据时,那么它不是原始数据的拷贝,而是原始数据的引用,改变它的数据也会同时改变原始数据。

    例如:在 setup 中使用父组件传递的 props 数据时,要引用 props 的某个属性,且要保持响应式连接,就必须使用 toRef。

    <template>
      <div>{{ myTitle }}</div>
    </template>
    <script>
      import { defineComponent, toRef } from 'vue'
    
      export default defineComponent({
        props: [title],
        setup (props) {
          // 创建变量myTitle
          const myTitle = toRef(props, 'title')
          console.log(myTitle.value)
          return {
    		myTitle
          }
        }
      })
    </script>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    四、toRefs——将多个 reactive 自动解构为多个 ref

    • toRefs 用于将响应式对象转换为普通对象,其中普通对象的每个属性都是指向原始对象相应属性的 ref,两者保持引用关系。
    • toRefs 常用于 ES6 的解构赋值操作。但是,对一个响应式对象直接解构时,解构后的数据将不再有响应式,而使用 toRefs 可以方便解决这个问题。
    • 获取数据值的时候需要加 .value
    • 使用 toRefs 转化后生成的 ref 数据如果是引用类型数据时,那么它不是原始数据的拷贝,而是原始数据的引用,改变它的数据也会同时改变原始数据。
    • 其作用和 toRef 类似,只不过 toRef 是对一个个属性手动赋值,而 toRefs 是自动解构赋值。
    <template>
      <div>{{ myTitle }}</div>
    </template>
    <script>
      import { defineComponent, toRefs } from 'vue'
    
      export default defineComponent({
        props: [title],
        setup (props) {
          // toRefs 默认使用了解构赋值,创建了变量 myTitle
          const { myTitle } = toRefs(props)
          console.log(myTitle.value)
          return {
    		myTitle
    	  }
        }
      })
    </script>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
  • 相关阅读:
    js获取blob格式的json对象
    DBNet:具有可微分二值化的实时场景文本检测
    内存泄漏了~
    Jetpack业务架构—四件套(Lifecycle、ViewModel、LiveData、DataBinding)
    ffmpeg分离左右声道到多音轨
    葡萄糖氧化酶(GOD)修饰纳米金(Nano-Au)/壳聚糖(CS)/1-丁基-3-甲基咪唑六氟磷酸盐(BMIMPF6)复合材料
    内网渗透神器CobaltStrike之DNS Beacon(四)
    Django系列15-员工管理系统实战--订单管理
    CentOS7和CentOS8 Asterisk 20.0.0 简单图形化界面8--PJSIP的环境NAT设置
    如何运用3DGIS技术整合智慧社区综合管理解决方案
  • 原文地址:https://blog.csdn.net/mChales_Liu/article/details/125629639