Spring Boot + vue-element 开发个人博客项目实战教程(二十四、添加文章页面弹出层)

165 阅读4分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第14天,点击查看活动详情

1、编写添加文章页面弹出层

1.1、添加标签和分类查询接口

在/src/api文件下找到category.js接口,我们将刚才新添加的分类查询接口加入进来

export function getCategory(data) {
  return request({
    url: '/category/getCategory',
    method: 'post',
    data
  })
}

在/src/api文件下找到tag.js接口,我们将刚才新添加的标签查询接口加入进来

export function getTag(data) {
  return request({
    url: '/tag/selectTag',
    method: 'post',
    data
  })
}

1.2、添加文章分类功能

文章分类功能是在我们弹出框里,为了方便大家学习,我现将业务逻辑分析一下,然后再来写具体的代码,这样就能清晰的分析代码,进而读懂代码了。

文章分类业务分析:

首先我们写完文章之后,点击发布文章,然后跳出一个弹出框,需要我们填写文章的一些属性,我们先重点来说分类,然后标签就和这类似了。

image.png

上图是我点击发布文章之后弹出的,我们先设置一个添加分类的按钮,这时我们会触发查询分类的接口,将数据库中的所有分类全部查询出来。然后我们可以进行搜索或者自定义分类,使用了vue的el-autocomplete搜索框来实现。

  • 搜索:当我们在输入框输入数据时,就会请求接口进行条件查询。
  • 自定义:直接在输入框中输入完分类的名称之后,直接回车即可。

image.png

接下来我们用代码进行分析。

这里主要是分析弹出框里面的内容。

当你选择完分类之后,会在页面上展示出来分类的名称。

<el-tag type="success" v-show="article.categoryName" style="margin:0 1rem 0 0" :closable="true" @close="removeCategory">
   {{ article.categoryName }}
</el-tag>

removeCategory()方法的实现:

removeCategory() {
      this.article.categoryName = null;
},

以下是选择分类的功能模块

  • el-popover 是ElementUI封装的一个弹窗组件,类似于el-tooltip,弹窗中也可以自定义内容等。
  • autocomplete 是一个可带输入建议的输入框组件,具体官方文档:element.eleme.cn/#/zh-CN/com…
        <!-- 分类选项 -->
           <el-popover placement="bottom-start" width="460" trigger="click" v-if="!article.categoryName">
            <div class="popover-title">分类</div>
            <!-- 搜索框 -->
            <el-autocomplete
              style="width:100%"
              v-model="categoryName"
              :fetch-suggestions="findCategories"
              placeholder="请输入分类名搜索,如果自定义分类,输入完成之后直接回车即可!"
              :trigger-on-focus="false"
              @keyup.enter.native="saveCategory"
              @select="handleFindCategories"
            >
              <template slot-scope="{ item }">
                <div>{{ item.categoryName }}</div>
              </template>
            </el-autocomplete>

            <!-- 分类数据展示 -->
            <div class="popover-container">
              <div class="category-item" v-for="item of categoryList" :key="item.id" @click="addCategory(item)">
                {{ item.categoryName }}
              </div>
            </div>
            <el-button type="success" plain slot="reference" size="small"> 添加分类 </el-button>

           </el-popover>

其余的也没什么好说的,大家看一下应该都能看懂,之前也讲过一部分,比如分类数据展示,就是个list数据的展示等操作。

js的部分主要实现一些方法的操作,这里我们还引入了分类的接口。后边还会引入标签的接口。

import { addArticle, updateArticle, getArticleById } from '@/api/article'
import { getCategory } from '@/api/category'


data() {
    return {
      showDialog: false,
      categoryName: "",
      categoryList: [],
      article: {
        id: "",
        title: "",
        categoryId: "",
        content: "",
        categoryName: null
      }
    }
  },

methods: {

     // 打开文章信息填写框
    openDialog() {
      if (this.article.title.trim() == "") {
        this.$message.error("文章标题为空,请填写文章标题");
        return false;
      }
      if (this.article.content.trim() == "") {
        this.$message.error("文章内容为空,请填写文章内容");
        return false;
      }
      this.getCategoriesList();
      this.showDialog = true;
    },

    //------分类的业务处理开始------
    getCategoriesList() {
      var categoryName = "";
      getCategory({categoryName}).then(response => {
         this.categoryList = response.data;
      })
    },
    removeCategory() {
      this.article.categoryName = null;
    },
    //搜索分类名称
    findCategories(categoryName, cb) {
       getCategory({categoryName}).then(response => {
         cb(response.data);
       })
    },
    saveCategory() {
      if (this.categoryName.trim() != "") {
        this.addCategory({
          categoryName: this.categoryName
        });
        this.categoryName = "";
      }
    },
    addCategory(item) {
      this.article.categoryName = item.categoryName;
    },
    handleFindCategories(item) {
      this.addCategory({
        categoryName: item.categoryName
      });
    },
  //------分类的业务处理结束------

handleSubmit() {
        this.showDialog = true;
        var body = this.article;
      
    },
    
    handleCancel() {
      this.showDialog = false;
    },
  }


//css
.popover-title {
    margin-bottom: 1rem;
    text-align: center;
  }
  .category-item {
    cursor: pointer;
    padding: 0.6rem 0.5rem;
  }
  .category-item:hover {
    background-color: #f0f9eb;
    color: #67c23a;
  }

具体的代码我会将放在这一节的最后展示,大家先进行学习,有错误了再去对照完整的代码看一下。当你选择完分类之后,会在页面上展示出来分类的名称。

<el-tag type="success" v-show="article.categoryName" style="margin:0 1rem 0 0" :closable="true" @close="removeCategory">
   {{ article.categoryName }}
</el-tag>

removeCategory()方法的实现:

removeCategory() {
      this.article.categoryName = null;
},

以下是选择分类的功能模块

  • el-popover 是ElementUI封装的一个弹窗组件,类似于el-tooltip,弹窗中也可以自定义内容等。
  • autocomplete 是一个可带输入建议的输入框组件,具体官方文档:element.eleme.cn/#/zh-CN/com…
        <!-- 分类选项 -->
           <el-popover placement="bottom-start" width="460" trigger="click" v-if="!article.categoryName">
            <div class="popover-title">分类</div>
            <!-- 搜索框 -->
            <el-autocomplete
              style="width:100%"
              v-model="categoryName"
              :fetch-suggestions="findCategories"
              placeholder="请输入分类名搜索,如果自定义分类,输入完成之后直接回车即可!"
              :trigger-on-focus="false"
              @keyup.enter.native="saveCategory"
              @select="handleFindCategories"
            >
              <template slot-scope="{ item }">
                <div>{{ item.categoryName }}</div>
              </template>
            </el-autocomplete>

            <!-- 分类数据展示 -->
            <div class="popover-container">
              <div class="category-item" v-for="item of categoryList" :key="item.id" @click="addCategory(item)">
                {{ item.categoryName }}
              </div>
            </div>
            <el-button type="success" plain slot="reference" size="small"> 添加分类 </el-button>

           </el-popover>

其余的也没什么好说的,大家看一下应该都能看懂,之前也讲过一部分,比如分类数据展示,就是个list数据的展示等操作。

js的部分主要实现一些方法的操作,这里我们还引入了分类的接口。后边还会引入标签的接口。

import { addArticle, updateArticle, getArticleById } from '@/api/article'
import { getCategory } from '@/api/category'


data() {
    return {
      showDialog: false,
      categoryName: "",
      categoryList: [],
      article: {
        id: "",
        title: "",
        categoryId: "",
        content: "",
        categoryName: null
      }
    }
  },

methods: {

     // 打开文章信息填写框
    openDialog() {
      if (this.article.title.trim() == "") {
        this.$message.error("文章标题为空,请填写文章标题");
        return false;
      }
      if (this.article.content.trim() == "") {
        this.$message.error("文章内容为空,请填写文章内容");
        return false;
      }
      this.getCategoriesList();
      this.showDialog = true;
    },

    //------分类的业务处理开始------
    getCategoriesList() {
      var categoryName = "";
      getCategory({categoryName}).then(response => {
         this.categoryList = response.data;
      })
    },
    removeCategory() {
      this.article.categoryName = null;
    },
    //搜索分类名称
    findCategories(categoryName, cb) {
       getCategory({categoryName}).then(response => {
         cb(response.data);
       })
    },
    saveCategory() {
      if (this.categoryName.trim() != "") {
        this.addCategory({
          categoryName: this.categoryName
        });
        this.categoryName = "";
      }
    },
    addCategory(item) {
      this.article.categoryName = item.categoryName;
    },
    handleFindCategories(item) {
      this.addCategory({
        categoryName: item.categoryName
      });
    },
  //------分类的业务处理结束------

handleSubmit() {
        this.showDialog = true;
        var body = this.article;
      
    },
    
    handleCancel() {
      this.showDialog = false;
    },
  }


//css
.popover-title {
    margin-bottom: 1rem;
    text-align: center;
  }
  .category-item {
    cursor: pointer;
    padding: 0.6rem 0.5rem;
  }
  .category-item:hover {
    background-color: #f0f9eb;
    color: #67c23a;
  }

具体的代码我会将放在这一节的最后展示,大家先进行学习,有错误了再去对照完整的代码看一下。