1

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>
7
  • I just started using stackOverflow, and I have tried my best to write a good question, if you find my question has any part which is incorrect, or have any suggestions of the question, hope you could tell me, also. Commented Feb 15 at 8:41
  • 1
    The error message says that a property was accessed from an object that was undefined, i.e. undefined[0]. Looking at the code, my guess is that it happens in loadBlogs, where res.data.data.rows turns out to be undefined. I think you can fix this with simple debugging. Commented Feb 15 at 10:16
  • 1
    console.log(contentShow.value[index]) is called too late. And any way, console isn't a proper way to debug Commented Feb 15 at 10:45
  • @MoritzRingler When I use console.log(), the data of res.data.data.rows is right. Commented Feb 15 at 11:07
  • @EstusFlask Thanks for your reply, firstly, do you mean that the time when contentShow.value[index] get value is too late, so it has been mounted as undefined? And secondly, do you have any good debug method except console? Thanks for your reply, again. Commented Feb 15 at 11:10

1 Answer 1

1

Refs 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 }}
        ...
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.