系列文章目录

  1. 系统功能演示——基于SpringBoot和Vue的后台管理系统项目系列博客(一)
  2. Vue2安装并集成ElementUI——基于SpringBoot和Vue的后台管理系统项目系列博客(二)
  3. Vue2前端主体框架搭建——基于SpringBoot和Vue的后台管理系统项目系列博客(三)
  4. SpringBoot后端初始框架搭建——基于SpringBoot和Vue的后台管理系统项目系列博客(四)
  5. SpringBoot集成Mybatis——基于SpringBoot和Vue的后台管理系统项目系列博客(五)
  6. SpringBoot实现增删改查——基于SpringBoot和Vue的后台管理系统项目系列博客(六)
  7. SpringBoot实现分页查询——基于SpringBoot和Vue的后台管理系统项目系列博客(七)
  8. SpringBoot实现集成Mybatis-Plus和SwaggerUI——基于SpringBoot和Vue的后台管理系统项目系列博客(八)
  9. Vue实现增删改查——基于SpringBoot和Vue的后台管理系统项目系列博客(九)
  10. SpringBoot实现代码生成器——基于SpringBoot和Vue的后台管理系统项目系列博客(十)
  11. Vue使用路由——基于SpringBoot和Vue的后台管理系统项目系列博客(十一)
  12. SpringBoot和Vue实现导入导出——基于SpringBoot和Vue的后台管理系统项目系列博客(十二)
  13. SpringBoot和Vue实现用户登录注册与异常处理——基于SpringBoot和Vue的后台管理系统项目系列博客(十三)
  14. SpringBoot和Vue实现用户个人信息展示与保存与集成JWT——基于SpringBoot和Vue的后台管理系统项目系列博客(十四)
  15. SpringBoot和Vue实现文件上传与下载——基于SpringBoot和Vue的后台管理系统项目系列博客(十五)
  16. SpringBoot和Vue整合ECharts——基于SpringBoot和Vue的后台管理系统项目系列博客(十六)
  17. SpringBoot和Vue实现权限菜单功能——基于SpringBoot和Vue的后台管理系统项目系列博客(十七)
  18. SpringBoot实现1对1、1对多、多对多关联查询——基于SpringBoot和Vue的后台管理系统项目系列博客(十八)
  19. 用户前台页面设计与实现——基于SpringBoot和Vue的后台管理系统项目系列博客(十九)
  20. SpringBoot集成Redis实现缓存——基于SpringBoot和Vue的后台管理系统项目系列博客(二十)
  21. SpringBoot和Vue集成高德地图——基于SpringBoot和Vue的后台管理系统项目系列博客(二十一)
  22. SpringBoot和Vue集成视频播放组件——基于SpringBoot和Vue的后台管理系统项目系列博客(二十二)
  23. SpringBoot和Vue集成Markdown和多级评论——基于SpringBoot和Vue的后台管理系统项目系列博客(二十三)

项目资源下载

  1. GitHub下载地址
  2. Gitee下载地址
  3. 项目MySql数据库文件

文章目录

  • 系列文章目录
  • 项目资源下载
  • 前言
  • 一、后端基础内容的创建
  • 二、前端基础内容的创建
  • 三、Vue后台集成Markdown组件
  • 四、Vue前台集成Markdown组件
  • 五、实现前台文章评论显示功能
  • 六、实现前台文章评论保存功能
  • 七、实现前台文章评论删除功能
  • 八、实现前台文章多级评论功能
  • 总结

前言

今天的主要内容包括:后端基础内容的创建、前端基础内容的创建、Vue后台集成Markdown组件、Vue前台集成Markdown组件、实现前台文章评论显示功能、实现前台文章评论保存功能、实现前台文章评论删除功能、实现前台文章多级评论功能等,今天的学习内容也比较多,但都是非常实用的功能,这也是本系列博文的最后一篇了,加油!下面就开始今天的学习!


一、后端基础内容的创建

  1. 首先在数据库中新建表,按照如下内容创建
  2. 输入表名为article,然后保存
  3. 然后使用代码生成器,生成关于article的代码
  4. 可以看到已经成功生成了
  5. 为了后面可以实现条件查询,所以我们修改ArticleController.java中的如下内容

二、前端基础内容的创建

  1. 首先在views下新建Article.vue
  2. 然后将Article.vue中的全部内容替换为如下内容
<template><div><div style="margin: 10px 0"><el-input style="width: 200px" placeholder="请输入名称" suffix-icon="el-icon-search" v-model="name"></el-input><el-button class="ml-5" type="primary" @click="load">搜索</el-button><el-button type="warning" @click="reset">重置</el-button></div><div style="margin: 10px 0"><el-button type="primary" @click="handleAdd" v-if="user.role === 'ROLE_ADMIN'">新增 <iclass="el-icon-circle-plus-outline"></i></el-button><el-popconfirmclass="ml-5"confirm-button-text='确定'cancel-button-text='我再想想'icon="el-icon-info"icon-color="red"title="您确定批量删除这些数据吗?"@confirm="delBatch"><el-button type="danger" slot="reference">批量删除 <i class="el-icon-remove-outline"></i></el-button></el-popconfirm></div><el-table :data="tableData" border stripe :header-cell-class-name="'headerBg'"@selection-change="handleSelectionChange"><el-table-column type="selection" width="55"></el-table-column><el-table-column prop="id" label="ID" width="80"></el-table-column><el-table-column prop="name" label="文章标题"></el-table-column><el-table-column prop="content" label="文章内容"></el-table-column><el-table-column prop="user" label="发布人"></el-table-column><el-table-column prop="time" label="发布时间"></el-table-column><el-table-column label="操作" width="280" align="center"><template slot-scope="scope"><el-button type="success" @click="handleEdit(scope.row)" v-if="user.role === 'ROLE_ADMIN'">编辑 <iclass="el-icon-edit"></i></el-button><el-popconfirmclass="ml-5"confirm-button-text='确定'cancel-button-text='我再想想'icon="el-icon-info"icon-color="red"title="您确定删除吗?"@confirm="del(scope.row.id)"><el-button type="danger" slot="reference" v-if="user.role === 'ROLE_ADMIN'">删除 <iclass="el-icon-remove-outline"></i></el-button></el-popconfirm></template></el-table-column></el-table><div style="padding: 10px 0"><el-pagination@size-change="handleSizeChange"@current-change="handleCurrentChange":current-page="pageNum":page-sizes="[2, 5, 10, 20]":page-size="pageSize"layout="total, sizes, prev, pager, next, jumper":total="total"></el-pagination></div><el-dialog title="文章信息" :visible.sync="dialogFormVisible" width="60%"><el-form label-width="80px" size="small"><el-form-item label="标题"><el-input v-model="form.name" autocomplete="off"></el-input></el-form-item><el-form-item label="内容"><el-input v-model="form.content" autocomplete="off"></el-input></el-form-item></el-form><div slot="footer" class="dialog-footer"><el-button @click="dialogFormVisible = false">取 消</el-button><el-button type="primary" @click="save">确 定</el-button></div></el-dialog></div>
</template><script>export default {name: "Article",data() {return {form: {},tableData: [],name: '',multipleSelection: [],pageNum: 1,pageSize: 10,total: 0,dialogFormVisible: false,teachers: [],user: localStorage.getItem("user") ? JSON.parse(localStorage.getItem("user")) : {},}},created() {this.load()},methods: {load() {this.request.get("/article/page", {params: {pageNum: this.pageNum,pageSize: this.pageSize,name: this.name,}}).then(res => {this.tableData = res.data.recordsthis.total = res.data.total});},changeEnable(row) {this.request.post("/article/update", row).then(res => {if (res.code === '200') {this.$message.success("操作成功")}})},del(id) {this.request.delete("/article/" + id).then(res => {if (res.code === '200') {this.$message.success("删除成功")this.load()} else {this.$message.error("删除失败")}})},handleSelectionChange(val) {console.log(val)this.multipleSelection = val},delBatch() {let ids = this.multipleSelection.map(v => v.id)  // [{}, {}, {}] => [1,2,3]this.request.post("/article/del/batch", ids).then(res => {if (res.code === '200') {this.$message.success("批量删除成功")this.load()} else {this.$message.error("批量删除失败")}})},save() {this.request.post("/article", this.form).then(res => {if (res) {this.$message.success("保存成功")this.dialogFormVisible = falsethis.load()} else {this.$message.error("保存失败")}})},reset() {this.name = ""this.load()},handleAdd() {this.dialogFormVisible = truethis.form = {}},handleEdit(row) {this.form = rowthis.dialogFormVisible = true},handleSizeChange(pageSize) {console.log(pageSize)this.pageSize = pageSizethis.load()},handleCurrentChange(pageNum) {console.log(pageNum)this.pageNum = pageNumthis.load()},download(url) {window.open(url)}}}
</script><style scoped></style>
  1. 然后在菜单管理中新增文章管理的路由
  2. 然后给管理员分配文章管理页面的权限
  3. 重新登陆之后发现已经出现了文章管理页面了

三、Vue后台集成Markdown组件

  1. 首先在控制台输入npm install mavon-editor@2.10.4 -S,安装Markdown组件
  2. 安装完此组件后需要在main.js中进行全局注册
  3. 然后在Article.vue中如下几处中新增代码


  4. 然后来到前端的文章管理页面,发现Markdown功能都可以使用
  5. 但是现在有一个问题,当我们保存的时候,效果并不好,所以我们要对此部分内容进行优化
  6. 为了解决这个问题,我们在ArticleController.java中加入如下代码
  7. 此时再来到前台测试,发现所有信息都已经成功显示了。但是文章内容部分不太好看,我们要进行一些优化
  8. 为了解决这个问题,我们要修改Article.vue中如下几处内容



  9. 此时来到前端测试,发现当我们点击查看内容按钮时
  10. 可以成功显示出Markdown格式的文章了

四、Vue前台集成Markdown组件

  1. 首先在front中新建Article.vue
  2. 然后为其配置路由
  3. 然后在Front.vue中为文章列表新增路由链接
  4. 然后将Article.vue中的全部内容替换为如下内容
<template><div><div style="margin: 10px 0"><el-input size="small" style="width: 300px" placeholder="请输入名称" suffix-icon="el-icon-search"v-model="name"></el-input><el-button class="ml-5" type="primary" @click="load" size="small">搜索</el-button><el-button type="warning" @click="reset" size="small">重置</el-button></div><div style="margin: 10px 0"><div style="padding: 10px 0; border-bottom: 1px dashed #ccc" v-for="item in tableData" :key="item.id"><div class="pd-10" style="font-size: 20px; color: #3F5EFB; cursor: pointer"@click="$router.push('/front/articleDetail?id=' + item.id)">{{ item.name }}</div><div style="font-size: 14px; margin-top: 10px"><i class="el-icon-user-solid"></i> <span>{{ item.user }}</span><i class="el-icon-time" style="margin-left: 10px"></i> <span>{{ item.time }}</span></div></div></div><div style="padding: 10px 0"><el-pagination@size-change="handleSizeChange"@current-change="handleCurrentChange":current-page="pageNum":page-sizes="[2, 5, 10, 20]":page-size="pageSize"layout="total, prev, pager, next":total="total"></el-pagination></div></div>
</template><script>import axios from "axios";export default {name: "Article",data() {return {form: {},tableData: [],name: '',multipleSelection: [],pageNum: 1,pageSize: 10,total: 0,dialogFormVisible: false,teachers: [],user: localStorage.getItem("user") ? JSON.parse(localStorage.getItem("user")) : {},content: '',viewDialogVis: false,}},created() {this.load()},methods: {view(content) {this.content = contentthis.viewDialogVis = true},// 绑定@imgAdd eventimgAdd(pos, $file) {let $vm = this.$refs.md// 第一步.将图片上传到服务器.const formData = new FormData();formData.append('file', $file);axios({url: 'http://localhost:9090/file/upload',method: 'post',data: formData,headers: {'Content-Type': 'multipart/form-data'},}).then((res) => {// 第二步.将返回的url替换到文本原位置![...](./0) -> ![...](url)$vm.$img2Url(pos, res.data);})},load() {this.request.get("/article/page", {params: {pageNum: this.pageNum,pageSize: this.pageSize,name: this.name,}}).then(res => {this.tableData = res.data.recordsthis.total = res.data.total});},changeEnable(row) {this.request.post("/article/update", row).then(res => {if (res.code === '200') {this.$message.success("操作成功")}})},del(id) {this.request.delete("/article/" + id).then(res => {if (res.code === '200') {this.$message.success("删除成功")this.load()} else {this.$message.error("删除失败")}})},handleSelectionChange(val) {console.log(val)this.multipleSelection = val},delBatch() {let ids = this.multipleSelection.map(v => v.id)  // [{}, {}, {}] => [1,2,3]this.request.post("/article/del/batch", ids).then(res => {if (res.code === '200') {this.$message.success("批量删除成功")this.load()} else {this.$message.error("批量删除失败")}})},save() {this.request.post("/article", this.form).then(res => {if (res) {this.$message.success("保存成功")this.dialogFormVisible = falsethis.load()} else {this.$message.error("保存失败")}})},reset() {this.name = ""this.load()},handleAdd() {this.dialogFormVisible = truethis.form = {}},handleEdit(row) {this.form = rowthis.dialogFormVisible = true},handleSizeChange(pageSize) {console.log(pageSize)this.pageSize = pageSizethis.load()},handleCurrentChange(pageNum) {console.log(pageNum)this.pageNum = pageNumthis.load()},download(url) {window.open(url)}}}
</script><style scoped></style>
  1. 此时当我们在网站前台点击文章列表时
  2. 就可以显示文章信息了。但是我们现在还不能点击去看文章的具体信息,所以我们下面就要完成显示文章具体信息的功能了
  3. 在views/front下面新建ArticleDetail.vue
  4. 然后我们为ArticleDetail.vue配一个路由
  5. 然后将ArticleDetail.vue中的全部内容替换为如下内容
<template><div style="color: #666"><div style="margin: 20px 0; "><div class="pd-10" style="font-size: 20px; color: #3F5EFB; cursor: pointer">{{ article.name }}</div><div style="font-size: 14px; margin-top: 10px"><i class="el-icon-user-solid"></i> <span>{{ article.user }}</span><i class="el-icon-time" style="margin-left: 10px"></i> <span>{{ article.time }}</span></div></div><div style="margin: 20px 0"><mavon-editorclass="md":value="article.content":subfield="false":defaultOpen="'preview'":toolbarsFlag="false":editable="false":scrollStyle="true":ishljs="true"/></div></div>
</template><script>export default {name: "ArticleDetail",data() {return {article: {},user: localStorage.getItem("user") ? JSON.parse(localStorage.getItem("user")) : {},}},created() {this.load()},methods: {load() {const id = this.$route.query.idthis.request.get("/article/" + id).then(res => {this.article = res.data});},}}
</script><style scoped></style>
  1. 此时在来到我们的文章列表中,点击文章标题
  2. 发现已经可以成功显示我们的文章内容了

五、实现前台文章评论显示功能

  1. 首先在数据库中新建文章评论的数据库,其中字段如下设置
  2. 将其命名为t_comment
  3. 然后使用代码生成器生成关于刚才创建的数据库的一些功能
  4. 可以看到运行之后,已经成功生成了
  5. 成功生成之后首先在Comment.java中新增两个字段,为了查询出评论人的昵称和头像
  6. 然后在CommentMapper.java中写我们的查询
  7. 然后在CommentServiceImpl.java中新增如下内容
  8. 在ICommentService.java中新增如下内容
  9. 最后在CommentController.java中返回我们查询到的结果
  10. 然后在数据表中输入一些测试内容
  11. 最后使用PostMan测试,发现已经可以成功获取到数据了。这里测试的时候需要注意,要带着用户的token进行测试,否则会被拦截从而测试失败
  12. 然后将ArticleDetail.vue中的内容全部替换为如下内容
<template><div style="color: #666"><div style="margin: 20px 0; "><div class="pd-10" style="font-size: 20px; color: #3F5EFB; cursor: pointer">{{ article.name }}</div><div style="font-size: 14px; margin-top: 10px"><i class="el-icon-user-solid"></i> <span>{{ article.user }}</span><i class="el-icon-time" style="margin-left: 10px"></i> <span>{{ article.time }}</span></div></div><div style="margin: 20px 0"><mavon-editorclass="md":value="article.content":subfield="false":defaultOpen="'preview'":toolbarsFlag="false":editable="false":scrollStyle="true":ishljs="true"/></div><div style="margin: 30px 0"><div style="margin: 10px 0"><div style="border-bottom: 1px solid orangered; padding: 10px 0; font-size: 20px">评论</div><div style="padding: 10px 0"><el-input size="small" type="textarea" v-model="commentForm.content"></el-input></div><div class="pd-10" style="text-align: right"><el-button type="primary" size="small" @click="">评论</el-button></div></div></div><!--      评论列表--><div><div v-for="item in comments" :key="item.id" style="border-bottom: 1px solid #ccc; padding: 10px 0; "><div style="display: flex"><!--  头像--><div style="width: 100px; text-align: center"><el-image :src="item.avatar"style="width: 50px; height: 50px; border-radius: 50%"></el-image></div><!--  内容--><div style="flex: 1; font-size: 14px; padding: 5px 0; line-height: 25px"><b>{{ item.nickname }}:</b><span>{{ item.content }}</span><div style="display: flex; line-height: 20px; margin-top: 5px"><div style="width: 200px;"><i class="el-icon-time"></i><span style="margin-left: 5px">{{ item.time }}</span></div><div style="text-align: right; flex: 1"><el-button style="margin-left: 5px" type="text" @click="">回复</el-button><el-button type="text" style="color: red" @click=""v-if="user.id === item.userId">删除</el-button></div></div></div></div></div></div></div>
</template><script>export default {name: "ArticleDetail",data() {return {article: {},user: localStorage.getItem("user") ? JSON.parse(localStorage.getItem("user")) : {},comments: [],commentForm: {},id: this.$route.query.id,}},created() {this.load()this.loadComment()},methods: {load() {const id = this.$route.query.idthis.request.get("/article/" + id).then(res => {this.article = res.data});},loadComment() {this.request.get("/comment/tree/" + this.id).then(res => {this.comments = res.data})},}}
</script><style scoped></style>
  1. 然后来到前台可以看到,已经可以成功显示用户的评论了

六、实现前台文章评论保存功能

  1. 首先在CommentController.java中新增如下内容
  2. 然后在ArticleDetail.vue中修改如下两处代码

  3. 然后来到前台测试,发现已经成功保存我们的用户评论了

七、实现前台文章评论删除功能

  1. 因为后台代码都已经生成好了,所以我们只需要修改ArticleDetail.vue中如下两处代码即可

  2. 然后来到前台测试,发现已经成功实现文章评论删除功能了

八、实现前台文章多级评论功能

  1. 首先在Comment.java中新增三个字段
  2. 然后修改CommentController.java中如下内容
  3. 然后将ArticleDetail.vue中的内容全部替换为如下内容
<template><div style="color: #666"><div style="margin: 20px 0; "><div class="pd-10" style="font-size: 20px; color: #3F5EFB; cursor: pointer">{{ article.name }}</div><div style="font-size: 14px; margin-top: 10px"><i class="el-icon-user-solid"></i> <span>{{ article.user }}</span><i class="el-icon-time" style="margin-left: 10px"></i> <span>{{ article.time }}</span></div></div><div style="margin: 20px 0"><mavon-editorclass="md":value="article.content":subfield="false":defaultOpen="'preview'":toolbarsFlag="false":editable="false":scrollStyle="true":ishljs="true"/></div><div style="margin: 30px 0"><div style="margin: 10px 0"><div style="border-bottom: 1px solid orangered; padding: 10px 0; font-size: 20px">评论</div><div style="padding: 10px 0"><el-input size="small" type="textarea" v-model="commentForm.content"></el-input></div><div class="pd-10" style="text-align: right"><el-button type="primary" size="small" @click="save">评论</el-button></div></div></div><!--      评论列表--><div><div v-for="item in comments" :key="item.id" style="border-bottom: 1px solid #ccc; padding: 10px 0; "><div style="display: flex"><!--  头像 --><div style="width: 100px; text-align: center"><el-image :src="item.avatar"style="width: 50px; height: 50px; border-radius: 50%"></el-image></div><!--  内容 --><div style="flex: 1; font-size: 14px; padding: 5px 0; line-height: 25px"><b>{{ item.nickname }}:</b><span>{{ item.content }}</span><div style="display: flex; line-height: 20px; margin-top: 5px"><div style="width: 200px;"><i class="el-icon-time"></i><span style="margin-left: 5px">{{ item.time }}</span></div><div style="text-align: right; flex: 1"><el-button style="margin-left: 5px" type="text" @click="handleReply(item.id)">回复</el-button><el-button type="text" style="color: red" @click="del(item.id)"v-if="user.id === item.userId">删除</el-button></div></div></div><!-- 回复 --><div v-if="item.children.length" style="padding-left: 200px;"><div v-for="subItem in item.children" :key="subItem.id"style="background-color: #f0f0f0; padding: 5px 20px"><div style="font-size: 14px; padding: 5px 0; line-height: 25px"><div><b style="color: #3a8ee6" v-if="subItem.pnickname">@{{ subItem.pnickname }}</b></div><div style="padding-left: 5px"><b>{{ subItem.nickname }}:</b><span>{{ subItem.content }}</span></div><div style="display: flex; line-height: 20px; margin-top: 5px; padding-left: 5px"><div style="width: 200px;"><i class="el-icon-time"></i><spanstyle="margin-left: 5px">{{ subItem.time }}</span></div><div style="text-align: right; flex: 1"><el-button style="margin-left: 5px" type="text"@click="handleReply(subItem.id)">回复</el-button><el-button type="text" style="color: red" @click="del(subItem.id)"v-if="user.id === subItem.userId">删除</el-button></div></div></div></div></div></div></div></div><el-dialog title="回复" :visible.sync="dialogFormVisible" width="50%"><el-form label-width="80px" size="small"><el-form-item label="回复内容"><el-input type="textarea" v-model="commentForm.contentReply" autocomplete="off"></el-input></el-form-item></el-form><div slot="footer" class="dialog-footer"><el-button @click="dialogFormVisible = false" size="small">取 消</el-button><el-button type="primary" @click="save" size="small">确 定</el-button></div></el-dialog></div>
</template><script>export default {name: "ArticleDetail",data() {return {article: {},user: localStorage.getItem("user") ? JSON.parse(localStorage.getItem("user")) : {},comments: [],commentForm: {},id: this.$route.query.id,dialogFormVisible: false,}},created() {this.load()this.loadComment()},methods: {load() {const id = this.$route.query.idthis.request.get("/article/" + id).then(res => {this.article = res.data});},loadComment() {this.request.get("/comment/tree/" + this.id).then(res => {this.comments = res.data})},save() {if (!this.user.id) {this.$message.warning("请登录后操作")return}this.commentForm.articleId = this.idif (this.commentForm.contentReply) {this.commentForm.content = this.commentForm.contentReply}this.request.post("/comment", this.commentForm).then(res => {if (res.code === '200') {this.$message.success("评论成功")this.commentForm = {}  // 初始化评论对象内容this.loadComment()this.dialogFormVisible = false} else {this.$message.error(res.msg)}})},del(id) {this.request.delete("/comment/" + id).then(res => {if (res.code === '200') {this.$message.success("删除成功")this.loadComment()} else {this.$message.error("删除失败")}})},handleReply(pid) {this.commentForm = {pid: pid}this.dialogFormVisible = true},}}
</script><style scoped></style>
  1. 然后来到前端测试,发现可以实现多级评论的保存和删除功能了

总结

这就是本系列博文的全部内容了,一共23篇博文,跟着做下来肯定能把这个系统做好,当作毕设什么的都没问题。整个系列结束了,Web的学习也结束了,以后的内容应该和深度学习和源码漏洞检测相关,还请感兴趣的读者持续关注,谢谢大家!

SpringBoot和Vue集成Markdown和多级评论——基于SpringBoot和Vue的后台管理系统项目系列博客(二十三)相关推荐

  1. SpringBoot实现代码生成器——基于SpringBoot和Vue的后台管理系统项目系列博客(十)

    系列文章目录 系统功能演示--基于SpringBoot和Vue的后台管理系统项目系列博客(一) Vue2安装并集成ElementUI--基于SpringBoot和Vue的后台管理系统项目系列博客(二) ...

  2. SpringBoot实现1对1、1对多、多对多关联查询——基于SpringBoot和Vue的后台管理系统项目系列博客(十八)

    系列文章目录 系统功能演示--基于SpringBoot和Vue的后台管理系统项目系列博客(一) Vue2安装并集成ElementUI--基于SpringBoot和Vue的后台管理系统项目系列博客(二) ...

  3. SpringBoot实现分页查询——基于SpringBoot和Vue的后台管理系统项目系列博客(七)

    系列文章目录 系统功能演示--基于SpringBoot和Vue的后台管理系统项目系列博客(一) Vue2安装并集成ElementUI--基于SpringBoot和Vue的后台管理系统项目系列博客(二) ...

  4. 订单支付和评论——基于Django框架的天天生鲜电商网站项目系列博客(十五)

    系列文章目录 需求分析--基于Django框架的天天生鲜电商网站项目系列博客(一) 网站框架搭建--基于Django框架的天天生鲜电商网站项目系列博客(二) 用户注册模块--基于Django框架的天天 ...

  5. Vue集成markdown

    第一步 安装mavon-editor npm install mavon-editor --save 第二步 在main.js注册mavon-editor并使用 // 全局注册// import wi ...

  6. springboot实战项目——个人博客系统

    1.项目介绍 1.1项目效果 博客首页 登录功能 注册功能 文章分类 文章归档 文章页面 发布文章 (集成富文本编译器) 1.2项目使用技术 前端: vue element-ui 后端: Spring ...

  7. SpringBoot整合mybatis、shiro、redis实现基于数据库的细粒度动态权限管理系统实例(转)...

    SpringBoot整合mybatis.shiro.redis实现基于数据库的细粒度动态权限管理系统实例 shiro 目录(?)[+] 前言 表结构 maven配置 配置Druid 配置mybatis ...

  8. SpringBoot整合mybatis、shiro、redis实现基于数据库的细粒度动态权限管理系统实例...

    SpringBoot整合mybatis.shiro.redis实现基于数据库的细粒度动态权限管理系统实例 shiro 目录(?)[+] 1.前言 本文主要介绍使用SpringBoot与shiro实现基 ...

  9. Vue 2.x折腾记 - (16) 基于Ant Design Vue 封装一个配置式的表单搜索组件

    前言 这次的后台管理系统项目选型用了Vue来作为主技术栈: 因为前段时间用过React来写过项目(用了antd),感觉棒棒的. 所以这次就排除了Element UI,而采用了Ant Design Vu ...

最新文章

  1. 20篇「ACL2020」!抢先看自然语言处理2020在研究什么?
  2. js之数组,对象,类数组对象
  3. Log4j自定义Appender介绍
  4. P4198 楼房重建
  5. c 语言 模板函数,函数模板特化
  6. 分布式事务Seata的AT模式下两阶段提交原理
  7. Windwos命令工作笔记002---windows下tree命令列出文件目录打印到文件中_过滤文件不知道怎么做啊
  8. ASP.NET与JS交互
  9. 2021年中国国家级高新区 (科技园)数量、产值及营业收入分析[图]
  10. 极域课堂管理系统软件如何取消控制_极域新品发布会圆满落幕,你想看的都在这里...
  11. 贷款广告投放行为观察:价格高企主要客户是小贷公司,朋友圈转化效果最好
  12. 如何对CAD图纸快速测量?
  13. strconv,strings的学习(三)
  14. Matlab 火焰识别技术
  15. php微信转发无法显示标题图片,解决微信公众号分享朋友圈不显示标题图片描述的方法...
  16. 递归算法实例应用(五)
  17. 变态Java系列 String
  18. 程序员北漂没钱整租,如何爱上合租?
  19. Configure文件学习
  20. Android Ble 一连多笔记

热门文章

  1. SAP 创建销售订单和生产订单收货如何冲减独立需求
  2. 为服务器加装机械硬盘
  3. 初中英语听力计算机考试反馈,初中英语听力试题与答案
  4. 隐藏滚动条(滚动功能可用)
  5. java上传图片损坏_iview 文件上传二进制文件提示文件已经损坏
  6. eBay跨境电商好做吗?为什么要选择eBay平台?
  7. vue 中利用canvas 给pdf文件加水印---详细教程(附上完整代码)
  8. <selectKey>标签详解
  9. 2023最新爆点系统搭建H5
  10. 【已解决】SQL Server2014数据库自动备份之作业