问题描述
2023/06/04
今天在学习时,看黑马的视频,小兔鲜的前端项目。
目标 数据是对象数组类型,但是视频中将目标数据使用ref()来生成
心里很不得劲,因为在我的习惯中,只有基本数据类型才用ref(),对象和数组类型要使用reactive()
这个目标数据是通过异步请求获取到的,在异步请求的会调函数中,完成对响应式数据的赋值。
视频中完整的代码是这样的:
<script setup>
// 导入封装的异步api
import { getCategoryAPI } from '@/api/home'
import { ref } from 'vue'
// 定义响应式数据
const category = ref([])
// 封装请求函数
async function getCategory(){
const res = await getCategory()
// 赋值
// res.result是一个普通数组
category.value = res.result
}
</script>
<template>
<!-- 渲染数据 -->
<ul>
<li v-for="item in category" :key="item.id">
...
</li>
</ul>
</template>
这个代码执行起来是没有问题的,成功拿到数据,页面成功渲染。
我想要通过reactive()来定义,然后我的代码是这样的
我是这样想的:
import { reactive } from 'vue'
// 定义响应式数据
const category = reactive([])
async function getCategory(){
const res = await getCategoryAPI()
// category失去响应式
category = res.result
}
import { reactive } from 'vue'
// 定义响应式数据
const category = reactive([])
async function getCategory(){
const res = await getCategoryAPI()
// 等于重新创建了一个响应式对象
// 虽然可以实现响应式数据
// 但是之前的那个空数组就浪费了
// 所以我不想这样
category = reactive(res.result)
}
最终经过我的“深思熟虑”,代码是这样的
import { reactive } from 'vue'
// 定义一个数据
const category
async function getCategory(){
const res = await getCategoryAPI()
// 此时赋值并规定category是一个响应式的数据
category = reactive(res.result)
}
这样做的问题是:可以成功获取到数据,通过Devtools调试发现,category也是一个响应式数据,但是页面渲染不出来。
纳闷了~~~
解析
一开始,我以为是reactive()函数与异步请求的有冲突,哈哈~~
晚上吃饭的时候,突然想到了。
分析:
改进
所以,要想使用reactive()来接收响应式数据数组,而且又不想浪费空间,可以这样
● 先将category定义为响应式数据
● 在异步请求中,将接收的数据追加到category中
const category = reactive([])
async function getCategory(){
const res = await getCategoryAPI()
category.push(...res.result)
}
总结
模版要用到的响应式数据,不要在异步操作中定义/声明成响应式,而是应该在异步请求前完成对响应式的定义、声明。