浅谈vue3中ref、toRef、toRefs 和 reactive的区别

目录
  • 一、ref——定义任意类型响应式数据
  • 二、reactive——定义响应式对象
  • 三、toRef——将一个 reactive 转化为一个 ref
  • 四、toRefs——将多个 reactive 自动解构为多个 ref

一、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>

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>

二、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>

三、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>

四、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>

到此这篇关于浅谈vue3中ref、toRef、toRefs 和 reactive的区别的文章就介绍到这了,更多相关vue3 ref toRef toRefs reactive内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • vue3如何定义变量及ref、reactive、toRefs特性说明

    目录 vue3定义变量及ref.reactive.toRefs特性 1.ref() 函数 2.reactive() 函数 3.toRefs() 函数 vue3定义变量 1.const 声明变量 2.reactive和ref 3.provide与inject vue3定义变量及ref.reactive.toRefs特性 1.ref() 函数 ref() 函数用来根据给定的值创建一个响应式的数据对象,传入的为基本数据类型,例如字符串.数字.boolean 等,返回值是一个对象,这个对象上只包含一个

  • vue3的ref,computed,reactive和toRefs你都了解吗

    目录 1.ref 2.computed 3.reactive 4.toRefs 总结 在vue2中,data函数里返回的值直接为响应式的,但在vue3中我们需要使用一些函数才能达到这个效果. setup函数中拿不到vue的this 1.ref 本质为一个函数,输入参数为一个值(原始类型),返回响应式的对象 2.computed 本质为一个函数,输入参数是一个函数,可以将我们需要的值作为输入函数的返回值 例子:实现点击按钮,屏幕上的数加1 <template> <div id='app'&

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

    目录 一.ref——定义任意类型响应式数据 二.reactive——定义响应式对象 三.toRef——将一个 reactive 转化为一个 ref 四.toRefs——将多个 reactive 自动解构为多个 ref 一.ref——定义任意类型响应式数据 ref 能定义“任何类型”的响应式数据(ref 在 vue3 中指响应式数据). 参数可以传入任意数据类型. 使用 ref 定义的属性必须通过 .value 的形式才能修改其值.属性的值一旦被修改就会触发模板的重新渲染以显示最新的值. 对于在

  • 浅谈Vue3中watchEffect的具体用法

    前言 watchEffect,它立即执行传入的一个函数,同时响应式追踪其依赖,并在其依赖变更时重新运行该函数. 换句话说:watchEffect相当于将watch 的依赖源和回调函数合并,当任何你有用到的响应式依赖更新时,该回调函数便会重新执行.不同于 watch,watchEffect 的回调函数会被立即执行(即 { immediate: true }) 此文主要讲述怎样利用清除副作用使我们的代码更加优雅~ watchEffect的副作用 什么是副作用(side effect),简单的说副作用

  • 浅谈Java中的四种引用方式的区别

    强引用.软引用.弱引用.虚引用的概念 强引用(StrongReference) 强引用就是指在程序代码之中普遍存在的,比如下面这段代码中的object和str都是强引用: Object object = new Object(); String str = "hello"; 只要某个对象有强引用与之关联,JVM必定不会回收这个对象,即使在内存不足的情况下,JVM宁愿抛出OutOfMemory错误也不会回收这种对象. 比如下面这段代码: public class Main { publi

  • 浅谈java中BigDecimal的equals与compareTo的区别

    这两天在处理支付金额校验的时候出现了点问题,有个金额比较我用了BigDecimal的equals方法来比较两个金额是否相等,结果导致金额比较出现错误(比如3.0与3.00的比较等). [注:以下所讲都是以sun jdk 1.4.2版本为例,其他版本实现未必一致,请忽略] 首先看一下BigDecimal的equals方法: public boolean equals(Object x){ if (!(x instanceof BigDecimal)) return false; BigDecima

  • 浅谈java中类名.class, class.forName(), getClass()的区别

    Class对象的生成方式如下: 1.类名.class    说明: JVM将使用类装载器, 将类装入内存(前提是:类还没有装入内存),不做类的初始化工作.返回Class的对象 2.Class.forName("类名字符串")  (注:类名字符串是包名+类名) 说明:装入类,并做类的静态初始化,返回Class的对象 3.实例对象.getClass()  说明:对类进行静态初始化.非静态初始化:返回引用o运行时真正所指的对象(因为:子对象的引用可能会赋给父对象的引用变量中)所属的类的Cla

  • 浅谈java中六大时间类的使用和区别

    java.util.Date java.sql.Date java.sql.Time java.sql.Timestamp java.text.SimpleDateFormat java.util.Calendar java.util.Date日期格式为:年月日时分秒 java.sql.Date日期格式为:年月日 java.sql.Time日期格式为:时分秒 java.sql.Timestamp日期格式为:年月日时分秒纳秒(毫微秒) 从数据库中取出来的日期一般都用getTimestamp()方法

  • 浅谈Python中threading join和setDaemon用法及区别说明

    Python多线程编程时,经常会用到join()和setDaemon()方法,今天特地研究了一下两者的区别. 1.join ()方法:主线程A中,创建了子线程B,并且在主线程A中调用了B.join(),那么,主线程A会在调用的地方等待,直到子线程B完成操作后,才可以接着往下执行,那么在调用这个线程时可以使用被调用线程的join方法. 原型:join([timeout]) 里面的参数时可选的,代表线程运行的最大时间,即如果超过这个时间,不管这个此线程有没有执行完毕都会被回收,然后主线程或函数都会接

  • 浅谈numpy中np.array()与np.asarray的区别以及.tolist

    array和asarray都可以将结构数据转化为ndarray,但是主要区别就是当数据源是ndarray时,array仍然会copy出一个副本,占用新的内存,但asarray不会. 1.输入为列表时 a=[[1,2,3],[4,5,6],[7,8,9]] b=np.array(a) c=np.asarray(a) a[2]=1 print(a) print(b) print(c) 从中我们可以看出np.array与np.asarray功能是一样的,都是将输入转为矩阵格式.当输入是列表的时候,更改

  • 浅谈Java中IO和NIO的本质和区别

    IO的本质 IO的作用就是从外部系统读取数据到java程序中,或者把java程序中输出的数据写回到外部系统.这里的外部系统可能是磁盘,网络流等等. 因为对所有的外部数据的处理都是由操作系统内核来实现的,对于java应用程序来说,只是调用操作系统中相应的接口方法,从而和外部数据进行交互. 所有IO的本质就是对Buffer的处理,我们把数据放入Buffer供系统写入外部数据,或者从系统Buffer中读取从外部系统中读取的数据.如下图所示: 用户空间也就是我们自己的java程序有一个Buffer,系统

  • 浅谈mysql中int(1)和int(10)的区别

    目录 困惑 数据说话 零填充 总结 困惑 最近遇到个问题,有个表的要加个user_id字段,user_id字段可能很大,于是我提mysql工单alter table xxx ADD user_id int(1).领导看到我的sql工单,于是说:这int(1)怕是不够用吧,接下来是一通解释. 其实这不是我第一次遇到这样的问题了,其中不乏有工作5年以上的老司机.包括我经常在也看到同事也一直使用int(10),感觉用了int(1),字段的上限就被限制,真实情况肯定不是这样. 数据说话 我们知道在mys

随机推荐