採用 vue+webpack 構建的單頁應用——私人部落格 MintloG 誕生記

Jrain發表於2018-12-06

寫於 2016.03.18

介紹

專案地址:github.com/jrainlau/Mi… (特別亂,參考就好-_-|||)

採用 vue+webpack 構建的單頁應用——私人部落格 MintloG 誕生記
MintloG是我在五天之內完全由自己開發的私人部落格,前端技術方案採用了vue+vue-router+vue-resource+webpack的構建方案,後端技術採用了原生PHP+MySQL。部落格完全由ajax實現和後臺的通訊,後臺只提供了一個介面,通過傳入不同的引數實現不同的增刪改查功能。同時部落格通過vue-router實現路由管理,通過路由的切換來切換功能,完全沒有頁面的重新整理和跳轉,是百分百的單頁應用。

設計的靈感來自清新的薄荷綠,因為最近南方的回南天是在噁心,“清新”是最迫切的需求,所以採用了比較明亮的薄荷綠作為主色調。但是因為我的筆記本是12年買的老機器,螢幕比較差,不同的角度看到的顏色也會不一樣,所以這裡的薄荷綠具體綠成什麼樣我並不知道……

下面來看看MintloG到底長什麼樣——

首頁

採用 vue+webpack 構建的單頁應用——私人部落格 MintloG 誕生記
首頁主要有三個部分,分別是導航欄、文章列表、分類皮膚。

  • 導航欄:左側為“主頁”按鈕,可以快速回到首頁;中間為MintloG的logo;右側為編寫按鈕,點選以後可以切換到編寫功能。
  • 文章列表:點選文章標題可以進入檢視文章詳情,點選時間或標籤可以快速篩選;刪除按鈕可以直接刪除該篇文章。
  • 分類皮膚:可以通過輸入標題關鍵字,點選標籤或者時間對文章列表進行分類。

文章詳情

採用 vue+webpack 構建的單頁應用——私人部落格 MintloG 誕生記
點選“編輯”以後會進入編輯頁面

採用 vue+webpack 構建的單頁應用——私人部落格 MintloG 誕生記
可以對文章進行修改。


撰寫文章

點選右上角的編寫按鈕,進入編寫頁面,左邊的輸入視窗支援markdown語法,會在右邊的視窗實時輸出編譯後的文字。

採用 vue+webpack 構建的單頁應用——私人部落格 MintloG 誕生記
提交併提示成功

採用 vue+webpack 構建的單頁應用——私人部落格 MintloG 誕生記
點選OK以後會跳回首頁,看到新寫的文章

採用 vue+webpack 構建的單頁應用——私人部落格 MintloG 誕生記


查詢功能

可以通過文章的標題、標籤、修改時間進行查詢

採用 vue+webpack 構建的單頁應用——私人部落格 MintloG 誕生記

採用 vue+webpack 構建的單頁應用——私人部落格 MintloG 誕生記

採用 vue+webpack 構建的單頁應用——私人部落格 MintloG 誕生記
具體可以看位址列上面的路由有啥不同~


刪除功能

點選刪除按鈕並確認以後會刪除對應文章,重新渲染列表。(此處懶得放圖)


後臺搭建

介紹完了MintloG的增刪改查功能,我們來看一下後臺是如何搭建的。 我採用原生PHP編寫後臺,因為感覺增刪改查的功能很簡單,就懶得用框架了(其實是不會)。

我在conn_sql.php裡面新建了一個類,專門用來連結資料庫以及提供運算元據庫的功能:

<?php
// 連線資料庫(單例模式)
class ConnMySQL {
    protected static $_connect = null;
    protected $dbName;
    protected $dsn;
    protected $pdoObj;

    // 初始化
    private function __construct($host, $user, $pwd, $dbName) {
        try {
            $this->dsn = 'mysql:host='.$host.';dbname='.$dbName;
            $this->pdoObj = new PDO($this->dsn, $user, $pwd);
            $this->pdoObj->query("set names utf8");
        } catch (PDOException $e) {
            echo $e->getMessage();
        }
    }

    // 防止克隆
    private function __clone(){}

    // 返回一個例項化的PDO物件
    public static function makeConnect($host, $user, $pwd, $dbName) {
        if (self::$_connect === null) {
            self::$_connect = new self($host, $user, $pwd, $dbName);
        }
        return self::$_connect;
    }

    // 定義查詢方法
    public function query($db, $sqlState = null, $sqlVal=null) {
        if(!$sqlState) {
            $_result = $this->pdoObj->query("select * from $db");
        } else {
            $_result = $this->pdoObj->query("select * from $db where $sqlState like '%".trim($sqlVal)."%'");
        }
        return $_result;
    }

    // 定義新增方法
    public function insert($db, $where, $what) {
        $_result = $this->pdoObj->exec("insert into $db ($where) values ($what)");
        return $_result;
    }

    // 定義刪除方法
    public function delete($db, $where) {
        $_result = $this->pdoObj->exec("delete from $db where $where");
        return $_result;
    }

    // 定義更新方法
    public function updata($db, $what, $where) {
        $_result = $this->pdoObj->exec("update $db set $what where $where");
        return $_result;
    }

    // 斷開和資料庫連結
    public function destruct()
    {
        $this->pdoObj = null;
    }
}
?>
複製程式碼

難點其實在於“單例模式”應該如何例項化一個PDO吧我猜……然後在option.php檔案裡面引入上面這個類,並通過獲取$_POST[]獲取引數並echo相應的返回資訊。因為是ajax應用,涉及到跨域的問題,所以我在檔案的開頭加了這麼一句話header("Access-Control-Allow-Origin:*");跨域問題妥妥的解決了。

後臺那邊搞定了,就通過phpMyAdmin建了一個MySQL資料庫,建立了一張表,存放文章的各種資訊,部落格的基本功能其實就是在這張表上面折騰。

採用 vue+webpack 構建的單頁應用——私人部落格 MintloG 誕生記
嗯,就是這麼隨性。


UI設計

“不懂設計的前端不是好老闆”。 不懂可以學嘛~ 所以在邊學邊做的情況下進行了我的第一次UI設計……所以如果看官覺得MintloG長得醜請直接把磚頭砸向我!我會把你們的磚頭都撿起來然後拿去賣錢…… 其實剛設計出來的時候更醜……

採用 vue+webpack 構建的單頁應用——私人部落格 MintloG 誕生記
一定的UI規範還是有的:統一以15px作為同類元素的間距,30px作為非同類元素的間距。頁面的顏色不超過5個,元素通過陰影作為區分。 實在是很鍾情google的MD風格,所以模仿的痕跡還是相當重哈!雖然不怎麼像。 因為懶所以沒有用css框架也沒有做成響應式。


前端構建

因為打算採用vuejs,所以採用了官方的vue-cli來生成專案,並安裝了vue-router,vue-resource作為路由管理和資源請求工具。 檔案目錄如下:

--- /MintloG  專案主目錄
    |
    --- /bower_component  第三方庫
    |
    --- /src
        |
        --- /components  元件*.vue資料夾
        |       |
                --- blog-article.vue  文章詳情
                |
                --- blog-head.vue  導航欄
                |
                --- blog-list.vue  文章列表
                |
                --- blog-search.vue  搜尋框
                |
                --- blog-tags.vue  標籤欄
                |
                --- blog-timeline.vue  時間線
                |
                --- browse-mode.vue  瀏覽模式父元件
                |
                --- toolbox.vue  編輯頁工具欄
                |
                --- write-panel.vue  編輯頁
        |
        --- main.js  入口js檔案(路由控制)
        |
        --- App.vue  主程式檔案
    |
    --- /lib  第三方檔案
    |
    --- /image  圖片資源

複製程式碼

可以看到,MintloG是通過不同的元件組合而成,這樣符合元件化的思想,以後的維護和修改也會更方便。由於專案比較簡單,所以沒有使用vuex作為狀態管理,而是採用了“子元件——父元件——子元件”的方式實現狀態共享,具體實現方式可以參考我的一個demogithub.com/jrainlau/vu…

重點部分是main.js檔案,它作為入口檔案,規定了不同路由的含義:

router.map({
    '/': {
      component: browseMode,
      subRoutes: {
        '/': {
          component: blogList
        },
        '/details/:artId': {
          component: blogArticle
        }
      }
    },
    '/edit/:mode': {
      component: writePanel
    },
    '/search/tag/:tag': {
      component: browseMode,
      subRoutes: {
        '/': {
          component: blogList
        }
      }
    },
    '/search/time/:time': {
      component: browseMode,
      subRoutes: {
        '/': {
          component: blogList
        }
      }
    },
    '/search/title/:title': {
      component: browseMode,
      subRoutes: {
        '/': {
          component: blogList
        }
      }
    },
})
複製程式碼

App.vue則作為父元件:

採用 vue+webpack 構建的單頁應用——私人部落格 MintloG 誕生記
它載入了blog-head.vue作為導航欄,通過<router-view>切換“瀏覽模式”和“編輯模式”。

  • 瀏覽模式browseMode.vue
    採用 vue+webpack 構建的單頁應用——私人部落格 MintloG 誕生記
    它也有一個<router-view>,用來切換“文章列表”和“文章詳情”,也就是blog-list.vueblog-article.vue
  • 編輯模式
    採用 vue+webpack 構建的單頁應用——私人部落格 MintloG 誕生記
    它載入了toolbox.vue作為工具欄,然後可以進行文章的撰寫與修改。這個編輯頁面複用了我以前的一個專案Markcook,具體可以到這兒去看~ github.com/jrainlau/ma…

比較需要動腦的地方在於路由的巢狀對應元件的切換,以及每一次切換路由所需要進行的狀態更新。不過vue-router把這些問題都考慮得很周到,仔細研究官方文件能解決大部分的問題。具體的元件巢狀及組合形式如圖:

採用 vue+webpack 構建的單頁應用——私人部落格 MintloG 誕生記

在ajax通訊方面,第一次使用vue-resource,感覺比使用jquery相對複雜一點,尤其是配置項,需要全域性配置請求體的json格式才能正常傳送請求的引數:

import VueRouter from 'vue-router'
Vue.use(VueRouter)
Vue.http.options.emulateJSON = true;
複製程式碼

當然付出得多,得到的也多。vue-resource返回的response物件還會帶有狀態碼、狀態描述,請求頭等等,方便更復雜的使用

採用 vue+webpack 構建的單頁應用——私人部落格 MintloG 誕生記

在內容更新方面,由於是單頁應用,不提倡重新整理的操作,因為會產生不必要的資源請求而浪費資源,所以通過“重新渲染”的方式實現內容更新。舉個例子,在browseMode.vue裡我定義了一個getList()方法,用於獲取資料:

採用 vue+webpack 構建的單頁應用——私人部落格 MintloG 誕生記
任何需要“重新整理”的時候,我都可以通過this.$emit('getList')來觸發這個方法,把內容重新渲染到頁面上,實現內容更新的功能。


後記

寫了那麼多,總算是把MintloG的誕生給介紹完了,其實主要目的還是作為自己成長的一個記錄吧。在一週之內,從完全不懂後臺開發到掌握PHP和MySQL的使用,在5天之內完成後臺的搭建,UI設計,前端構建,一個MintloG給我的收穫遠遠大於知識的本身,我的畢業設計也終於完成啦!學以致用才是學習最好的方法,繼續加油~

相關文章