主页主要包含两大部分: 导航栏,问题列表。根据上文构建路由提到,导航栏部署在主页布局layouts/HomeLayout.vue
组件中,问题列表则是在嵌套路由渲染的views/QuestionList.vue
中。
修改App.vue
既然是通过vue Router
来渲染页面,那么就需要配置一个最顶层的路由出口<router-view>
。修改文件src/App.vue
<template>
<div id="app">
<router-view />
</div>
</template>
<script>
export default {
name: 'App',
}
</script>
<style>
</style>
清除了VueClie
生成的默认代码,添加 <router-view />
,渲染最高级别路由匹配到的组件
编辑主页布局
主页布局是layouts/HomeLayout.vue
组件。此组件作为/question
路由映射的组件。编辑此文件
<template>
<div>
<Navbar></Navbar>
<router-view />
</div>
</template>
<script>
import Navbar from '../components/Navbar'
export default {
name: 'HomeLayout',
components: {
Navbar
}
}
</script>
首先引入导航栏Navbar
组件
然后添加 <router-view />
,渲染路有文件中的子路有匹配的组件内容
编辑问题列表
在路由文件中配置了问题列表路由
{
path: '/question',
component: HomeLayout,
children: [
{
path: '',
component: QuestionList
},
{
path: 'create',
component: CreateQuestion
},
{
path: ':id',
component: ShowQuestion
}
]
},
访问路径/question
会匹配到src/views/QuestionList
页面,编辑此页面
<template>
<div class="container question-container">
<div class="question-item" v-for="question in questionList" :key="question.id">
<b-media right-align vertical-align="center">
<p class="mb-0 text-secondary qa-desc">
<span>{{question.author}}</span> {{question.created_at}}提问
</p>
<h5 class="mt-0 mb-1">
<b-link :to="`/question/${question.id}`">{{question.title}}</b-link>
</h5>
<p class="mb-0 meta">
<span class="meta-item"><b-icon-chat-square-fill></b-icon-chat-square-fill> {{question.comment_num}}</span>
<span class="meta-item"><b-icon-suit-heart-fill></b-icon-suit-heart-fill> {{question.like_num}}</span>
</p>
</b-media>
</div>
<div>
<b-button v-if="loadFlag" pill block @click="handledQuestionList">加载更多</b-button>
<b-button v-else pill block disabled>没有更多了~</b-button>
</div>
</div>
</template>
<script>
import { getNewQuestionList } from '../api/question'
export default {
name: 'QuestionList',
data () {
return {
questionList: [],
loadFlag: true,
page: 1,
pageSize: 10
}
},
methods: {
handledQuestionList () {
getNewQuestionList({
page: this.page,
size: this.pageSize
}).then(res => {
if (res.data.list.length) {
var questionList = this.questionList
this.questionList = questionList.concat(res.data.list)
this.page = res.data.page,
this.pageSize = res.data.size
} else {
this.loadFlag = false
}
})
}
},
created () {
this.handledQuestionList()
}
}
</script>
<style scoped>
.question-container {
width: 60%;
}
.qa-title {
margin: -7px 0 4px;
display: inherit;
font-size: 18px;
font-weight: 700;
line-height: 1.5;
color: #969696;
}
.qa-desc {
margin: 0 0 8px;
font-size: 13px;
line-height: 24px;
color: #b4b4b4;
}
.meta {
padding-right: 0!important;
font-size: 12px;
font-weight: 400;
line-height: 20px;
}
.meta-item {
margin-right: 10px;
color: #b4b4b4;
}
.question-item {
width: 100%;
margin: 0 0 15px;
padding: 15px 2px 20px 0;
border-bottom: 1px solid #f0f0f0;
}
a {
color: #333;
}
</style>