- 背景:最近在学习一个全栈项目,但是我对前端不太了解,所以出现了很多菜鸡问题,向大家请教。
- 问题:
- 浏览器控制台报错:Uncaught (in promise) TypeError: Cannot read properties of undefined (reading ‘name’)
- 前端页面表现为:点击selectTree选择不同的文档,页面内容、阅读数、点赞数不变化;此时控制台内的请求和响应都正常,响应的结果里有页面内容。
- 后端控制台一切正常,没有报错。
- 我发现这里的日志也没有打印出来。可能是给do.value赋值这里出了问题?
- 如果是前端页面没有拿到后端数据,第一次加载的时候,显示的页面内容、阅读数、点赞数又是正确的;
- 如果是前端页面拿到后端数据,为什么页面的内容没有渲染出来呢?
- 好像是Doc的属性,在Doc.vue都没有拿到。我想这是不是和axios的异步有关?
- 对前端不是很了解,百思不得其解,请各位前辈帮忙看看原因。
运行环境:
- Win10
- IDEA 2022.1.3
- SpringBoot
- Vue cli 4.5.9
- ant design view 3.2.11
- 前端代码如下
<template>
<a-layout>
<a-layout-content :style="{ background: '#fff', padding: '24px', margin: 0, minHeight: '280px' }">
<a-row>
<h3 v-if="level1.length === 0">No doc found!</h3>
<a-col :span="6">
<a-tree
v-if="level1.length > 0"
:tree-data="level1"
@select="onSelect"
:fieldNames="{title: 'name', key: 'id', value: 'id'}"
:defaultExpandAll="true"
:defaultSelectedKeys="defaultSelectedKeys"
>
</a-tree>
</a-col>
<a-col :span="18" v-if="level1.length !== 0">
<div>
<h2>{{doc.name}}</h2>
<div>
<span>阅读数:{{doc.viewcount}}</span>
<span>点赞数:{{doc.votecount}}</span>
</div>
<a-divider style="height: 2px; background-color: #9999cc"/>
</div>
<div class="wangeditor" :innerHTML="html"></div>
</a-col>
</a-row>
</a-layout-content>
</a-layout>
</template>
<script lang="ts">
import { defineComponent, onMounted, ref, createVNode } from 'vue';
import axios from 'axios';
import {message} from 'ant-design-vue';
import {Tool} from "@/util/tool";
import {useRoute} from "vue-router";
export default defineComponent({
name: 'Doc',
setup() {
const route = useRoute();
const docs = ref();
const html = ref();
const defaultSelectedKeys = ref();
defaultSelectedKeys.value = [];
// 当前选中的文档
const doc = ref();
doc.value = {};
const level1 = ref(); // 一级文档树,children属性就是二级文档
level1.value = [];
/**
* 内容查询
**/
const handleQueryContent = (id: number) => {
axios.get("/doc/find-content/" + id).then((response) => {
const data = response.data;
if (data.success) {
html.value = data.content;
} else {
message.error(data.message);
}
});
};
/**
* 数据查询
**/
const handleQuery = () => {
axios.get("/doc/all/" + route.query.ebookId).then((response) => {
const data = response.data;
if (data.success) {
docs.value = data.content;
level1.value = [];
level1.value = Tool.array2Tree(docs.value, 0);
if (Tool.isNotEmpty(level1)) {
defaultSelectedKeys.value = [level1.value[0].id];
handleQueryContent(level1.value[0].id);
// 初始显示文档信息
doc.value = level1.value[0];
}
} else {
message.error(data.message);
}
});
};
const onSelect = (selectedKeys: any, info: any) => {
console.log('selected', selectedKeys, info);
if (Tool.isNotEmpty(selectedKeys)) {
// 选中某一节点时,加载该节点的文档信息
doc.value = info.selectedNodes[0].props;
// 加载内容
handleQueryContent(selectedKeys[0]);
}
};
onMounted(() => {
handleQuery();
});
return {
level1,
html,
onSelect,
defaultSelectedKeys,
doc
}
}
});
</script>
<style>
/* wangeditor默认样式, 参照: http://www.wangeditor.com/doc/pages/02-%E5%86%85%E5%AE%B9%E5%A4%84%E7%90%86/03-%E8%8E%B7%E5%8F%96html.html */
/* table 样式 */
.wangeditor table {
border-top: 1px solid #ccc;
border-left: 1px solid #ccc;
}
.wangeditor table td,
.wangeditor table th {
border-bottom: 1px solid #ccc;
border-right: 1px solid #ccc;
padding: 3px 5px;
}
.wangeditor table th {
border-bottom: 2px solid #ccc;
text-align: center;
}
/* blockquote 样式 */
.wangeditor blockquote {
display: block;
border-left: 8px solid #d0e5f2;
padding: 5px 10px;
margin: 10px 0;
line-height: 1.4;
font-size: 100%;
background-color: #f1f1f1;
}
/* code 样式 */
.wangeditor code {
display: inline-block;
*display: inline;
*zoom: 1;
background-color: #f1f1f1;
border-radius: 3px;
padding: 3px 5px;
margin: 0 3px;
}
.wangeditor pre code {
display: block;
}
/* ul ol 样式 */
.wangeditor ul, ol {
margin: 10px 0 10px 20px;
}
/* 和antdv p冲突,覆盖掉 */
.wangeditor blockquote p {
font-family:"YouYuan";
margin: 20px 10px !important;
font-size: 16px !important;
font-weight:600;
}
</style>
这里打个断点看一下 level1 的值。目测数组里有个元素是 null/undefined。