Spring Boot + vue-element 开发个人博客项目实战教程(二十四、文章管理页面开发(3))

⭐ 作者简介:码上言


⭐ 代表教程:Spring Boot + vue-element 开发个人博客项目实战教程


⭐专栏内容:零基础学Java个人博客系统

👦 学习讨论群:530826149

后端代码gitee地址:https://gitee.com/xyhwh/personal_blog

前端代码gitee地址:https://gitee.com/xyhwh/personal_vue

项目部署视频

https://www.bilibili.com/video/BV1sg4y1A7Kv/?vd_source=dc7bf298d3c608d281c16239b3f5167b

前言

还是接着上边的来写,下面就剩下文章的展示一块了,马上这个系统就完结了,我看了一下即将写了一年,断断续续的。感谢大家的支持!

4、列表

这个列表相信大家已经写了很多遍了,现在可以说大概的思路应该掌握在手,这里我对后端又进行了处理,以前的bug也修复了一些,我这里先把后端改的代码来说一下。

4.1、功能修改

1、首先修改了根据分类id查找分类信息

这里的改动不大,主要是改动了查询的sql语句。

<select id="getById" resultMap="BaseResultMap">
    select * from person_category where category_id = #{categoryId, jdbcType=INTEGER}
</select>

2、修改文章查询的接口,这里改动的稍微有点大。

这边我把文章的标签给拆开了,减少了数据库查询的语句。

	@Override
    @PostConstruct
    public void init() {
        List<Article> articleList = articleMapper.findAll();
        try {
            getTagsOrCategory(articleList);
            for(Article article : articleList) {
                articleMap.put(article.getId(), article);
            }
            log.info("文章缓存数据加载完成");
        } catch (Exception e) {
            log.error("文章缓存数据加载失败!", e.getMessage());
        }
    }

    @Override
    public List<Article> getArticlePage(ArticleBO articleBO) {
        int pageNum = articleBO.getPageNum();
        int pageSize = articleBO.getPageSize();
        PageHelper.startPage(pageNum,pageSize);
        List<Article> articleList = articleMapper.getArticlePage(articleBO);
        getTagsOrCategory(articleList);
        return articleList;
    }


    public void getTagsOrCategory(List<Article> list) {
        if (list != null) {
            for (Article article : list) {
                //查询分类
                Category category = categoryService.findById(article.getCategoryId());
                if (category == null) {
                    article.setCategoryName("无分类");
                } else {
                    article.setCategoryName(category.getCategoryName());
                }
                List<Tag> tagList = new ArrayList<>();
                List<ArticleTag> articleTags = articleTagService.findArticleTagById(article.getId());
                if (articleTags != null) {
                    for (ArticleTag articleTag : articleTags) {
                        Tag tag = tagService.findTagById(articleTag.getTagId());
                        tagList.add(tag);
                    }
                }
                article.setTagList(tagList);
            }
        }
    }

查询的接口如参要再包一层body

   /**
     * 文章列表
     * @param articleBO
     * @return
     */
    @ApiOperation(value = "文章列表")
    @PostMapping("list")
    public JsonResult<Object> listPage(@RequestBody @Valid PageRequestApi<ArticleBO> articleBO) {
        List<Article> articleList = articleService.getArticlePage(articleBO.getBody());
        PageInfo pageInfo = new PageInfo(articleList);
        PageRequest pageRequest = new PageRequest();
        pageRequest.setPageNum(articleBO.getBody().getPageNum());
        pageRequest.setPageSize(articleBO.getBody().getPageSize());
        PageResult pageResult = PageUtil.getPageResult(pageRequest, pageInfo);
        return JsonResult.success(pageResult);
    }

ArticleBO.java类:

package com.blog.personalblog.bo;

import lombok.Data;

/**
 * @author: SuperMan
 * @create: 2021-12-31
 */
@Data
public class ArticleBO {

    /**
     * 分类id
     */
    private Integer categoryId;

    /**
     * 发布,默认0, 0-发布, 1-草稿
     */
    private Integer artStatus;

    /**
     * 文章标题
     */
    private String title;

    /**
     * 页码
     */
    private int pageNum;

    /**
     * 每页的数据条数
     */
    private int pageSize;
}

大家对以上的代码应该都能看的懂,我们再去修改一下xml文件。以下只是删掉了对标签的查询。

    <resultMap id="BaseResultMap" type="com.blog.personalblog.entity.Article">
        <result column="id" jdbcType="INTEGER" property="id"/>
        <result column="author" jdbcType="VARCHAR" property="author"/>
        <result column="title" jdbcType="VARCHAR" property="title"/>
        <result column="user_id" jdbcType="INTEGER" property="userId"/>
        <result column="category_id" jdbcType="INTEGER" property="categoryId"/>
        <result column="content" jdbcType="VARCHAR" property="content"/>
        <result column="views" jdbcType="BIGINT" property="views"/>
        <result column="total_words" jdbcType="BIGINT" property="totalWords"/>
        <result column="commentable_id" jdbcType="INTEGER" property="commentableId"/>
        <result column="art_status" jdbcType="INTEGER" property="artStatus"/>
        <result column="description" jdbcType="VARCHAR" property="description"/>
        <result column="image_url" jdbcType="VARCHAR" property="imageUrl"/>
        <result column="create_time" jdbcType="TIMESTAMP" property="createTime"/>
        <result column="update_time" jdbcType="TIMESTAMP" property="updateTime"/>
        <result column="categoryname" jdbcType="VARCHAR" property="categoryName"></result>
    </resultMap>

<select id="getArticlePage" resultMap="BaseResultMap" parameterType="com.blog.personalblog.bo.ArticleBO">
        SELECT
        a.*,
        u.category_name categoryname
        FROM person_article a
        left JOIN person_category u on a.category_id = u.category_id
        <where>
            <if test="articleBO.title != null">
                and a.title like '%${articleBO.title}%'
            </if>
            <if test="articleBO.categoryId != null">
                and a.category_id = #{articleBO.categoryId}
            </if>
            <if test="articleBO.artStatus != null">
                and a.art_status = #{articleBO.artStatus}
            </if>
        </where>

    </select>

3、根据文章id查找文章

这个功能我根据前端的需要,重新写了一个返回类,用做编辑的时候数据回显的时候使用。

新增了了一个vo包,然后在包内新建一个ArticleVO.java

package com.blog.personalblog.vo;

import com.blog.personalblog.entity.Tag;
import lombok.Data;

import java.time.LocalDateTime;
import java.util.List;

/**
 * @author: SuperMan
 * @create: 2022-10-10
 **/

@Data
public class ArticleVO {
    /**
     * 文章id
     */
    private Integer id;

    /**
     * 作者
     */
    private String author;

    /**
     * 文章标题
     */
    private String title;

    /**
     * 用户id
     */
    private Integer userId;

    /**
     * 分类id
     */
    private Integer categoryId;

    /**
     * 文章内容
     */
    private String content;

    /**
     * 文章浏览量
     */
    private Long views;

    /**
     * 文章总字数
     */
    private Long totalWords;

    /**
     * 评论id
     */
    private Integer commentableId;

    /**
     * 发布,默认1, 1-发布, 2-仅我可见  3-草稿
     */
    private Integer artStatus;

    /**
     * 描述
     */
    private String description;

    /**
     * 文章logo
     */
    private String imageUrl;

    /**
     * 创建时间
     */
    private LocalDateTime createTime;

    /**
     * 更新时间
     */
    private LocalDateTime updateTime;

    /**
     * 文章标签
     */
    private List<Tag> tagList;

    private List<String> tagNameList;

    /**
     * 分类名称
     */
    private String categoryName;
}

然后修改查询的接口

    /**
     * 根据文章id查找文章
     * @param articleId
     * @return
     */
    ArticleVO findById(Integer articleId);

实现类:

   @Override
   public ArticleVO findById(Integer articleId) {
        Article article = articleMap.get(articleId);

        ArticleVO articleVO = BeanUtil.copyProperties(article, ArticleVO.class);
        List<String> tagNameList = new ArrayList<>();
        if (articleVO != null) {
            if (articleVO.getTagList() != null) {
                for (Tag tag : articleVO.getTagList()) {
                    tagNameList.add(tag.getTagName());
                }
            }
        }
        articleVO.setTagNameList(tagNameList);
        articleVO.setCategoryName(article.getCategoryName());
        return articleVO;
    }

接口也要修改一下返回类。

    /**
     * 根据文章id查找
     * @param id
     * @return
     */
    @ApiOperation(value = "根据文章id查找")
    @GetMapping("/getArticle/{id}")
    @OperationLogSys(desc = "根据文章id查找", operationType = OperationType.SELECT)
    public JsonResult<Object> getArticleById(@PathVariable(value = "id") int id) {
        ArticleVO article = articleService.findById(id);
        return JsonResult.success(article);
    }

基本上就修改了这几个地方,接下来开始写文章列表的页面。

首先在article.js文件中修改一下根据id获取文章的接口地址。

export function getArticleById(id){
  return request({
    url: '/article/getArticle/' + id,
    method: 'get'
  })
}

还有之前我们点击发布文章之后,没有返回到列表页,现在我们先添加上这个功能,只要在之前写的方法里添加上跳转的地址即可。

添加这一句话:this.$router.push("/articles/list");

 var body = this.article;
      addArticle(body).then(res => {
        if(res.code === 200) {
          this.$notify({
              title: "文章发表成功",
              message: `文章《${this.article.title}》发表成功!`,
              type: "success",
          });
          this.$router.push("/articles/list");
        } else {
          this.$notify({
              title: "文章发表失败",
              message: `文章《${this.article.title}》发表失败!`,
              type: "error",
          });
        }
         this.showDialog = false;
     })

同时在发布草稿的方法里也要加上这一句。

  // ------- 保存草稿
    saveDraft() {
      this.article.artStatus = 3;
      if (this.article.title.trim() == "") {
        this.$message.error("文章标题不能为空");
        return false;
      }
      if (this.article.content.trim() == "") {
        this.$message.error("文章内容不能为空");
        return false;
      }
      var body = this.article;
      addArticle(body).then(res => {
        if(res.code === 200) {
          this.$message({
            type: 'success',
            message: '保存草稿成功!'
          });
          this.$router.push("/articles/list");
        } else {
          this.$message({
            type: 'error',
            message: '保存草稿失败!'
          });
        }
      })
    },

4.2、列表页面

页面和其他的列表差不多,这里我按照模块展示。

我先将return方法里的参数写出来。

data() {
    return {
      list: null,
      listLoading: true,
      count: 0,
      listQuery: {
        pageNum: 1,
        pageSize: 10,
        categoryId: null,
        artStatus: null,
        title: null
      },
      categoryId: null,
      categoryList: [],
      tagId: null,
      tagList: [],
      title: null,
      typeList: [
        {
          value: 1,
          label: "发布"
        },
        {
          value: 2,
          label: "仅我可见"
        },
        {
          value: 3,
          label: "草稿"
        }
      ],
      artStatus: null,
      views: null,
      totalWords: null,
      description: null
    }
  },

然后将接口导入进来

import { articleList, deleteArticle } from '@/api/article'
import { getCategory } from '@/api/category'
import { getTag } from '@/api/tag'

接着写页面功能。

    <!-- 设置标题文章管理 -->
    <div slot="header" class="clearfix">
      <span>文章列表</span>
    </div>

4.2.1、分类查询

废话不多说直接上代码,完整代码再最后,可直接跳过看完整代码。

     <!-- 文章分类 -->
        <el-select
          clearable
          size="small"
          v-model="categoryId"
          filterable
          placeholder="请选择分类"
          style="margin-right:1rem"
        >
          <el-option
            v-for="item in categoryList"
            :key="item.id"
            :label="item.categoryName"
            :value="item.categoryId"
          />
        </el-select>

这里遍历了categoryList,而这个list则是查询全部分类获取的,所以我们要写一个方法来查询分类,还要在页面初始的时候就要查询出来。接口还是那个添加文章的分类下拉的。

getCategoriesList() {
      var categoryName = "";
      getCategory({categoryName}).then(response => {
         this.categoryList = response.data;
      })
},

现在是有值了,然后再初始化页面的时候就加载完成。

  created() {
    this.getList();
    this.getCategoriesList();
  },

好啦,这时候可以看一下页面:

在这里插入图片描述

4.2.2、文章类型查询

接下来我们再继续写文章的类型查询。

<!-- 文章类型 -->
  <el-select
    clearable
    v-model="artStatus"
    placeholder="请选择文章类型"
    size="small"
    style="margin-right:1rem"
    >
    <el-option
      v-for="item in typeList"
      :key="item.value"
      :label="item.label"
      :value="item.value"
    />
  </el-select>

typeList这个数据就是data方法中的数组,在上边已经列出来了

typeList: [
        {
          value: 1,
          label: "发布"
        },
        {
          value: 2,
          label: "仅我可见"
        },
        {
          value: 3,
          label: "草稿"
        }
],

在这里插入图片描述

同样也要在页面加载的时候一起加载数据,将方法也要放到created中

 created() {
    this.getList();
    this.getCategoriesList();
    this.getTagsList();
  },

4.2.3、文章标题查询

还有一个标题的搜索和点击搜索的按钮,当点击搜索的按钮触发查询的接口。

    	<!-- 文章名 -->
        <el-input
          clearable
          v-model="title"
          prefix-icon="el-icon-search"
          size="small"
          placeholder="请输入文章名"
          style="width:200px"
          @keyup.enter.native="searchArticles"
        />

        <el-button
          type="primary"
          size="small"
          icon="el-icon-search"
          style="margin-left:1rem"
          @click="searchArticles"
        >
          搜索
        </el-button>

这里用到了一个方法:searchArticles

searchArticles() {
  this.getList();
},

这里面又调用了getList方法

getList() {
      this.listLoading = true
      this.listQuery.categoryId = this.categoryId;
      this.listQuery.title = this.title;
      this.listQuery.artStatus = this.artStatus;

      var body = this.listQuery;
      articleList({body}).then(response => {
        this.list = response.data.result
        this.count = response.data.totalSize
        this.listLoading = false
      })
  },

下面可以写数据展示的表格了,这个没什么好说的,直接上代码

<el-table v-loading="listLoading" :data="list" fit highlight-current-row style="width: 98%; margin-top:30px;">
      <el-table-column align="center" label="ID" >
        <template slot-scope="scope">
          <span>{{ scope.row.id }}</span>
        </template>
      </el-table-column>

      <el-table-column label="文章封面" width="180" align="center">
        <template slot-scope="scope">
          <img
            class="article-cover"
            :src=" scope.row.imageUrl" />
        </template>
      </el-table-column>

      <!-- 文章标题 -->
      <el-table-column prop="title" label="标题" align="center" />

      <!-- 文章分类 -->
      <el-table-column prop="categoryName" label="分类" width="110" align="center"/>

      <!-- 文章标签 -->
      <el-table-column prop="tagList" label="标签" width="170" align="center">
        <template slot-scope="scope">
          <el-tag
            v-for="item of scope.row.tagList"
            :key="item.id"
            style="margin-right:0.2rem;margin-top:0.2rem"
          >
            {{ item.tagName }}
          </el-tag>
        </template>
      </el-table-column>

      <!-- 文章浏览量 -->
      <el-table-column
        prop="views"
        label="浏览量"
        width="70"
        align="center"
      >
        <template slot-scope="scope">
          <span v-if="scope.row.views">
            {{ scope.row.views }}
          </span>
          <span v-else>0</span>
        </template>
      </el-table-column>
      <!-- 文章总字数 -->
      <el-table-column
        prop="totalWords"
        label="总字数"
        width="70"
        align="center"
      >
        <template slot-scope="scope">
          <span v-if="scope.row.totalWords">
            {{ scope.row.totalWords }}
          </span>
          <span v-else>0</span>
        </template>
      </el-table-column>

      <!-- 文章描述 -->
      <el-table-column prop="description" label="描述" align="center" />

      <el-table-column align="center" label="操作" width="180">
        <template slot-scope="scope">
          <el-button type="primary" size="mini" icon="el-icon-edit" @click="editArticle(scope.row.id)">编辑</el-button>
          <el-button type="danger" size="small" icon="el-icon-delete" @click="deleteArticleById(scope.row.id)" >删除</el-button>
        </template>
      </el-table-column>

    </el-table>

    <!-- 分页 -->
    <el-pagination
      class="pagination-container"
      background
      @size-change="handleSizeChange"
      @current-change="handleCurrentChange"
      :current-page="this.listQuery.pageNum"
      :page-size="this.listQuery.pageSize"
      :total="count"
      :page-sizes="[10, 20, 30]"
      layout="total, sizes, prev, pager, next, jumper"
    />

方法:

 handleSizeChange(pageSize) {
      this.listQuery.pageSize = pageSize
      this.getList()
    },
 handleCurrentChange(pageNum) {
      this.listQuery.pageNum = pageNum
      this.getList()
  },

以上就是展示的功能,下面我们来写删除和编辑的,这个就比较简单了,和之前的基本上一样。

5、删除

删除后端的接口传的参数格式做了修改,我记得没有写。这里我先写出来,大家如果没有更改就修改一下,如果修改了就过掉。

	/**
     * 删除文章
     * @return
     */
    @ApiOperation(value = "删除文章")
    @DeleteMapping("/delete")
    @OperationLogSys(desc = "删除文章", operationType = OperationType.DELETE)
    public JsonResult<Object> articleDelete(@RequestParam(value = "id") int id) {
        articleService.deleteArticle(id);
        return JsonResult.success();
    }

前端接口:

export function deleteArticle(id) {
  return request({
    url: '/article/delete',
    method: 'delete',
    params: { id }
  })
}

删除的方法:

 deleteArticleById (id) {
      this.$confirm('此操作将永久删除该文章, 是否继续?', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(() => {
        deleteArticle(id).then(response => {
           this.$message({
            type: 'success',
            message: '删除成功!'
          })
           this.getList()
        }).catch(() => {
          console.log('error')
        })
      }).catch(() => {
         this.$message({
            type: 'error',
            message: '你已经取消删除该文章!'
          })
      })
    },

这里没啥好说的,和之前的删除操作基本上一样。

6、修改功能

修改功能稍微做了一点的改变,我们看一下表格的操作栏的编辑按钮

<el-button type="primary" size="mini" icon="el-icon-edit" @click="editArticle(scope.row.id)">编辑</el-button>

点击时间绑定了一个方法,我们要传入文章的id

 editArticle(id) {
      this.$router.push({ name: 'Addrticles', params: { id: id }});
  },

这个和之前的公告差不多,只是将这个跳转提取到了方法内实现。

相对应的,在add页面中进行接收。

  created() {
    const id = this.$route.params.id;
    if(id) {
      getArticleById(id).then((res) => {
        
        console.log(res.data)
        this.article = res.data;
      });
    }
  },

这是编辑的功能也修改好了。

在这里插入图片描述
看着还可以,大家可以自己美化一下页面,到这里文章的所有功能基本上全部完成了。
以下是列表的全部代码:

<template>
    <el-card class="box-card">

    <!-- 设置标题文章管理 -->
    <div slot="header" class="clearfix">
      <span>文章列表</span>
    </div>

    <!-- 文章按条件查找 -->
     <div style="margin-left:auto">
       <!-- 文章分类 -->
        <el-select
          clearable
          size="small"
          v-model="categoryId"
          filterable
          placeholder="请选择分类"
          style="margin-right:1rem"
        >
          <el-option
            v-for="item in categoryList"
            :key="item.id"
            :label="item.categoryName"
            :value="item.categoryId"
          />
        </el-select>
        <!-- 文章类型 -->
        <el-select
          clearable
          v-model="artStatus"
          placeholder="请选择文章类型"
          size="small"
          style="margin-right:1rem"
        >
          <el-option
            v-for="item in typeList"
            :key="item.value"
            :label="item.label"
            :value="item.value"
          />
        </el-select>
        <!-- 文章名 -->
        <el-input
          clearable
          v-model="title"
          prefix-icon="el-icon-search"
          size="small"
          placeholder="请输入文章名"
          style="width:200px"
          @keyup.enter.native="searchArticles"
        />

        <el-button
          type="primary"
          size="small"
          icon="el-icon-search"
          style="margin-left:1rem"
          @click="searchArticles"
        >
          搜索
        </el-button>
     </div>

    <el-table v-loading="listLoading" :data="list" fit highlight-current-row style="width: 98%; margin-top:30px;">
      <el-table-column align="center" label="ID" >
        <template slot-scope="scope">
          <span>{{ scope.row.id }}</span>
        </template>
      </el-table-column>

      <el-table-column label="文章封面" width="180" align="center">
        <template slot-scope="scope">
          <img
            class="article-cover"
            :src=" scope.row.imageUrl" />
        </template>
      </el-table-column>

      <!-- 文章标题 -->
      <el-table-column prop="title" label="标题" align="center" />

      <!-- 文章分类 -->
      <el-table-column prop="categoryName" label="分类" width="110" align="center"/>

      <!-- 文章标签 -->
      <el-table-column prop="tagList" label="标签" width="170" align="center">
        <template slot-scope="scope">
          <el-tag
            v-for="item of scope.row.tagList"
            :key="item.id"
            style="margin-right:0.2rem;margin-top:0.2rem"
          >
            {{ item.tagName }}
          </el-tag>
        </template>
      </el-table-column>

      <!-- 文章浏览量 -->
      <el-table-column
        prop="views"
        label="浏览量"
        width="70"
        align="center"
      >
        <template slot-scope="scope">
          <span v-if="scope.row.views">
            {{ scope.row.views }}
          </span>
          <span v-else>0</span>
        </template>
      </el-table-column>
      <!-- 文章总字数 -->
      <el-table-column
        prop="totalWords"
        label="总字数"
        width="70"
        align="center"
      >
        <template slot-scope="scope">
          <span v-if="scope.row.totalWords">
            {{ scope.row.totalWords }}
          </span>
          <span v-else>0</span>
        </template>
      </el-table-column>

      <!-- 文章描述 -->
      <el-table-column prop="description" label="描述" align="center" />

      <el-table-column align="center" label="操作" width="180">
        <template slot-scope="scope">
          <el-button type="primary" size="mini" icon="el-icon-edit" @click="editArticle(scope.row.id)">编辑</el-button>
          <el-button type="danger" size="small" icon="el-icon-delete" @click="deleteArticleById(scope.row.id)" >删除</el-button>
        </template>
      </el-table-column>

    </el-table>

    <!-- 分页 -->
    <el-pagination
      class="pagination-container"
      background
      @size-change="handleSizeChange"
      @current-change="handleCurrentChange"
      :current-page="this.listQuery.pageNum"
      :page-size="this.listQuery.pageSize"
      :total="count"
      :page-sizes="[10, 20, 30]"
      layout="total, sizes, prev, pager, next, jumper"
    />

    </el-card>
</template>

<script>

import { articleList, deleteArticle } from '@/api/article'
import { getCategory } from '@/api/category'
import { getTag } from '@/api/tag'

export default {
  name: 'articleList',

  created() {
    this.getList();
    this.getCategoriesList();
    this.getTagsList();
  },

  data() {
    return {
      list: null,
      listLoading: true,
      count: 0,
      listQuery: {
        pageNum: 1,
        pageSize: 10,
        categoryId: null,
        artStatus: null,
        title: null
      },
      categoryId: null,
      categoryList: [],
      tagId: null,
      tagList: [],
      title: null,
      typeList: [
        {
          value: 1,
          label: "发布"
        },
        {
          value: 2,
          label: "仅我可见"
        },
        {
          value: 3,
          label: "草稿"
        }
      ],
      artStatus: null,
      views: null,
      totalWords: null,
      description: null
    }
  },

  methods: {

    getList() {
      this.listLoading = true
      this.listQuery.categoryId = this.categoryId;
      this.listQuery.title = this.title;
      this.listQuery.artStatus = this.artStatus;

      var body = this.listQuery;
      articleList({body}).then(response => {
        this.list = response.data.result
        this.count = response.data.totalSize
        this.listLoading = false
      })
    },

    editArticle(id) {
      this.$router.push({ name: 'Addrticles', params: { id: id }});
    },

    getCategoriesList() {
      var categoryName = "";
      getCategory({categoryName}).then(response => {
         this.categoryList = response.data;
      })
    },

    getTagsList() {
      var tagName = "";
      getTag({tagName}).then(response => {
         this.tagList = response.data;
      })
    },

    searchArticles() {
      this.getList();
    },

    handleSizeChange(pageSize) {
      this.listQuery.pageSize = pageSize
      this.getList()
    },
    handleCurrentChange(pageNum) {
      this.listQuery.pageNum = pageNum
      this.getList()
    },


    deleteArticleById (id) {
      this.$confirm('此操作将永久删除该文章, 是否继续?', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(() => {
        deleteArticle(id).then(response => {
           this.$message({
            type: 'success',
            message: '删除成功!'
          })
           this.getList()
        }).catch(() => {
          console.log('error')
        })
      }).catch(() => {
         this.$message({
            type: 'error',
            message: '你已经取消删除该文章!'
          })
      })
    },

  },

 
}
</script>

<style rel="stylesheet/scss" lang="scss" scoped>
  .pagination-container {
    float: right;
    margin-top: 1.25rem;
    margin-bottom: 1.25rem;
  }
  .box-card {
    width: 98%;
    margin: 1%;
  }
  .clearfix:before,
  .clearfix:after {
    display: table;
    content: "";
  }
  .clearfix:after {
    clear: both
  }
  .clearfix span {
    font-weight: 600;
  }
  .article-cover {
    position: relative;
    width: 100%;
    height: 90px;
    border-radius: 4px;
  }
  .article-cover::after {
    content: "";
    background: rgba(0, 0, 0, 0.3);
    position: absolute;
    top: 0;
    bottom: 0;
    left: 0;
    right: 0;
  }

</style>

7、总结

目前为止我们这个全部的功能已经基本上实现了,现在我们接下来要美化一下我们的系统,大家也发现当登录进来的首页还是空的,登录页面也比较的单调丑陋,所以可能还需要一篇来扩展一下我们的系统,可能也是最后一篇了。

关于项目的发布,不知道还要不要写,项目在linux上所需要的环境搭建,我会放到我的公众号上,这里不再写搭建的内容,这里征求一下意见,如果有需要我就写一下或者直接私信我,没有我就不再写了,这个项目就完结了。

在这里插入图片描述

上一篇:Spring Boot + vue-element 开发个人博客项目实战教程(二十三、文章管理页面开发(2))

下一篇:Spring Boot + vue-element 开发个人博客项目实战教程(二十五、项目完善及扩展(前端部分))

  • 3
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

码上言

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值