由于最近打算简单写一个个人博客项目练习,在实现服务端传递数据给父组件,父组件将获取到的具体数据传递给子组件时遇到了很多问题。
问题一、处理数据库传递过来的数据
我是利用axios根据路由获取的文章Id来进行数据库的查询,然后定义了一个articles来捕获数据,由于是使用reactive定义的,所以在接收文章时需要用value来进行获取,具体效果如下:
const loadArticle = async(articleId)=>{
try{
const res = await axios.get(`http://localhost:3000/articles/${articleId}`)
articles.value = res.data
console.log('文章信息获取成功')
}catch(error){
console.error('文章信息获取失败');
}
}
接下来需要单独接收位于服务端文件夹下的文章内容,为了将其也放在articles.value的属性下,我使用了如下代码来进行获取:
const loadArticlecontent = async(articleId)=>{
try{
const res = await axios.get(`http://localhost:3000/articles/${articleId}/content`)
articles.value[0].content = res.data
// console.log(articles.value)
}catch(error){
console.error('未能正常获取文章内容或者未能正确解析');
}
}
要注意,这里我使用了article.value[0]来进行数据的接收,这是因为由于我使用的是reactive来定义的articles,但是实际上前面不需要使用value来定义,因为到了这一步时,value成了一个无中生有的数组,因此需要通过特殊处理(绕远了,不过后来重写了这部分代码,改成了ref)。
二、父组件向子组件传递articles数据
结合上述内容,我使用下面的代码向子组件传递数据,此时我实际上传递了一个数组(重点)。
:article="articles.value"
在子组件props中,我使用的是:
props: {
article: {
type: Object,
required: true
}
}
这种方式来接收的数据,合情合理,毕竟数组在typeof下是输出object的,不过当时没考虑到这一点,最初是将其当做对象来进行处理,于是处处碰壁,最后发现了这个问题,为了解决数据类型带来的困扰,我使用watch来写了一个对数据内容的监视以及利用解构赋值,重新创建了一个带有数据的对象,以此来调取所获取的数据,具体实现如下:
watch(
() => props.article,(newArticle) => {
let articleData = newArticle; // 默认使用传递的数据
if (Array.isArray(newArticle) && newArticle.length > 0) {
articleData = newArticle[0]; // 如果是数组形式,则取第一个元素
}
if (articleData && articleData.content) {
const {
title,
date,
views,
likes,
commentsNum,
content
} = articleData;
Object.assign(SingleArticle, {
title,
date,
views,
likes,
commentsNum,
content
});
}
},{ immediate: true });
// 使用 toRefs 将 SingleArticle 转换为响应式引用对象
const { ...refSingleArticle } = toRefs(SingleArticle);
说实话,造成以上问题的原因是对reactive和ref的使用方式上的混淆和不理解,最终兜兜转转实际上是绕了一大圈,主要是因为无中生有的value[0],造成了一系列的问题,不过也算是一个创新的解决思路,因此记录了下来。