首页、博文列表
模板部分:
<template> <!--博文列表--> <el-row :gutter="12"> <el-col :span="5"> <!--分组--> <blogGroup :isDetail="true"/> </el-col> <el-col :span="18"> <el-card shadow="hover" v-for="(item, index) in blogList" :key="'bloglist_' + index" > <template #header> <div class="card-header"> <router-link :to="{name:'blogs', params:{id:item.ID}}"> {{item.title}} </router-link> <span class="button">({{dateFormat(item.addTime).format('YYYY-MM-DD')}})</span> </div> </template> <!--简介--> <div class="text item" v-html="item.introduction"></div> <hr> <i class="el-icon-view"></i> {{item.viewCount}} <i class="el-icon-circle-check"></i> {{item.agreeCount}} <i class="el-icon-chat-dot-square"></i> {{item.discussCount}} </el-card> <!--没有找到数据--> <el-empty description="没有找到博文呢。" v-if="blogList.length === 0"></el-empty> <el-pagination background layout="prev, pager, next" v-model:currentPage="blogState.page.pageIndex" :page-size="blogState.page.pageSize" :total="blogState.page.pageTotal"> </el-pagination> </el-col> </el-row> </template>
模板部分没啥变化,还是老样子,使用 el-row 做了一个简单的布局:
- 左面,blogGroup 显示分组的组件。
- 右面,用 el-card 做了一个列表,用于显示博文。
- 下面,用 el-pagination 实现分页功能。
代码部分:
<script setup> import { watch, reactive } from 'vue' import { useRoute } from 'vue-router' import blogGroup from '../components/blog-group.vue' import blogStateManage from '../model/blogState' import { blogManage } from '../model/blogManage' // 日期格式化 const dateFormat = dayjs // 博文管理 const { getBlogList, getBlogCount } = blogManage() // 状态管理 const { getBlogState } = blogStateManage() // 博文的状态 const blogState = getBlogState() // 博文列表 const blogList = reactive([]) 【后面就不写这些引入的代码了】 /** * 按照首页、分组、查询显示博文列表。 * 显示第一页,并且统计总记录数 */ const showBlog = () => { // 分组ID let groupId = blogState.currentGroupId if (groupId === 0) { // 首页,清空查询条件,显示第一页 blogState.findQuery = {} blogState.page.pageIndex = 1 } else { // 分组的博文列表,设置分组条件,显示第一页 blogState.findQuery = { groupId: [401, groupId] } blogState.page.pageIndex = 1 } // 统计符合条件的总记录数 getBlogCount().then((count) => { blogState.page.pageTotal = count }) // 获取第一页的数据 getBlogList().then((data) => { blogList.length = 0 blogList.push(...data) }) } const route = useRoute() // 如果是首页,把 当前分组ID设置为 0 ,以便于显示所有分组的博文。 watch(() => route.fullPath, () => { if (route.fullPath === '/' || route.fullPath === '/blog') { blogState.currentGroupId = 0 } }) // 监控选择的分组的ID watch(() => blogState.currentGroupId, () => { showBlog() }) // 监听页号的变化,按照页号显示博文列表 watch(() => blogState.page.pageIndex, () => { getBlogList().then((data) => { blogList.length = 0 blogList.push(...data) }) }) // 默认执行一遍 showBlog()
代码有点长,这说明了啥呢?还有优化的空间。
- script setup
vite2 建立的项目,默认推荐的是这种方式,其实 vite2 也是支持 export default { setup (props, ctx) { }} 这种写法的。当然 vue-cli 建立的项目也是支持 script setup 这种方式。所以用哪一种可以看个人喜好。
script setup 更简洁,省去了好多“麻烦”,比如组件引入部分,import 就好,不需要再次注册了。const 后也不用 return 了,模板可以直接读取到。
- 各种js类
基于这种“散养”方式,所以必须写各种单独的js文件来实现基础功能,然后在 setup 里面整合,否则 setup 就没法看了。 - watch等
watch、ref、reactive这些的用法没有改变。
看一下效果:
后端出身,不会css,也没有艺术细胞所以比较难看,还望谅解
表单 发布博文
这里借鉴一下“简书”的编辑方式,个人感觉还是很方便的,左面是分组目录,中间的选择的分组的博文列表,右面是编辑博文的区域。
<template> <el-row :gutter="12"> <el-col :span="4"> <!--分组--> <blogGroup/> </el-col> <el-col :span="5"> <!--标题列表--> <blogArticle/> </el-col> <el-col :span="14"> <!--写博文--> <el-input style="width:90%" :show-word-limit="true" maxlength="100" placeholder="请输入博文标题,最多100字" v-model="blogModel.title" /> <el-button type="primary" plain @click="submit"> 发布文章 </el-button> {{dateFormat(blogModel.addTime).format('YYYY-MM-DD HH:mm:ss')}} <v-md-editor :include-level="[1, 2, 3, 4]" v-model="blogModel.concent" :height="editHeight+'px'"></v-md-editor>1 </el-col> </el-row> </template>
- blogGroup 博文分组的组件,显示分组列表,便于我们选择分组。
- blogArticle 博文列表,选择分组后,显示分组里面的博文列表。在这里可以添加博文,点击博文标题,可以在右面加载博文的表单,进行博文编辑。
用过简书的编辑方式之后,感觉这个还是非常方便的。
代码部分:
【引入的代码略】 // 组件 import blogGroup from '../components/blog-group.vue' import blogArticle from '../components/blog-article.vue' // 可见的高度 const editHeight = document.documentElement.clientHeight - 200 // 管理 const { updateBlog, getArtcileById } = blogManage() // 表单的model const blogModel = reactive(blogForm()) // 监控编辑文章的ID watch(() => blogState.editArticleId, (v1, v2) => { getArtcileById(v1).then((data) => { Object.assign(blogModel, data) }) }) // 发布文章 const submit = () => { blogModel.ID = blogState.editArticleId blogModel.state = 2 // 改为发布状态 updateBlog(blogModel).then((id) => { // 通知列表 }) }
- watch(() => blogState.editArticleId 监听要编辑的博文ID,然后加载博文数据绑定表单,编辑之后用 submit 发布博文。
这里还需要一个自动保存草稿的功能,以后再完善。
- submit 发布博文,其实这里是修改博文,因为添加的工作是在 blogArticle 组件里面实现的。
- updateBlog 调用管理类里面的方式实现发布博文的功能。
各个平台的发文方式也体验了一下,还是喜欢这种方式,所以个人博客也采用这种方式来实现编辑博文的功能。
看一下效果:
编辑博文
目录导航:
博文的目录导航
v-md-editor 提供的目录导航功能,还是非常给力的,看着大纲编写,思路清晰多了。