博文内容 + 讨论
<template> <el-row :gutter="12"> <el-col :span="5"> <!--分组--> <blogGroup :isDetail="true"/> </el-col> <el-col :span="18"> <!--显示博文--> <h1>{{blogInfo.title}}</h1> ({{dateFormat(blogInfo.addTime).format('YYYY-MM-DD')}}) <v-md-preview :text="blogInfo.concent"></v-md-preview> <hr> <!--讨论列表--> <discussList :id="id"/> <!--讨论表单--> <discussForm :id="id"/> </el-col> </el-row> </template>
【引入的代码略】 // 组件的属性,博文ID const props = defineProps({ id: String }) // 管理 const { getArtcileById } = blogManage() // 表单的model const blogInfo = reactive({}) getArtcileById(props.id).then((data) => { Object.assign(blogInfo, data) })
这个代码就很简单了,因为只实现了基本的发讨论和显示讨论的功能,其他暂略。
看看效果:
好吧,这个讨论做的蛮敷衍的,其实有好多想法,只是篇幅有限,以后再介绍。
组件级别的代码
虽然在vue里面,除了js文件,就是vue文件了,但是我觉得还是应该细分一下。比如上面都是是页面级的代码,下面这些是“组件”级别的代码了。
1
博文分组
多次提到的博文分组。
<template> <!--分组,分为显示状态和编辑状态--> <el-card shadow="hover" v-for="(item, index) in blogGroupList" :key="'grouplist_' + index" > <template #header> <div class="card-header"> <span>{{item.label}}</span> <span class="button"></span> </div> </template> <div class="text item" style="cursor:pointer" v-for="(item, index) in item.children" :key="'group_' + index" @click="changeGroup(item.value)" > {{item.label}} </div> </el-card> </template>
暂时先用 el-card 来实现,后期会改成 NavMenu 来实现。
【引入的代码略】 // 组件的属性 const props = defineProps({ isDetail: Boolean }) /** * 博文的分组列表 */ const blogGroupList = reactive([ { value: '1000', label: '前端', children: [ { value: '1001', label: 'vue基础知识', }, { value: '1002', label: 'vue组件', }, { value: '1003', label: 'vue路由', } ] }, { value: '2000', label: '后端', children: [ { value: '2001', label: 'MySQL', }, { value: '2002', label: 'web服务', } ] } ]) // 选择分组 const { setCurrentGroupId } = blogStateManage() const router = useRouter() const changeGroup = (id) => { setCurrentGroupId(id) // 判断是不是要跳转 // 首页、编辑页不跳,博文详细页面调整 if (props.isDetail) { // 跳转到列表页 router.push({ name: 'groups', params: { groupId: id }}) } }
分组数据暂时写死了,没有做成可以维护的方式,以后再完善。
2
博文列表,编辑用
<template> <!--添加标题--> <el-card shadow="hover"> <template #header> <div class="card-header"> <el-button @click="addNewArticle" >添加新文章</el-button> <span class="button"></span> </div> </template> <div class="text item" style="cursor:pointer" v-for="(item, index) in blogList" :key="'article_' + index" @click="changeArticle(item.ID)" > {{item.ID}}:{{item.title}} ({{dateFormat(item.addTime).format('YYYY-MM-DD')}}) </div> <el-empty description="该分类里面还没有文章呢。" v-if="blogList.length === 0"></el-empty> </el-card> </template>
用 el-card 做个列表,上面是 添加博文的按钮,下面是博文列表,单击可以进行修改。
【引入的代码略】 // 博文列表 const blogList = reactive([]) // 博文管理 const { addNewBlog, getBlogListByGroupId } = blogManage() // 状态管理 const { getBlogState, setEditArticleId } = blogStateManage() // 博文的状态 const blogState = getBlogState() // 更新列表 const load = () => { getBlogListByGroupId(blogState.currentGroupId).then((data) => { blogList.length = 0 blogList.push(...data) }) } load() // 监控选择的分组的ID watch(() => blogState.currentGroupId, () => { load() }) // 添加新文章,仅标题、时间 const addNewArticle = () => { const newArticle = blogForm() // 选择的分组ID newArticle.groupId = blogState.currentGroupId // 用日期作为默认标题 newArticle.title = dayjs(new Date()).format('YYYY-MM-DD') addNewBlog(newArticle).then((id) => { // 设置要编辑的文章ID setEditArticleId(id) // 通知列表 newArticle.ID = id blogList.unshift(newArticle) }) } // 选择要编辑的文章 const changeArticle = (id) => { setEditArticleId(id) }
3
讨论列表
<el-card shadow="hover" v-for="(item, index) in discussList" :key="'bloglist_' + index" > <template #header> <div class="card-header"> {{item.discusser}} <span class="button">({{dateFormat(item.addTime).format('YYYY-MM-DD')}})</span> </div> </template> <!--简介--> <div class="text item" v-html="item.concent"></div> <hr> <i class="el-icon-circle-check"></i> {{item.agreeCount}} </el-card> <!--没有找到数据--> <el-empty description="没有讨论呢,抢个沙发呗。" v-if="discussList.length === 0"></el-empty>
还是用 el-card 做个列表,el-empty 做一个没有讨论的提示。
【引入的代码略】 // 组件的属性 const props = defineProps({ id: String }) // 管理 const { getDiscussListByBlogId } = blogManage() // 获取状态 const { getBlogState } = blogStateManage() const blogState = getBlogState() // 表单的model const discussList = reactive([]) getDiscussListByBlogId(props.id).then((data) => { discussList.push(...data) }) watch(() => blogState.isReloadDiussList, () => { getDiscussListByBlogId(props.id).then((data) => { discussList.length = 0 discussList.push(...data) }) })
因为功能比较简单,所以代码也很简单,获取讨论数据绑定显示即可,暂时没有实现分页功能。
4
讨论表单
<el-form style="width:400px;" label-position="top" :model="dicussModel" label-width="80px" > <el-form-item label="昵称"> <el-input v-model="dicussModel.discusser"></el-input> </el-form-item> <el-form-item label="内容"> <el-input type="textarea" v-model="dicussModel.concent"></el-input> </el-form-item> <el-form-item> <el-button type="primary" @click="submit">发表讨论</el-button> <el-button>取消</el-button> </el-form-item> </el-form>
用 el-form 做个表单。
【引入的代码略】 // 组件的属性 const props = defineProps({ id: String }) // 管理 const { addDiuss } = blogManage() // 获取状态 const { getBlogState, setReloadDiussList } = blogStateManage() const blogState = getBlogState() // 表单的model const dicussModel = reactive(discuss()) // 发布讨论 const submit = () => { dicussModel.blogId = props.id // 这是博文ID addDiuss(dicussModel).then((id) => { // 可以想象成 axios 的提交 // 通知列表 setReloadDiussList() }) }
分成多个组件,每个组件的代码就可以非常少了,这样便于维护。发布讨论的函数,先使用blogManage的功能提交数据,回调函数里面,使用的状态管理的功能提醒讨论列表刷新数据。
源码
https://gitee.com/naturefw/vue3-blog
在线演示
https://naturefw.gitee.io/vue3-blog
本文作者:自然框架
个人网址:jyk.cnblogs.com
声明:本文为 脚本之家专栏作者 投稿,未经允许请勿转载。