Vue3中关于ref和reactive的问题
关于ref和reactive的问题
如果你使用过 Vue3,你知道的,在 Vue3 中有两个非常常用的响应式 API:reactive 和 ref。它们会把我们想要追踪的数据变成响应式。
而且我们在使用时一直被告知 ref 用于创建基础类型的响应式,也可以创建引用类型的响应式。而对于引用类型,底层也是转换为 reactive 来进行响应式处理。那既然这样为撒还需要 reactive ,全部使用 ref 不就行了吗?
虽然 ref 创建的响应式数据在脚本中需要通过 .value 才能访问到呀!但是这里肯定影响不大。并且在模板中会自动添加上 .value,所以模板中不需要通过 .value 访问。
既然这二者基本没撒差别,但是还是暴露了 reactive 这个 API,难道有什么场景是 reactive 能做而 ref 做不了的?
简单了解 ref & reactive
我们先简单了解一下这两个 API。
reactive
返回对象的响应式副本,响应式转换是“深层”的——它影响所有嵌套 property。我们一般这样写。
const obj = reactive({ count: 0 })并且可以直接使用。
const count = obj.count
ref
受一个内部值并返回一个响应式且可变的 ref 对象。ref 对象仅有一个 .value property,指向该内部值。我们一般是这样写。
const data = ref(xxx)
引用的时候,一般会通过data.value的方式引用。
const dataValue = data.value
通过跟踪 Vue3 的源代码可以证明,当我们调用 ref 方法来定义响应式数据时,当参数为对象类型时,其实里面用的是 reactive 方法。也就是说上面的 data.value ,事实上是 reactive 方法创造出来的。
注意:
reactive 能做的 ref 也能做,并且还是用 reactive 做的
当 ref 的参数为对象时,用的就是 reactive 方法
在 Vue3 中,如果是把对象类型的数据弄成响应式,reactive 和 ref 都可以,且ref 内部是通过r eactive 来支持的。也就是说,你 reactive 能做的,我 ref 也能做。
简单来说 ref 是在 reactive 上在进行了封装进行了增强,所以在 Vue3 中 reactive 能做的,ref 也能做,reactive 不能做的,ref 也能做。
个人理解ref是reactive的语法糖,如:ref(1) 就等价于 reactive({value: 1});
平时项目ref一把梭,是可以的,问题也不大
vue3 ref 和reactive的区别
Ref
ref数据响应式监听。ref 函数传入一个值作为参数,一般传入基本数据类型,返回一个基于该值的响应式Ref对象,该对象中的值一旦被改变和访问,都会被跟踪到,就像我们改写后的示例代码一样,通过修改 count.value 的值,可以触发模板的重新渲染,显示最新的值
<template>
<h1>{{name}}</h1>
<h1>{{age}}</h1>
<button @click="sayName">按钮</button>
</template>
<script lang="ts">
import {ref,computed} from 'vue'
export default {
name: 'App',
setup(){
const name = ref('zhangsan')
const birthYear = ref(2000)
const now = ref(2020)
const age = computed(()=>{
return now.value - birthYear.value
})
const sayName = () =>{
name.value = 'I am ' + name.value
}
return {
name,
sayName,
age
}
}
}
</script>
reactive
reactive是用来定义更加复杂的数据类型,但是定义后里面的变量取出来就不在是响应式Ref对象数据了
所以需要用toRefs函数转化为响应式数据对象

将上面用ref写的代码转化成reactive型的代码
<template>
<!-- <img alt="Vue logo" src="./assets/logo.png"> -->
<div>
<h1>{{ name }}</h1>
<h1>{{ age }}</h1>
<button @click="sayName">按钮</button>
</div>
</template>
<script lang="ts">
import { computed, reactive,toRefs } from "vue";
interface DataProps {
name: string;
now: number;
birthYear: number;
age: number;
sayName: () => void;
}
export default {
name: "App",
setup() {
const data: DataProps = reactive({
name: "zhangsan",
birthYear: 2000,
now: 2020,
sayName: () => {
console.log(1111);
console.log(data.name);
data.name = "I am " + data.name;
console.log(data.name);
},
age: computed(() => {
return data.now - data.birthYear;
}),
});
const refData = toRefs(data)
refData.age
return {
...refData,
};
},
};
</script>
<style>
#app {
font-family: Avenir, Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
margin-top: 60px;
}
</style>
总结
以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。
相关文章
vue2文件流下载成功后文件格式错误、打不开及内容缺失的解决方法
使用Vue时我们前端如何处理后端返回的文件流,下面这篇文章主要给大家介绍了关于vue2文件流下载成功后文件格式错误、打不开及内容缺失的解决方法,文中通过实例代码介绍的非常详细,需要的朋友可以参考下2023-04-04
vue项目如何引入element ui、iview和echarts
这篇文章主要介绍了vue项目如何引入element ui、iview和echarts,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教2022-09-09
前端vue按1920*1080设计图的页面适配屏幕缩放并适配4K屏详解
最近在做一个数据可视化的项目,整个项目全是大屏展示,期间也是遇到很多问题,最令人头疼的就是大屏的适配,下面这篇文章主要给大家介绍了前端vue按1920*1080设计图的页面适配屏幕缩放并适配4K屏的相关资料,需要的朋友可以参考下2022-11-11
在vue-cli3.0 中使用预处理器 (Sass/Less/Stylus) 配置全局变量操作
这篇文章主要介绍了在vue-cli3.0 中使用预处理器 (Sass/Less/Stylus) 配置全局变量操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧2020-08-08


最新评论