豆宝社区项目实战教程简介
本项目实战教程配有免费视频教程,配套代码完全开源。手把手从零开始搭建一个目前应用最广泛的Springboot+Vue前后端分离多用户社区项目。本项目难度适中,为便于大家学习,每一集视频教程对应在Github上的每一次提交。
项目首页截图
代码开源地址
视频教程地址
前端技术栈
Vue Vuex Vue Router Axios Bulma Buefy Element Vditor DarkReader
后端技术栈
Spring Boot Mysql Mybatis MyBatis-Plus Spring Security JWT Lombok
帖子列表前端
1.下载格式时间
yarn add dayjs
2.src\main.js添加
// 国际化
import 'dayjs/locale/zh-cn'
const dayjs = require('dayjs');
// 相对时间插件
dayjs.extend(relativeTime)
dayjs.locale('zh-cn') // use locale globally
dayjs().locale('zh-cn').format() // use locale in a specific instance
Vue.prototype.dayjs = dayjs;//可以全局使用dayjs
Vue.filter('date', (date) => {
return format(new Date(date), 'yyyy-MM-dd')
})
3.新增src\api\post.js
import request from '@/utils/request'
// 列表
export function getList(pageNo, size, tab) {
return request(({
url: '/post/list',
method: 'get',
params: { pageNo: pageNo, size: size, tab: tab }
}))
}
4. 修改src\views\post\index.vue
替换即可
<template>
<div>
<el-card shadow="never">
<div slot="header" class="clearfix">
<el-tabs v-model="activeName" @tab-click="handleClick">
<el-tab-pane label="最新主题" name="latest">
<article v-for="(item, index) in articleList" :key="index" class="media">
<div class="media-left">
<figure class="image is-48x48">
<img :src="`https://cn.gravatar.com/avatar/${item.userId}?s=164&d=monsterid`" style="border-radius: 5px;">
</figure>
</div>
<div class="media-content">
<div class="">
<p class="ellipsis is-ellipsis-1">
<el-tooltip class="item" effect="dark" :content="item.title" placement="top">
<router-link :to="{name:'post-detail',params:{id:item.id}}">
<span class="is-size-6">{{ item.title }}</span>
</router-link>
</el-tooltip>
</p>
</div>
<nav class="level has-text-grey is-mobile is-size-7 mt-2">
<div class="level-left">
<div class="level-left">
<router-link class="level-item" :to="{ path: `/member/${item.username}/home` }">
{{ item.alias }}
</router-link>
<span class="mr-1">
发布于:{{ dayjs(item.createTime).format("YYYY/MM/DD") }}
</span>
<span
v-for="(tag, index) in item.tags"
:key="index"
class="tag is-hidden-mobile is-success is-light mr-1"
>
<router-link :to="{ name: 'tag', params: { name: tag.name } }">
{{ "#" + tag.name }}
</router-link>
</span>
<span class="is-hidden-mobile">浏览:{{ item.view }}</span>
</div>
</div>
</nav>
</div>
<div class="media-right" />
</article>
</el-tab-pane>
<el-tab-pane label="热门主题" name="hot">
<article v-for="(item, index) in articleList" :key="index" class="media">
<div class="media-left">
<figure class="image is-48x48">
<img :src="`https://cn.gravatar.com/avatar/${item.userId}?s=164&d=monsterid`" style="border-radius: 5px;">
</figure>
</div>
<div class="media-content">
<div class="">
<p class="ellipsis is-ellipsis-1">
<el-tooltip class="item" effect="dark" :content="item.title" placement="top">
<router-link :to="{name:'post-detail',params:{id:item.id}}">
<span class="is-size-6">{{ item.title }}</span>
</router-link>
</el-tooltip>
</p>
</div>
<nav class="level has-text-grey is-mobile is-size-7 mt-2">
<div class="level-left">
<div class="level-left">
<router-link class="level-item" :to="{ path: `/member/${item.username}/home` }">
{{ item.alias }}
</router-link>
<span class="mr-1">
发布于:{{ dayjs(item.createTime).format("YYYY/MM/DD") }}
</span>
<span
v-for="(tag, index) in item.tags"
:key="index"
class="tag is-hidden-mobile is-success is-light mr-1"
>
<router-link :to="{ name: 'tag', params: { name: tag.name } }">
{{ "#" + tag.name }}
</router-link>
</span>
<span class="is-hidden-mobile">浏览:{{ item.view }}</span>
</div>
</div>
</nav>
</div>
<div class="media-right" />
</article>
</el-tab-pane>
<el-tab-pane label="最近修改" name="udpate">
<article v-for="(item, index) in articleList" :key="index" class="media">
<div class="media-left">
<figure class="image is-48x48">
<img :src="`https://cn.gravatar.com/avatar/${item.userId}?s=164&d=monsterid`" style="border-radius: 5px;">
</figure>
</div>
<div class="media-content">
<div class="">
<p class="ellipsis is-ellipsis-1">
<el-tooltip class="item" effect="dark" :content="item.title" placement="top">
<router-link :to="{name:'post-detail',params:{id:item.id}}">
<span class="is-size-6">{{ item.title }}</span>
</router-link>
</el-tooltip>
</p>
</div>
<nav class="level has-text-grey is-mobile is-size-7 mt-2">
<div class="level-left">
<div class="level-left">
<router-link class="level-item" :to="{ path: `/member/${item.username}/home` }">
{{ item.alias }}
</router-link>
<span class="mr-1">
发布于:{{ dayjs(item.createTime).format("YYYY/MM/DD") }}
</span>
<span
v-for="(tag, index) in item.tags"
:key="index"
class="tag is-hidden-mobile is-success is-light mr-1"
>
<router-link :to="{ name: 'tag', params: { name: tag.name } }">
{{ "#" + tag.name }}
</router-link>
</span>
<span class="is-hidden-mobile">浏览:{{ item.view }}</span>
</div>
</div>
</nav>
</div>
<div class="media-right" />
</article>
</el-tab-pane>
</el-tabs>
</div>
</el-card>
</div>
</template>
<script>
import { getList } from '@/api/post'
export default {
name: "TopicList",
data() {
return {
activeName: 'latest',
articleList: [],
};
},
created() {
this.init(this.tab)
},
methods: {
init(tab) {
getList(1, 10, tab).then((response) => {
const { data } = response
this.articleList = data.records
})
},
handleClick(tab) {
this.init(tab.name)
}
}
};
</script>