用vue實現部落格列表的級聯效果

thomaszhou發表於2018-04-18

專案要放在最醒目的位置 my-blog(如果對你有幫助,那就來個star吧)

PS:可能錄屏軟體有點問題,在某些時候會出現泛白的一片區域,見諒

後續不斷隨著專案完善,對應更新部落格

vue元件-分類列表-對應部落格顯示(一)

對應技術棧:Vue + axios

用vue實現部落格列表的級聯效果

如果出現錯誤,請在評論中指出,我也好自己糾正自己的錯誤

author: thomaszhou

功能描述:

1、 左邊是全部分類(ALL,Html,javascript,css,資料結構,其他)...後續可自行新增和更改分類)

2、 對應的右邊是部落格文章,點選左側的分類,右側的部落格顯示列表會相對應的進行顯示

補充:部落格的資料都是通過mock模擬資料來獲取的

下圖是我們的佈局,目前沒有實現邏輯,只是實現將左邊的分類資訊和右邊的部落格列表進行顯示和佈局

用vue實現部落格列表的級聯效果

(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

image

(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;
		  }
		})
	  })
    })
},
複製程式碼

所以只要我們頁面重新整理就會自動載入資料,顯示資料,可以看到下面每個類別後面的()都有對應的數字---就是該種類的文章數量

用vue實現部落格列表的級聯效果

(4) 點選分類,右邊僅顯示該類別的blog(重點)

(4-1) 動態顯示部落格列表

用vue實現部落格列表的級聯效果

右側的部落格列表的程式碼我就不詳述,原始檔目錄在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. 實現部落格懶載入功能

相關文章