项目要放在最醒目的位置
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参数传递到子组件
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
复制代码
每次我们点击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); } });},复制代码
-
后续第二篇博客补充功能:
-
- 添加博客列表的排序(根据事件排序)
-
- 实现博客懒加载功能
-