When I try to mount contentShow.value[index]
, it couldn't show normally and just empty.If I don't mount contentShow.value[index]
, other part is normal, but when I mount it, the whole page couldn't show.
The browser caught error as follows:
Uncaught (in promise) TypeError: Cannot read properties of undefined (reading '0')
Here is the code in this file,the wrong is just relative of the part I wrap it with **
, but for the coherence of the code, I put code as much as possible.
<template>
<n-tabs type="line" animated size="large" justify-content="start" :bar-width="100">
<n-tab-pane name="list" tab="文章列表">
**↓
<div v-for="(blog,index) in blogListInfo" :key="index">
<n-card :title="blog.title" size="huge" style="min-width: 80%;">
{{ contentShow.value[index] }}
<template #footer>
<n-space align="center">
<div>发布时间:{{ blog.create_time }}</div>
<n-button>修改</n-button>
<n-button>删除</n-button>
</n-space>
</template>
</n-card>
</div>
**↑
</n-tab-pane>
<n-tab-pane name="add" tab="添加文章">
<n-form>
<n-form-item label="标题">
<n-input v-model:value="addArticle.title" placeholder="请输入标题" size="large"></n-input>
</n-form-item>
<n-form-item label="分类">
<n-select v-model:value="addArticle.category_id" :options="categoryOptions" />
</n-form-item>
<n-form-item label="内容">
<RichTextEditor v-model="addArticle.content"></RichTextEditor>
</n-form-item>
<n-form-item label="">
<n-button @click="add">提交</n-button>
</n-form-item>
</n-form>
</n-tab-pane>
</n-tabs>
</template>
<script setup>
import { AdminStore } from '../../stores/AdminStore';
import {ref,reactive,inject,onMounted} from 'vue'
import RichTextEditor from '../../components/RichTextEditor.vue';
const axios = inject("axios");
const message = inject("message");
const addArticle = reactive({
category_id:0,
title:"",
content:"",
});
const categoryOptions = ref([]);
**↓
const blogListInfo = ref([]);
onMounted(()=>{
loadBlogs();
loadCategories();
});
const contentShow = ref([]);
const loadBlogs = async ()=>{
let res = await axios.get("/blog/search");
blogListInfo.value = res.data.data.rows;
for(let index = 0 ; index < blogListInfo.value.length ; index++){
if(blogListInfo.value[index].content.length>10){
contentShow.value[index] = blogListInfo.value[index].content.substring(0,10)+"...";
}else{
contentShow.value[index] = blogListInfo.value[index].content;
}
console.log(contentShow.value[index]);
}
}
**↑
const loadCategories = async ()=>{
let res= await axios.get("/category/list");
categoryOptions.value = res.data.rows.map((item)=>{
return {
label:item.name,
value:item.id
};
});
}
const add = async ()=>{
let res = await axios.post("/blog/_token/add",addArticle);
if(res.data.code==200){
message.info(res.data.msg);
addArticle.title="";
addArticle.content="";
}else{
message.error(res.data.msg);
}
}
</script>
When I try to mount contentShow.value[index]
, it couldn't show normally and just empty.If I don't mount contentShow.value[index]
, other part is normal, but when I mount it, the whole page couldn't show.
The browser caught error as follows:
Uncaught (in promise) TypeError: Cannot read properties of undefined (reading '0')
Here is the code in this file,the wrong is just relative of the part I wrap it with **
, but for the coherence of the code, I put code as much as possible.
<template>
<n-tabs type="line" animated size="large" justify-content="start" :bar-width="100">
<n-tab-pane name="list" tab="文章列表">
**↓
<div v-for="(blog,index) in blogListInfo" :key="index">
<n-card :title="blog.title" size="huge" style="min-width: 80%;">
{{ contentShow.value[index] }}
<template #footer>
<n-space align="center">
<div>发布时间:{{ blog.create_time }}</div>
<n-button>修改</n-button>
<n-button>删除</n-button>
</n-space>
</template>
</n-card>
</div>
**↑
</n-tab-pane>
<n-tab-pane name="add" tab="添加文章">
<n-form>
<n-form-item label="标题">
<n-input v-model:value="addArticle.title" placeholder="请输入标题" size="large"></n-input>
</n-form-item>
<n-form-item label="分类">
<n-select v-model:value="addArticle.category_id" :options="categoryOptions" />
</n-form-item>
<n-form-item label="内容">
<RichTextEditor v-model="addArticle.content"></RichTextEditor>
</n-form-item>
<n-form-item label="">
<n-button @click="add">提交</n-button>
</n-form-item>
</n-form>
</n-tab-pane>
</n-tabs>
</template>
<script setup>
import { AdminStore } from '../../stores/AdminStore';
import {ref,reactive,inject,onMounted} from 'vue'
import RichTextEditor from '../../components/RichTextEditor.vue';
const axios = inject("axios");
const message = inject("message");
const addArticle = reactive({
category_id:0,
title:"",
content:"",
});
const categoryOptions = ref([]);
**↓
const blogListInfo = ref([]);
onMounted(()=>{
loadBlogs();
loadCategories();
});
const contentShow = ref([]);
const loadBlogs = async ()=>{
let res = await axios.get("/blog/search");
blogListInfo.value = res.data.data.rows;
for(let index = 0 ; index < blogListInfo.value.length ; index++){
if(blogListInfo.value[index].content.length>10){
contentShow.value[index] = blogListInfo.value[index].content.substring(0,10)+"...";
}else{
contentShow.value[index] = blogListInfo.value[index].content;
}
console.log(contentShow.value[index]);
}
}
**↑
const loadCategories = async ()=>{
let res= await axios.get("/category/list");
categoryOptions.value = res.data.rows.map((item)=>{
return {
label:item.name,
value:item.id
};
});
}
const add = async ()=>{
let res = await axios.post("/blog/_token/add",addArticle);
if(res.data.code==200){
message.info(res.data.msg);
addArticle.title="";
addArticle.content="";
}else{
message.error(res.data.msg);
}
}
</script>
Share
Improve this question
asked Feb 15 at 8:35
OuterTownerOuterTowner
411 silver badge10 bronze badges
7
|
Show 2 more comments
1 Answer
Reset to default 1Refs are unwrapped in templates, it should be:
{{ contentShow[index] }}
Also, this line doesn't trigger an immediate update because state updates are currently batched in Vue:
blogListInfo.value = res.data.data.rows
But under some conditions it could results in accessing contentShow.value[index]
when contentShow.value
is an empty array that contains no index
element. A better practice to avoid potential problems is to process an iterated array to contain ready to use values:
<div v-for="(blog,index) in processedBlogEntries" :key="index">
<n-card :title="blog.title">
{{ blog.truncatedContent }}
...
undefined[0]
. Looking at the code, my guess is that it happens inloadBlogs
, whereres.data.data.rows
turns out to be undefined. I think you can fix this with simple debugging. – Moritz Ringler Commented Feb 15 at 10:16res.data.data.rows
is right. – OuterTowner Commented Feb 15 at 11:07contentShow.value[index]
get value is too late, so it has been mounted asundefined
? And secondly, do you have any good debug method except console? Thanks for your reply, again. – OuterTowner Commented Feb 15 at 11:10