VueCli+Node+mongodb打造我的博客(含前臺展現及後臺管理系統)(中)

前言

前文:VueCli+Node+mongodb打造我的博客(含前臺展現及後臺管理系統)(上)
https://segmentfault.com/a/11...css

github地址:https://github.com/ssevenk/ss...前端

在上篇文章中
咱們完成了後端的配置,實現了對數據的增刪查改
如今只須要前端頁面發送對應的請求給後端便可vue

引入axios

在開始搭建組件前,咱們先要肯定前端異步請求的方式
這裏我用的是axios
先在main.js中將其引入ios

import axios from 'axios'
Vue.prototype.$axios = axios;

這樣咱們就能夠在自定義的組件中,直接用this.$axios來發起異步請求git

後臺管理系統

圖片描述

這裏我把它分紅了兩個組件
管理組件(Manage.vue)以及編輯組件(Edit.vue)github

管理組件(Manage.vue)

該組件的頁面顯示如圖vue-router

clipboard.png
核心部分就是那個表格了
用來展現已經存在的數據並對其進行操做mongodb

左側導航

分紅了三個類別,文章,雜談和收藏
當咱們點擊對應的類別時,並無在切換組件,而是在更新數據
Manage.vue
咱們定義一個名叫things的空數組,來保存當前須要顯示的數據
以及一個kind值,來保存當前須要顯示的數據種類
咱們先令kind值爲blog,默認顯示 「文章」 數據axios

data() {
return {
  kind: "blog",
  things: [],
  }

當組件初始化時,調用生命週期函數created()向後端發起對應種類的請求
後端返回對應的數據,存進things裏面segmentfault

created() {
        this.getData("blog"); //第一次默認先獲取文章的數據
      },
    methods: {
      getData(kind) {
          this.kind = kind;
          this.$axios.get(`/data/${kind}`)
            .then(res => {
              this.things = res.data;
            })
     }

每次點擊左側的導航欄上的按鈕,就調用一次getData(),並傳入對應的kind參數
由此來更新thingskind
更新要顯示的數據和種類
好比點擊雜談的話,就調用getData(essay)

數據表格

這裏我用了Element-ui的組件庫來製做表格
基本上就是官方案例

clipboard.png
能夠看到跟個人效果基本上同樣
因此這部分能夠直接參考官網教程https://element.eleme.cn/#/zh...
在數據綁定的時候,選擇咱們以前建好的things數組

:data='things'

搜索

右上角有一個搜索輸入框
輸入後能夠即時顯示搜索的結果在數據表格裏
一開始我想新定義一個show數組,來存放搜索後的結果
而後給輸入框綁定鍵盤事件來調用搜索函數
但後來發現Element官網的作法異常簡單
能夠直接在el-table表格綁定的數據上作文章

:data="((things.filter(data=>!search||data.title.toLowerCase().includes(search.toLowerCase())「

其中search是雙向綁定在輸入框上的數據

分頁

數據太多了確定須要分頁
仍是用到了咱們的Element-ui組件庫

<el-pagination
        @current-change="handleCurrentChange"
        :page-size="pageSize"
        :current-page="currentPage"
        :total=" things.length"
        layout="total, prev, pager, next"
      ></el-pagination>

PageSize設置爲5,當前默認頁爲1

data() {
return {
  kind: "blog",
  things: [],
  currentPage: 1,
  pageSize: 5,
  search: ""
};}

當點擊頁碼切換的時候,把頁碼更新

handleCurrentChange(currentPage) {
  this.currentPage = currentPage;
}

而後再一次對咱們以前的el-table標籤上的數據進行改進

:data="((things.filter(data=>!search||data.title.toLowerCase().includes(search.toLowerCase())).slice((currentPage-1)*pageSize,currentPage*pageSize)))"

這裏的邏輯前後要理清
是先對數據進行搜索的過濾再分頁

編輯組件(Edit.vue)

比起展現,更重要的仍是對數據的操做
這裏我把新建和編輯功能整合進了同一個組件裏
由於都是利用markdown編輯器來編寫
佈局如出一轍,只有初始化,按鈕以及請求的方式不同

clipboard.png
關於這個markdown編輯器,我是利用的simpleMDE
並添加了原本沒有的本地上傳圖片功能
能夠參見個人另外一篇文章https://segmentfault.com/a/11...
這裏再也不重複說明
其中在樣式上,爲了使編輯器高度控制在頁面內,使滾動條出如今編輯器內而不是頁面

.CodeMirror-scroll {
  min-height:350px;
  height: 350px;
}

添加這樣的css樣式(原本默認是800px)

新建仍是編輯?

Mangage組件中點擊了新建或者某篇文章的編輯按鈕
咱們就進入了這個Edit組件
由於整合在了同一個組件中
因此首先它得判斷如今是要新建仍是編輯
以及是要處理哪一種數據,文章仍是雜談仍是收藏?
創建一個boolisNew和一個stringkind
而後在生命週期函數created()中進行判斷

created() {
    this.kind = this.$route.params.kind;
    if (this.$route.params.id != "new") {
      this.isNew = false;
    }
  },

根據Manage組件路由跳轉時傳入的參數來判斷
關於vue-router路由跳轉,若是對queryparams的用法有所疑問,能夠參考個人這篇文章https://segmentfault.com/a/11...

按鈕

按鈕給一個函數讓其自行計算應該顯示什麼文字

computed: {
btn: function() {
  switch (this.kind) {
    case "blog":
      return (this.isNew ? "發表" : "更新") + "文章";
    case "essay":
      return (this.isNew ? "發表" : "更新") + "雜談";
    case "article":
      return (this.isNew ? "發表" : "更新") + "收藏";
    default:
      return "";
  }
}

若是是編輯

mounted()周期函數中,請求後端的數據,來填入markdown編輯器的輸入框

if (!this.isNew) {
      this.$axios
        .get(`/data/${this.$route.params.kind}/${this.$route.params.id}`)
        .then(req => {
          this.title = req.data.title;
          this.content = req.data.content;
          this.comments=req.data.comments;
          simplemde.value(this.content);
        });
    }

編輯完成後對後端的post請求

if (!this.isNew) {
        this.$axios
          .post(`/data/${this.$route.params.kind}/${this.$route.params.id}`, {
            id: this.$route.params.id,
            title: this.title,
            content: this.content
          })

若是是新建

須要給新文章一個創做日期

computed:{
    date: function() {
          var time = new Date(this.time);
          return `${(time.getMonth() + 1).toString().padStart(2, "0")}-${time
            .getDate()
            .toString()
            .padStart(2, "0")}`;
        }}

爲了美觀,用padStart來保證個位很多天期也能以兩位輸出
post的時候,把日期也加上

this.$axios
          .post(`/data/${this.$route.params.kind}/new`, {
            title: this.title,
            content: this.content,
            comments:this.comments,
            date: this.date
          })

刪除數據

點擊刪除按鈕的時候,獲取到對應數據的id值並向後端傳遞
不過在這以前要先找到這個數據在things中的位置並刪除
使用findIndexsplice

del(delid) {
  var delIndex = this.things.findIndex(item => {
    return item._id == delid;
  });
  this.things.splice(delIndex, 1);
  this.$axios.delete(`/data/${this.kind}/${delid}`);
}

PS.

其實後來我又寫了一個EditArticle組件出來
對應」收藏「,由於它只須要標題和跳轉的連接,不須要編輯器
因此就單獨爲它寫了一個,原理類同,這裏再也不贅述

接下來

完成了後臺管理系統
咱們就要開始作展現頁面了
敬請期待後續文章

已更新第三篇:https://segmentfault.com/a/11...

相關文章
相關標籤/搜索