SpringBoot+Vue+Mybatis-plus 博客(三):完成搜索及博客列表展示功能前后端

SpringBoot+Vue+Mybatis-plus 博客(一):完成博客后台前端登录页面、后端登录接口
SpringBoot+Vue+Mybatis-plus 博客(二):完成登录的前后端对接、完善左侧菜单栏
SpringBoot+Vue+Mybatis-plus 博客(三):完成搜索及博客列表展示功能前后端
SpringBoot+Vue+Mybatis-plus 博客(四):完成发布文章、编辑文章、删除文章及查询文章功能
SpringBoot+Vue+Mybatis-plus 博客(五):完成分类管理和标签管理前后端对接
SpringBoot+Vue+Mybatis-plus 博客(六):完成评论管理前后端交互
SpringBoot+Vue+Mybatis-plus 博客(七):完成友链管理前后端对接

一、博客管理

1、在AllBlogs添加标签页

先看效果:
在这里插入图片描述
开始实现:

https://element.eleme.cn/#/zh-CN/component/tabs
在这里插入图片描述
在这里插入图片描述

<template>
  <div>
    <el-tabs v-model="activeName" @tab-click="handleClick">
      <el-tab-pane label="全部(120)" name="first">全部(120</el-tab-pane>
      <el-tab-pane label="原创(20)" name="second">原创(20</el-tab-pane>
      <el-tab-pane label="转载(20)" name="third">转载(20</el-tab-pane>
      <el-tab-pane label="草稿(20)" name="fourth">草稿(20</el-tab-pane>
      <el-tab-pane label="公开(50)" name="fifth">公开(50</el-tab-pane>
      <el-tab-pane label="私密(10)" name="sixth">私密(10</el-tab-pane>
      <el-tab-pane label="回收站(20)" name="serven">回收站(20</el-tab-pane>
    </el-tabs>
  </div>
</template>

<script>
export default {
  name: 'AllBlogs',
  data () {
   return {
    activeName: 'second'
   }
  },
  methods:{
    handleClick(tab, event) {
        console.log(tab.index);
    }
  }
}
</script>

<style scoped>

</style>

2、【全部】文章展示页面

在这里插入图片描述
AllBlogs.vue

<template>
  <div>
    <el-tabs v-model="activeName" @tab-click="handleClick" style="margin-top: 10px;">
      <el-tab-pane label="全部(120)" name="first">
         <!-- 搜索 -->
        <el-input size="small" v-model="input_title" placeholder="请输入标题,可回车搜索..." prefix-icon="el-icon-search"
        style="width: 400px;margin-right: 10px;"></el-input>
        <el-button size="small" type="primary" icon="el-icon-search">搜索</el-button>
        <el-button size="small" type="primary">高级搜索</el-button>

        <!-- 博客文章 -->
        <el-table
        :data="blogsData"
        stripe
        style="width: 100%">
        <el-table-column label="文章列表">
          <template slot-scope="scope">
            <el-card  class="box-card">
              <div style="font-size: 18px;">
                 <!-- v-if="!scope.row.shareStatement" 这里根据shareStatement属性判断文章是否为草稿 -->
                 <el-button size="mini" v-if="!scope.row.shareStatement" type="info" icon="el-icon-edit" circle></el-button>
                 {{scope.row.title}}
              </div>
              <div style="margin-top: 10px;">

                <el-tag size="small" style="margin-right: 10px;"  v-if="!scope.row.shareStatement" type="warning">草稿</el-tag>
                <el-tag style="margin-right: 10px;" v-if="scope.row.shareStatement" size="small">{{scope.row.flag}}</el-tag>
                <el-tag style="margin-right: 10px;" v-if="scope.row.shareStatement" size="small" type="info">{{scope.row.published}}</el-tag>
                <el-tag style="margin-right: 20px;" v-if="scope.row.shareStatement" size="small" type="success">{{scope.row.typeId}}</el-tag>
                <i style="margin-right: 20px;" class="el-icon-view"> {{scope.row.views}} </i>
                <i style="margin-right: 20px;" class="el-icon-chat-square"> {{scope.row.commentCount}} </i>
                <i style="margin-right: 20px;" class="el-icon-date"> {{scope.row.createTime}}</i>
                
                <el-button style="float: right;" type="danger" size="mini">删除</el-button>
                <el-button style="float: right; margin-right: 10px;" type="primary" size="mini">编辑</el-button>
               
              </div>

            

           </el-card>
          </template>
          
         </el-table-column>
       </el-table>

       <div style="margin-top: 20px;">
             <!-- 分页 -->
              <el-pagination
                background
                @size-change="handleSizeChange"
                @current-change="handleCurrentChange"
                :current-page="currentPage"
                :page-sizes="pagesizes"
                :page-size="pagesize"
                layout="total, sizes, prev, pager, next, jumper"
                :total="total">
              </el-pagination>
       </div>

      </el-tab-pane>

      <el-tab-pane label="原创(20)" name="second">原创(20</el-tab-pane>
      <el-tab-pane label="转载(20)" name="third">转载(20</el-tab-pane>
      <el-tab-pane label="草稿(20)" name="fourth">草稿(20</el-tab-pane>
      <el-tab-pane label="公开(50)" name="fifth">公开(50</el-tab-pane>
      <el-tab-pane label="私密(10)" name="sixth">私密(10</el-tab-pane>
      <el-tab-pane label="回收站(20)" name="serven">回收站(20</el-tab-pane>
    </el-tabs>

    
 
  </div>
</template>

<script>
export default {
  name: 'AllBlogs',
  data () {
   return {
    activeName: 'first',
    input_title: '', //输入框的值
    blogsData: [{   //文章数据
        title: '用于展示多条结构类似的数据,可对数据进行排序、筛选、对比或其他自定义操作',
        flag: '原创',
        published:'公开',
        createTime:'2020年12月07日 12:00:00',
        views:'999',
        commentCount:'99',
        typeId:'springboot学习',
        shareStatement:false,
      }, {
        title: '用于展示多条结构类似的数据,可对数据进行排序、筛选、对比或其他自定义操作',
        flag: '原创',
        published:'公开',
        createTime:'2020年12月07日 12:00:00',
        views:'999',
        commentCount:'99',
        typeId:'springboot学习',
        shareStatement:true,
      }],
      currentPage: 1,  //当前页
      total:100, //总记录数
      pagesize:10, //页面大小
      pagesizes:[10,20,30], //页面数组

    }
  },
  methods:{
    handleClick(tab, event) {
        console.log(tab.index);
    },
    // 分页的当前页
    handleCurrentChange(val) {
      console.log(`当前页: ${val}`);
    },
    //每页多少条
    handleSizeChange(val) {
        console.log(`每页 ${val} 条`);
      },
  }
}
</script>

<style scoped>

</style>

二、博客展示后端开发

1、修改RespBean

在这里插入图片描述

    public static RespBean build(){
        return new RespBean();
    }

2、分页查询 修改TBlogService

修改TBlogService
在这里插入图片描述

	/分页查询
    RespBean pageBlogs(Long current, Long limit, Boolean published, String flag, Boolean share_statement, Boolean is_delete);

3、修改TBlogServiceImpl

@Service
public class TBlogServiceImpl extends ServiceImpl<TBlogMapper, TBlog> implements TBlogService {

    @Autowired
    TBlogMapper tBlogMapper;

    RespBean respBean = RespBean.build();

    @Override
    public RespBean pageBlogs(Long current, Long limit, Boolean published, String flag,
                              Boolean share_statement, Boolean is_delete) {
        RespBean respBean = RespBean.build();
        //创建Page对象
        Page<TBlog> tBlogPage = new Page<>(current,limit);
        //构建条件
        QueryWrapper<TBlog> wrapper = new QueryWrapper<>();
        //获取传入讲师的条件是否为空
        //多条件组合查询
        //判断条件值是否为空,如果不为空拼接条件
        if (published != null){
            //构建条件
            wrapper.eq("published",published);
        }
        if (flag != null){
            //构建条件
            wrapper.eq("flag",flag);
        }
        if (share_statement != null){
            //构建条件
            wrapper.eq("share_statement",share_statement);
        }
        if (is_delete != null){
            //构建条件
            wrapper.eq("is_delete",is_delete);
        }
        
        //以更新时间排序(降序)
        wrapper.orderByDesc("update_time");
        
        //调用mybatis plus分页方法进行查询
        tBlogMapper.selectPage(tBlogPage,wrapper);

        //通过Page对象获取分页信息
        List<TBlog> tBlogList = tBlogPage.getRecords(); //每页的数据 list集合
        long size = tBlogPage.getSize(); //每页显示的条数
        long total = tBlogPage.getTotal(); //总记录数
        long pages = tBlogPage.getPages(); //总页数

        respBean.setStatus(200);
        respBean.setObj(tBlogPage);
        return respBean;
    }
}

4、修改TBlogController

在这里插入图片描述

@RestController
@RequestMapping("/blog")
public class TBlogController {

    @Autowired
    TBlogService tBlogService;

    RespBean respBean = RespBean.build();

    /**
     * 分页查询
     * @param current
     * @param size
     * @param published
     * @param flag
     * @param share_statement
     * @param is_delete
     * @return
     */
    @GetMapping("/getByPage")
    @ApiOperation("博客分页查询")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "current",value = "当前页") ,
            @ApiImplicitParam(name = "size",value = "每页的数量"),
            @ApiImplicitParam(name = "published",value = "是否公开"),
            @ApiImplicitParam(name = "flag",value = "原创或转载"),
            @ApiImplicitParam(name = "share_statement",value = "草稿"),
            @ApiImplicitParam(name = "is_delete",value = "是否已删除"),
    })
    public RespBean getByPage(Long current, Long size, Boolean published,
                              String flag, Boolean share_statement, Boolean is_delete){
        return tBlogService.pageBlogs(current, size,published,flag,share_statement,is_delete);
    }
}

5、测试

1)分页查询【全部】
在这里插入图片描述
对应
在这里插入图片描述
2)分页查询【原创】
在这里插入图片描述
对应:
在这里插入图片描述
3)分页查询【转载】
在这里插入图片描述
对应:
在这里插入图片描述

4)其他类似

6、根据标题查询

在这里插入图片描述
在TBlogService 添加:

    //根据博客标题查询
    RespBean getByTitle(String title);

在TBlogServiceImpl 添加:

    /**
     * 根据标题查询
     * @param title
     * @return
     */
    @Override
    public RespBean getByTitle(String title) {
       	RespBean respBean = RespBean.build();
        QueryWrapper<TBlog> queryWrapper = new QueryWrapper<TBlog>();
        queryWrapper.like("title",title);
        List<TBlog> tBlogList = tBlogMapper.selectList(queryWrapper);
        respBean.setStatus(200);
        respBean.setObj(tBlogList);
        return respBean;
    }

在 TBlogController中添加:

    /**
     * 根据博客标题查询
     * @param title
     * @return
     */
    @GetMapping("/getByTitle")
    @ApiOperation("通过文章标题查询")
    @ApiImplicitParam(name = "title",value = "文章的标题")
    public RespBean findByTitle(String title){
        return tBlogService.getByTitle(title);
    }

7、测试

在这里插入图片描述
在这里插入图片描述

8、日期格式化

在TBlogs加入注解:

  @JsonFormat(pattern="yyyy-MM-dd HH:mm:ss", timezone = "Asia/ShangHai")

在这里插入图片描述
在这里插入图片描述

三、博客展示前端对接

1、新建搜索专用子组件

SearchBlogsCom.vue
在这里插入图片描述

<template>
  <div>
        <!-- 博客文章 -->
        <el-table
            :data="blogsData"
            stripe
            style="width: 100%">
            <el-table-column label="文章列表">
            <template slot-scope="scope">
                <el-card  class="box-card">
                <div style="font-size: 18px;">
                    <!-- v-if="!scope.row.shareStatement" 这里根据shareStatement属性判断文章是否为草稿 -->
                    <el-button size="mini" v-if="!scope.row.shareStatement" type="info" icon="el-icon-edit" circle></el-button>
                    {{scope.row.title}}
                </div>
                <div style="margin-top: 10px;">

                    <el-tag size="small" style="margin-right: 10px;"  v-if="scope.row.isDelete" type="danger">已删除</el-tag>
                    <el-tag size="small" style="margin-right: 10px;"  v-if="!scope.row.shareStatement" type="warning">草稿</el-tag>
                    <el-tag style="margin-right: 10px;" v-if="scope.row.shareStatement" size="small">{{scope.row.flag}}</el-tag>
                    <el-tag style="margin-right: 20px;" v-if="scope.row.shareStatement" size="small" type="info">{{scope.row.published == '0' ? '私密' : '公开'}}</el-tag>
                    <i style="margin-right: 20px;" class="el-icon-view"> {{scope.row.views}} </i>
                    <i style="margin-right: 20px;" class="el-icon-chat-square"> {{scope.row.commentCount}} </i>
                    <i style="margin-right: 20px;" class="el-icon-date"> {{scope.row.createTime}}</i>
                    
                    <el-button style="float: right;" type="danger" size="mini">删除</el-button>
                    <el-button style="float: right; margin-right: 10px;" type="primary" size="mini">编辑</el-button>
                
                </div>

                </el-card>
            </template>
                
            </el-table-column>
        </el-table>

  </div>
</template>

<script>
export default {
  name: 'SearchBlogsCom',
  data () {
   return {
    blogsData: [], //文章数据

   }
  },
  props:["blogsData"], //接收父组件传过来的值
  methods:{
  }
}
</script>

<style scoped>

</style>

2、新建通用博客列表子组件

BlogListCom.vue
在这里插入图片描述

<template>
  <div>
        <!-- 博客文章 -->
        <el-table
            :data="blogsData"
            stripe
            style="width: 100%">
            <el-table-column label="文章列表">
            <template slot-scope="scope">
                <el-card  class="box-card">
                <div style="font-size: 18px;">
                    <!-- v-if="!scope.row.shareStatement" 这里根据shareStatement属性判断文章是否为草稿 -->
                    <el-button size="mini" v-if="!scope.row.shareStatement" type="info" icon="el-icon-edit" circle></el-button>
                    {{scope.row.title}}
                </div>
                <div style="margin-top: 10px;">

                    <el-tag size="small" style="margin-right: 10px;"  v-if="scope.row.isDelete" type="danger">已删除</el-tag>
                    <el-tag size="small" style="margin-right: 10px;"  v-if="!scope.row.shareStatement" type="warning">草稿</el-tag>
                    <el-tag style="margin-right: 10px;" v-if="scope.row.shareStatement" size="small">{{scope.row.flag}}</el-tag>
                    <el-tag style="margin-right: 20px;" v-if="scope.row.shareStatement" size="small" type="info">{{scope.row.published == '0' ? '私密' : '公开'}}</el-tag>
                    <!-- <el-tag style="margin-right: 20px;" v-if="scope.row.shareStatement" size="small" type="success">{{scope.row.typeId}}</el-tag> -->
                    <i style="margin-right: 20px;" class="el-icon-view"> {{scope.row.views}} </i>
                    <i style="margin-right: 20px;" class="el-icon-chat-square"> {{scope.row.commentCount}} </i>
                    <i style="margin-right: 20px;" class="el-icon-date"> {{scope.row.createTime}}</i>
                    
                    <el-button style="float: right;" type="danger" size="mini">删除</el-button>
                    <el-button style="float: right; margin-right: 10px;" type="primary" size="mini">编辑</el-button>
                
                </div>

                </el-card>
            </template>
                
            </el-table-column>
        </el-table>

       <!-- 分页 -->
       <div v-if="!hidden_page" style="margin-top: 20px;">
              <el-pagination
                background
                @size-change="handleSizeChange"
                @current-change="handleCurrentChange"
                :current-page="currentPage"
                :page-sizes="pagesizes"
                :page-size="pagesize"
                layout="total, sizes, prev, pager, next, jumper"
                :total="total">
              </el-pagination>
       </div>
 
  </div>
</template>

<script>
export default {
  name: 'BlogListCom',
  data () {
   return {
    blogsData: [], //文章数据
    currentPage: 1,  //当前页
    total:0, //总记录数
    pagesize:10, //页面大小
    pagesizes:[10,20,30], //页面数组
    t2index:0, //选项卡index
   }
  },
  props:["tindex"],
  mounted() {
    this.initIndex();
    this.initBlogs(); // 调用初始化博客数据
    
  },
  
  methods:{
    initIndex(){
        this.t2index = this.tindex  //保存父组件传过来的值
    },
    // 初始化【全部】博客的数据
    initBlogs(){
      const _this = this
      // 通用路由
      var baseurl = '/blog/getByPage?current=' + this.currentPage + '&size=' + this.pagesize
      //通过条件拼接路由
      if(this.t2index == "0"){ //全部
        baseurl +=' &is_delete=0'
      }
      if(this.t2index == "1"){ //原创
        baseurl +=' &flag=原创 &share_statement=1  &is_delete=0'
      }
      if(this.t2index == "2"){ //转载
        baseurl +=' &flag=转载 &share_statement=1  &is_delete=0'
      }
      if(this.t2index == "3"){  //草稿
        baseurl +=' &share_statement=0  &is_delete=0'
      }
      if(this.t2index == "4"){ //公开
        baseurl +=' &published=1 &share_statement=1  &is_delete=0'
      }
      if(this.t2index == "5"){ //私密
        baseurl +=' &published=0 &share_statement=1 &is_delete=0'
      }
      if(this.t2index == "6"){ //回收站
        baseurl +=' &is_delete=1 &share_statement=1  &is_delete=0'
      }
      // console.log(baseurl)
      this.getRequest(baseurl).then(resp=>{
        if(resp){
          console.log(resp)
          _this.blogsData = resp.obj.records  //将获取到的后端的值赋值给blogsData
          _this.total = resp.obj.total   // 保存一下总记录数,用于前端展示
        }
      })
    },
    // 分页的当前页
    handleCurrentChange(val) {
      console.log(`当前页: ${val}`);
      this.currentPage = val
      this.initBlogs()
    },
    //每页多少条
    handleSizeChange(val) {
        console.log(`每页 ${val} 条`);
        this.pagesize = val
        this.initBlogs()
    },
 
  }
}
</script>

<style scoped>

</style>

3、修改博客管理

AllBlogs.vue (后面给出完整代码)

导入刚才创建的两个子组件:
在这里插入图片描述
在这里插入图片描述
完整代码:

<template>
  <div>
    <el-tabs v-model="activeName" @tab-click="handleClick" style="margin-top: 10px;">
      <el-tab-pane label="全部(120)" name="first">
         <!-- 搜索 -->
        <el-input size="small" v-model="input_title" placeholder="请输入标题,可回车搜索..." prefix-icon="el-icon-search"
        style="width: 400px;margin-right: 10px;" @keydown.enter.native="search_title"></el-input>
        <el-button size="small" type="primary"  @click="search_title" icon="el-icon-search">搜索</el-button>
        <el-button size="small" type="primary">高级搜索</el-button>
        <!-- 通用博客列表组件 -->
        <BlogListCom :tindex="tabindex" v-if="tabindex == 0 && hidden_searchcom == false"></BlogListCom>
        <!-- 搜索专用组件 -->
        <SearchBlogsCom v-if="tabindex == 0 && hidden_searchcom == true" :blogsData="blogsData"></SearchBlogsCom>

      </el-tab-pane>

      <el-tab-pane label="原创(20)" name="second">
        <BlogListCom :tindex="tabindex" v-if="tabindex == 1"></BlogListCom>
      </el-tab-pane>
      <el-tab-pane label="转载(20)" name="third">
        <BlogListCom :tindex="tabindex" v-if="tabindex == 2"></BlogListCom>
      </el-tab-pane>
      <el-tab-pane label="草稿(20)" name="fourth">
        <BlogListCom :tindex="tabindex" v-if="tabindex == 3"></BlogListCom>
      </el-tab-pane>
      <el-tab-pane label="公开(50)" name="fifth">
        <BlogListCom :tindex="tabindex" v-if="tabindex == 4"></BlogListCom>
      </el-tab-pane>
      <el-tab-pane label="私密(10)" name="sixth">
        <BlogListCom :tindex="tabindex" v-if="tabindex == 5"></BlogListCom>
      </el-tab-pane>
      <el-tab-pane label="回收站(20)" name="serven">
        <BlogListCom :tindex="tabindex" v-if="tabindex == 6"></BlogListCom>
      </el-tab-pane>
    </el-tabs>

    
 
  </div>
</template>

<script>
  //导入子组件
  import BlogListCom from '@/components/blogs/BlogListCom'
  import SearchBlogsCom from '@/components/blogs/SearchBlogsCom'
export default {
  name: 'AllBlogs',
  components:{ BlogListCom,SearchBlogsCom }, //注册子组件
  data () {
   return {
    activeName: 'first',
    input_title: '', //输入框的值
    blogsData: [], //文章数据
   
    tabindex:0, //选项卡index
    
    hidden_searchcom: false , //是否隐藏搜索子组件

    }
  },
  mounted() {
    
  },
  methods:{
    // 获取标签栏的index
    handleClick(tab, event) {
        this.tabindex = tab.index
        console.log("tabindex = " + this.tabindex);
    },
    //根据标题搜索
    search_title(){
      //判断使用的是通用博客子组件还是搜索专用子组件
      if(this.input_title == ''){
        //如果搜索值为空,就隐藏搜索专用子组件,显示通用子组件
        this.hidden_searchcom = false
      }else{
        //如果搜索值不为空,就显示搜索专用子组件
        this.hidden_searchcom = true
      }
      const _this = this
      //发起根据标题搜索请求
      this.getRequest('/blog/getByTitle?title=' + this.input_title).then(resp=>{
        if(resp){
          _this.blogsData = resp.obj
        }
      
      })
    }

  }
}
</script>

<style scoped>

</style>

4、说明一下父组件如何传值给子组件

父组件
在这里插入图片描述
在这里插入图片描述
子组件:
在这里插入图片描述
在这里插入图片描述

5、效果展示

【全部】
在这里插入图片描述
【搜索】
在这里插入图片描述
在这里插入图片描述
【原创】
在这里插入图片描述
【转载】
在这里插入图片描述
【草稿】
在这里插入图片描述

【公开】
在这里插入图片描述

【私密】
在这里插入图片描述

【回收站】
在这里插入图片描述


关注【小L星光】回复 “博客” 即可获整个项目源码 ~
在这里插入图片描述

  • 6
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值