用vue实现博客列表的级联效果

项目要放在最醒目的位置 my-blog(如果对你有帮助,那就来个star吧)

PS:可能录屏软件有点问题,在某些时候会出现泛白的一片区域,见谅

后续不断随着项目完善,对应更新博客

vue组件-分类列表-对应博客显示(一)

对应技术栈:Vue + axios

如果出现错误,请在评论中指出,我也好自己纠正自己的错误

author: thomaszhou

功能描述:

1、 左边是全部分类(ALL,Html,javascript,css,数据结构,其他)...后续可自行添加和更改分类)

2、 对应的右边是博客文章,点击左侧的分类,右侧的博客显示列表会相对应的进行显示

补充:博客的数据都是通过mock模拟数据来获取的

下图是我们的布局,目前没有实现逻辑,只是实现将左边的分类信息和右边的博客列表进行显示和布局

(1)我们先看json数据

JSON源文件目录:thomas-blog/tree/master/mock

json数据包含了右边博客列表的内容,链接,还有一些用来标记的变量

  • label:是每篇博客的分类标记
{
  "status":"0",
  "msg": "",
  "result":[
    {
      "href": "#1",
      "imgSrc": "../../static/img/note1.png",
      "title": "javascript原生封装一个淡入淡出效果的函数",
      "label": "javascript",
      "time": "2017-7-1",
      "author": "thomas",
      "content": "说到js的渐变显示与消失,多数朋友会想到JQuery里面的fadeIn()、fadeOut()或fadeToggle()。但如果仅仅是为了引入这样的一个效果,而去调用了庞大JQuery库?或者说我通过用原生js实现一些函数来提高自己~ 所以,我简单的研究了一下纯js代码写淡入淡出的效果。 淡入淡出"
    },
    ...
}
复制代码

(2)vue文件里面设置的类别的数组species

源文件目录:thomas-blog/blob/master/src/views/main.vue

我们在data中声明一个数组专门存放左边的列表信息

  • index: 就是我们给每个类别设置的标记index
  • name: 是显示到页面上的内容
  • blogNum:就是我们这个类别含有blog的数量(初始为0,后续通过js赋值)
species:[
	{
	  index: 'html',
	  name: 'Html(5)',
	  blogNum: 0
	},
        {
         index:'javascript',
	 name: 'Javascript',
         blogNum: 0
        },
        ...
]
复制代码

左边的种类列表是这样的,()里面都是0

(3)我们要获取每个类别含有的blog数量

  • 我们先将取出json文件的数据存入到数组BlogsList 和 selectList中(后续讲解selectList)
  • 然后遍历BlogsList的数据,将每个数据的label和数组species中每个元素的index进行比对,如果相同,那就将该元素的blogNum增加一,(因为我们是将blogNum动态显示到页面中)
  • 因为我们需要在页面加载的第一时间看到分类的数据,所以我们需要将操作挂载到mouted周期函数中。
mounted() {
  this.getBlogsList();
},
methods:{
  getBlogsList() {
    // axios获取json数据
    axios.get('/result').then(res => {
      let results = res.data;
      this.BlogsList = results.data;
      this.selectList = results.data;
      this.allNum = this.BlogsList.length;
      // 从json中获取每个数据的label,用来更新species数组的blogNum值
	  this.BlogsList.forEach((blog, i) => {
		this.species.forEach((item, j) => {
		  if (item.index === blog.label) {
			item.blogNum += 1;
		  }
		})
	  })
    })
},
复制代码

所以只要我们页面刷新就会自动加载数据,显示数据,可以看到下面每个类别后面的()都有对应的数字---就是该种类的文章数量

(4) 点击分类,右边仅显示该类别的blog(重点)

(4-1) 动态显示博客列表

右侧的博客列表的代码我就不详述,源文件目录在thomas-blog/blob/master/src/components/BlogList.vue

首先右边的blog列表,我们是通过一个子组件来实现,我们父页面main.vue利用axios获取json的数据,然后通过blogs参数传递到子组件

<div class="accessory-list-wrap">
	<!--将axios获取到的数组存进BlogsList,然后将此传递至子组件BlogList-->
	<blog-list :blogs = "selectList"></blog-list>
</div>
					
import BlogList from '../components/BlogList'
复制代码

问题1: 从代码中getBlogsList() 方法可以看到我们将从json获取的数据存入this.BlogsList和this.selectList两个数组中,这是为什么?(看下面思路)

问题2: 我们传递给子组件的数组是selectList,而不是BlogsList,为什么?(看下面)

思路:
  • 我们创建一个缓存数组selectList,和BlogsList存的数据一样,都是json里面的数据
  • 我们给左边的每个分类列表都绑定一个click事件locationBlog,然后通过点击分类列表来传递当前的列表的index到locationBlog方法里面
  • locationBlog实现功能:
    • 将selectList数组清空
    • 遍历BlogsList数组,将label与传递的参数index相等的数据push进selectList数组(这样每次点击不同的列表,都会进行一次selectList数组的清空,然后重新添加,然后通过动态绑定,重新传递给子组件,进行重新渲染显示)

解答: 我们设置左边的各个列表含有的blog数量,用的就是BlogsList,这个值是要一直稳定的(直到json数据发生改变)。

假设我们一直使用BlogsList,实现点击某个类别的选项,就清空数组,然后将对应的blog重新填充至BlogsList,功能也可以事件,但是会出现一个问题:点击某个类别选项的时候,其他选项的()里面的数字会出现短暂的变成0,然后又回复正常,会严重影响用户体验!!!

所以我们创建一个缓冲数组selectList,并将其作为参数传递给子组件(selectList是控制右边blog列表的显示)

(4-2)给左侧列表添加点击事件

给每个列表(除all)都添加点击事件locationBlog,但是我们给All这个列表元素添加另一个单独的事件showAllBlog()。

因为我们默认就是显示all列表,包括列表元素的高亮的css样式也是如此,所以我们需要将All默认高亮,所以我们设置初始值speciesChecked = -1

<div class="filter stopPop" id="filter" v-bind:class="{'filterby-show':filterBy}">
  <dl class="filter-price">
    <dt>全部分类:</dt>
    <dd><a href="javascript:void(0)" @click="showAllBlog()" v-bind:class="{'cur':speciesChecked === -1}">ALL ({{allNum}})</a></dd>
    <dd v-for="(item,index) in species">
	<a href="javascript:void(0)" @click="locationBlog(item.index)" v-bind:class="{'cur':speciesChecked===item.index}">{{item.name}}({{item.blogNum}})</a>
    </dd>
  </dl>
</div>
复制代码

每次我们点击All列表,右边的博客就要显示全部的文章,我们通过重新遍历一边selectList数组来实现

showAllBlog(){
    this.speciesChecked = -1; // 给ALL种类列表加cur样式
    this.selectList = [];
    this.BlogsList.forEach((blog, i) => {
        this.selectList.push(blog);
    });
},
复制代码

我们点击其他的列表,我们通过向点击事件locationBlog(index)传递列表的index值,然后与json数据中的label进行比对,如果相同,则将该数据添加进selectList,然后进行渲染显示

左边列表的index值是数组species中的每个列表的index值

species:[
	{
	  index: 'html',
	  name: 'Html(5)',
	  blogNum: 0
	},
        {
         index:'javascript',
	 name: 'Javascript',
         blogNum: 0
        },
        ...
]
复制代码
locationBlog(index) { // 定位到对应种类的博客index
    this.speciesChecked = index; // 给对应的种类列表加cur样式
    this.selectList = []; // 记得每次重新显示要清空缓存
    this.BlogsList.forEach((blog, i) => {
      if (blog.label === index) {
        this.selectList.push(blog);
	}
    });
},
复制代码
  • 后续第二篇博客补充功能:

      1. 添加博客列表的排序(根据事件排序)
      1. 实现博客懒加载功能
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值