前端界面設(shè)計
用了Bootstrap之后開發(fā)效率果然非常高,在頁面美化這部分沒有耗費太多精力命满,而且就算像我這樣沒學過UI設(shè)計的人寫出來的界面也比較好看涝滴。看來Bootstrap能成為使用最廣的前端框架胶台,并不是沒有原因的歼疮。
直接上效果圖:
用這么多的英文、只用黑白兩種顏色诈唬、簡單與扁平化的風格是想做跟上一個項目完全不同的感覺韩脏,畢竟這個項目跟上一個PHP寫的是走了兩個極端——一個是多頁面前后端不分離,一個是單頁面前后端分離铸磅。
當然這個風格也是Bootstrap本身的特點赡矢,反正比我自己純手寫的頁面是好看多了杭朱。
組件
目前的組件列表如下:
每個組件的詳細說明:
- Add.vue:添加博文頁面
- Archive.vue:歸檔頁面
- ArchiveArticle.vue:歸檔頁面的文章列表
- Article.vue:主頁使用的文章列表,預計一頁顯示15篇文章
- ArticleDetail.vue:博文頁面(也就是文章的詳細內(nèi)容)
- Category.vue:主頁使用的目錄組件吹散,預計顯示10條最新的文章的鏈接
- Delete.vue:刪除文章的組件
- Header.vue:頁面頭部的灰色部分
- HelloWorld.vue:用vue-cli構(gòu)建項目時默認生成的組件痕檬,現(xiàn)在留作測試用途,完成之后會刪掉
- Login.vue:登錄頁面
- Logout.vue:銷毀Session或者Cookie實現(xiàn)登出的組件
- Main.vue:整個主頁
- Manage.vue:后臺管理頁面
- NavBar.vue:頁面頭部的導航欄
- PageNavgation.vue:首頁的翻頁條送浊,以后可能會加到別的頁面中
將整個網(wǎng)站拆解成這么多組件是為了解耦(降低耦合度)和提高每個組件的可重用性,也方便在開發(fā)的時候查錯改錯丘跌、為組件增加新功能袭景。當然這是第一次用vue-cli開發(fā),也有很多使用等方面的問題不大明白闭树,而且目前我也弄不大清楚是盡可能拆解出更多的組件好還是一個頁面一個組件更好耸棒,這個問題以后慢慢考慮吧。
配置需要引用的庫
目前有Bootstrap报辱、axios和VueAxios与殃。
main.js(整個應用的入口js文件)
// The Vue build version to load with the `import` command
// (runtime-only or standalone) has been set in webpack.base.conf with an alias.
import Vue from 'vue'
import App from './App'
import router from './router'
import axios from 'axios'
import VueAxios from 'vue-axios'
import 'bootstrap/dist/css/bootstrap.min.css'
Vue.use(axios, VueAxios)
Vue.config.productionTip = false
/* eslint-disable no-new */
new Vue({
el: '#app',
router,
components: { App },
template: '<App/>'
})
vue-router的配置
目前只想到文章和刪除需要動態(tài)id,以后如果有需要動態(tài)id的也會在里面改碍现。
這個只是目前的配置幅疼,隨著開發(fā)進程的推進,會繼續(xù)更改昼接。
index.js(vue-router的配置文件):
import Vue from 'vue'
import Router from 'vue-router'
import Manage from '@/components/Manage'
import Main from '@/components/Main'
import Login from '@/components/Login'
import Archive from '@/components/Archive'
import ArticleDetail from '@/components/ArticleDetail'
import Add from '@/components/Add'
import Delete from '@/components/Delete'
import Logout from '@/components/Logout'
Vue.use(Router)
export default new Router({
mode: 'history',
routes: [
{
path: '/',
name: 'Main',
component: Main
},
{
path: '/manage',
name: 'Manage',
component: Manage
},
{
path: '/login',
name: 'Login',
component: Login
},
{
path: '/archive',
name: 'Archive',
component: Archive
},
{
path: '/article/:id',
name: 'Article',
component: ArticleDetail
},
{
path: '/add',
name: 'Add',
component: Add
},
{
path: '/delete/:id',
name: 'Delete',
component: Delete
},
{
path: '/logout',
name: 'Logout',
component: Logout
}
]
})
頁面跳轉(zhuǎn)的實現(xiàn)
點擊鏈接實現(xiàn)頁面跳轉(zhuǎn)
因為是用vue-cli做的單頁面應用爽篷,所以所有的頁面跳轉(zhuǎn)都由vue-router完成,也就是完全放棄了<a></a>
標簽而用<router-link></router-link>
標簽來代替(其實<router-link>
渲染出來就是<a>
慢睡,所以可以用<a>
的樣式逐工,在CSS的部分如果要控制<router-link>
的樣式,選擇器也可以直接用元素選擇器a { }
)漂辐。以導航欄為例:
NavBar.vue(未完成)
<!--
導航欄組件泪喊,顯示前往首頁的按鈕、后臺管理按鈕髓涯、登出按鈕等
TODO: 開發(fā)根據(jù)登錄情況顯示不同按鈕的功能
-->
<template>
<nav class="navbar navbar-expand-sm bg-dark navbar-dark topnavbar">
<router-link to="/" class="navbar-brand">NullP0</router-link>
<ul class="navbar-nav ml-auto">
<li class="nav-item">
<router-link to="/archive" class="nav-link">Archive</router-link>
</li>
<li class="nav-item">
<router-link to="/add" class="nav-link">Add</router-link>
</li>
<li class="nav-item">
<router-link to="/manage" class="nav-link">Manage</router-link>
</li>
<li class="nav-item">
<router-link to="/logout" class="nav-link">Logout</router-link>
</li>
</ul>
</nav>
</template>
<script>
export default {
name: 'NavBar',
}
</script>
<style scoped>
.navbar {
position: fixed;
width: 100%;
z-index: 100;
}
</style>
在這里袒啼,導航欄上所有的鏈接的本質(zhì)都是路由跳轉(zhuǎn)。
至于頁面中獨立的按鈕(比如首頁中的閱讀全文按鈕)复凳,將<router-link>
加上按鈕的class就可以把鏈接渲染成按鈕瘤泪。
完成某操作后頁面強制跳轉(zhuǎn)
以登出組件為例,如果登出之后沒有任何操作育八,頁面將會停留在空白(因為預計登出組件不會顯示任何東西对途,僅僅是銷毀Cookie或者Session之后彈出一個框),所以需要一個強制跳轉(zhuǎn)髓棋∈堤矗可以使用this.$router.push()
函數(shù)完成:
Logout.vue(未完成)
<!--
登出組件
TODO: 開發(fā)登出功能
-->
<template>
</template>
<script>
export default {
name: 'Logout',
mounted () {
alert('登出成功惶洲!')
this.$router.push('/')
}
}
</script>
<style scoped>
</style>
獲取動態(tài)id并根據(jù)動態(tài)id返回不同內(nèi)容
如果要根據(jù)動態(tài)id顯示不同的內(nèi)容(比如根據(jù)文章編號的不同顯示相應內(nèi)容),除了要在vue-router的配置文件里配置上動態(tài)id膳犹,還需要在相應的組件里添加獲取動態(tài)id的方法恬吕。以文章頁面為例:
ArticleDetail.vue(未完成)
<!--
閱讀文章的頁面
TODO: 根據(jù)動態(tài)id顯示不同文章
-->
<template>
<div>
<v-header></v-header>
<div class="container">
<div class="col-12 border bg-light main-body">
<div class="article">
<h1 class="display-4">{{ detail.title }}</h1>
<small>yyyy.mm.dd - hh:mm:ss</small>
<hr class="my-3">
<pre>{{ detail.content }}</pre>
</div>
</div>
</div>
</div>
</template>
<script>
import Header from './Header'
export default {
name: 'ArticleDetail',
components: {
'v-header': Header,
},
data () {
return {
detail: {}
}
},
mounted () {
this.detail = this.getid(this.$route.params.id)
},
beforeRouteUpdate (to, from, next) {
this.detail = this.getid(to.params.id)
next()
},
methods: {
// TODO: 從后端接收數(shù)據(jù)并顯示
getid (id) {
switch (id) {
case '0' :
return {
id: 0,
title: 'This is a title.',
content: 'This is content.\n' + ' 中文測試。'
}
default :
return {
id: -1,
title: 'No data',
content: 'No data'
}
}
}
}
}
</script>
<style scoped>
.main-body {
padding: 40px;
margin: 30px;
}
pre {
font-family: 'DengXian', 'DengXian Light', sans-serif;
font-size: 1.1em;
}
h1 {
display: inline;
}
small {
margin-left: 20px;
}
</style>
實際效果:
當然须床,雖然現(xiàn)在文章內(nèi)容是寫死的铐料,但是后臺開發(fā)完成后文章內(nèi)容就可以動態(tài)地使用Ajax從服務器端獲取了。
將文章內(nèi)容放在<pre></pre>
而不是<p></p>
中是為了保留空格與換行豺旬,不讓文章本身的結(jié)構(gòu)混亂钠惩。
這部分代碼太多沒法全都放上來,開發(fā)完成之后我會把整個項目傳到GitHub族阅,詳細的代碼可以到時候在GitHub上查看篓跛。