Vue3中ref、reactive、toRef、toRefs、toRaw方法的用法

828 阅读1分钟

ref 和 reactive

ref: 用来给基本数据类型绑定响应式数据,在setup()函数中时,需要通过 .value 的形式, tamplate 会自动解析,不需要 .value

reactive: 用来给 复杂数据类型 绑定响应式数据,直接访问即可

ref其实也是内部调用 reactive 来实现的

<template>
  <div>
    <p>{{title}}</p>
    <h4>{{userInfo}}</h4>
  </div>
</template>

<script setup lang="ts">
import { ref, reactive } from "vue";
type Person = {
    name: string;
    age: number;
    gender?: string;
};
const title = ref<string>("基本数据类型");
const userInfo = reactive<Person>({
  name: '复杂数据类型',
  age: 18,
})
</script>

结果:

image.png

toRef

如果对象是非响应式的,数据可以改变,但视图显示数据没有更新

使用toRef方法,将数据变成响应式的(和Vue2中的$set很像)

不使用toRef()方法,存在的问题

<template>
  <div>
     <button @click="change">按钮</button>
     <div>{{ obj.age }}</div>
     <div>{{ newAge }}</div>
  </div>
</template>

<script setup lang="ts">
import { reactive, toRef } from 'vue'

const obj =reactive({
  name: '张三',
  age: 18
})
let newAge = obj.age

const change = () => {
  newAge++,
  console.log('obj:',obj,'newAge',newAge);
}
</script>

结果:

image.png

使用toRef()方法(解决数据改变、视图不更新的问题)

<template>
  <div>
     <button @click="change">按钮</button>
     <div>{{ obj.age }}</div>
     <div>{{ newAge }}</div>
  </div>
</template>

<script setup lang="ts">
import { reactive, toRef } from 'vue'

const obj =reactive({
  name: '张三',
  age: 18
})

let newAge = toRef(obj,'age')

const change = () => {
  newAge.value++,
  console.log('obj:',obj,'newAge',newAge);
}
</script>

结果:

image.png

toRefs

toRefs相当于对,对象内每个属性调用toRef,toRefs返回的对象内的属性使用时需要加.value,还能解构使用

<template>
  <div>
     <button @click="change">按钮</button>
     <div>{{ obj.age }}</div>
     <div>{{ age }}</div>
  </div>
</template>

<script setup lang="ts">
import { reactive, toRefs } from 'vue'

const obj =reactive({
  name: '张三',
  age: 18
})
// const newAge = toRefs(obj)
const {name,age} = toRefs(obj) // 解构

const change = () => {
  // newAge.age.value++,
  age.value++
  console.log('obj:',obj,'age',age);
}
</script>

toRaw

将响应式对象修改为普通对象

<template>
  <div>
     <button @click="change">按钮</button>
     <div>{{ obj.age }}</div>
     <div>{{ data }}</div>
  </div>
</template>

<script setup lang="ts">
import { reactive, toRaw } from 'vue'

const obj =reactive({
  name: '张三',
  age: 18
})
const data = toRaw(obj)

const change = () => {
  data.age++
  console.log('obj:',obj,'age',data);
}
</script>

结果:

image.png