vue項目-前端Vue 后臺express

項目地址?https://github.com/hongchh/timeline-x

一、成品展示

二、項目需求

添加每一天的時間記錄,修改某天的時間記錄(因為可能記錯或者忘了記某項活動)

每天的記錄可以有多項活動,每項活動有對應的時間

每項活動劃分到特定的類型

2016-01-20,星期五1. 學習Vue, 5h,[學習]2. 跑步,0.5h,[運動]3. 看霹靂布袋戲,2h,[休閑]

2、數據分析

按照月份統計每天的總時間,按照年份統計每月的總時間,按照分類統計各項內容的總時間

以圖表形式展示月份時間支出和年份時間支出的變化情況

以圖表形式展示各種類型的活動的時間支出情況

計算總時間和平均時間

3、時光展示

時光軸形式進行活動記錄展示,便于回顧總結

輪播圖形式進行活動記錄展示,便于回顧總結

4、數據模型

{? "items":[{? ? "content":"string",? ? "time":"number",? ? "type":"string"}],? "year":"number",? "month":"number",? "date":"number",? "day":"number"}

數據示例

{? "items":[{? ? "content":"學習Vue",? ? "time":"5",? ? "type":"學習"}, {? ? "content":"跑步",? ? "time":"0.5",? ? "type":"運動"}, {? ? "content":"看霹靂布袋戲",? ? "time":"2",? ? "type":"休閑"}],? "year":"2016",? "month":"01",? "date":"20",? "day":"5"}

三、開發思路

1、界面構成

整個應用分成2個主要界面:【主界面】,【權限界面】

【權限界面】用于用戶登錄,也是應用的啟動界面

【主界面】包含3個子界面:【管理】,【時光軸】,【時光展】

【時光軸】和【時光展】用于時光展示

【管理】用于展示數據分析結果以及編輯時光記錄(添加/修改)

2、跳轉關系

【權限界面】驗證成功之后跳轉到【主界面】

【主界面】默認展示【時光軸】界面

【主界面】頂欄可以選擇跳轉到【管理】、【時光軸】或【時光展】界面

【主界面】頂欄選擇“鎖屏”之后回到【權限界面】

3、組件劃分

└─App:掛載整個應用

? ├─Auth:【權限界面】

? │? └─StarFlow:【權限界面】底部的動畫

? └─Main:【主界面】的基本結構

? ? ? ├─Management:【管理】

? ? ? │? ? ├─TimeAnalysisPerMonth:月份時間分析組件

? ? ? │? ? ├─TimeAnalysisPerYear:年份時間分析組件

? ? ? │? ? ├─TimeAnalysisByType:分類時間分析組件

? ? ? │? ? └─EditTimeRecord:時間記錄編輯組件

? ? ? ├─Timeline:【時光軸】

? ? ? └─TimeSlide:【時光展】

4、文件結構

└─build:構建用到的相關文件├─config:構建的配置文件├─server:應用的服務器源碼│? ├─controller:服務端業務邏輯│? ├─model:數據存儲邏輯│? ├─static:靜態文件│? ├─views:應用的視圖文件│? ├─app.js:express服務器配置文件│? └─server.js:服務器啟動文件├─src:前端開發源碼│? ├─assets:圖片等靜態資源│? ├─components:前端組件│? ├─router:前端路由│? ├─store:vuex的store│? ├─App.vue:應用的外層結構│? └─entry.js:應用的入口文件└─static:前端開發過程中用到的靜態文件? ? └─data:存放偽數據以及偽數據生成器

四、開發歷程

1、基礎配置

使用vue-cli生成一個webpack項目模板

vue init webpack timeline-x

生成之后為了支持jade+sass開發,還需要安裝相關的依賴

npm install node-sass --save-dev

npm install sass-loader --save-dev

npm install jade --save-dev

配置完成之后我們就可以在項目中使用jade和sass來進行開發了,.vue文件的模板如下,注意在template標簽和style標簽里面使用lang屬性說明jade和sass。

div#auth? h1 Auth Pageexportdefault{? name:'auth'}#authborder: 1pxsolidred

2、準備組件

按照之前劃分好的組件,在src/components文件夾里面準備好相關文件。暫時不需要寫入各組件的內容,就按照上面的模板一樣寫個標題說明這是哪個組件即可。

3、配置路由

組件都準備好之后安裝路由

npm install vue-router --save

安裝完成之后需要在使用路由的時候將其導入,我這里選擇在router/index.js文件里面導入。

import Vue from'vue'import Router from'vue-router'Vue.use(Router)

按照前面確定好的頁面跳轉關系配置路由信息,然后測試界面跳轉是否正常。

constrouter =newRouter({? mode:'history',? routes: [? ? { path:'/auth', component: Auth },? ? {? ? ? path:'/main',? ? ? component: Main,? ? ? children: [? ? ? ? { path:'management', component: Management },? ? ? ? { path:'timeline', component: Timeline },? ? ? ? { path:'time-slide', component: TimeSlide },? ? ? ? { path:'', redirect:'timeline'}? ? ? ]? ? },? ? { path:'/', redirect:'/auth'}? ]})

4、組件設計

UI方面使用了一些element-ui的組件,因此還需要先安裝element-ui。同樣地安裝之后需要導入,導入方法類似之前的vue-router。注意這里還需要導入element-ui的樣式文件index.css。

npm install element-ui --save

import Vue from'vue'import ElementUI from'element-ui'import'element-ui/lib/theme-default/index.css'Vue.use(ElementUI)

3個時間分析圖表使用的是echarts,需要先安裝echarts。安裝之后import需要用到的圖表就行了,這樣經過webpack構建之后的產品代碼就只有用到的圖表的那部分代碼了,可以較少產品代碼體積。

npm install echarts --save

由于我只用到了柱狀圖和圓餅圖,然后圖表上面還使用了標題和提示等組件,所以只需要在entry.js里面導入這些組件即可。

import'echarts/lib/chart/pie'import'echarts/lib/chart/bar'import'echarts/lib/component/tooltip'import'echarts/lib/component/title'import'echarts/lib/component/legend'

到步驟【2】準備好的文件里面開始編寫組件。在template標簽中編寫組件的HTML結構,然后在style標簽中調節樣式,業務邏輯則是放在script標簽中。下面我用Auth.vue來作為例子,其他組件請參考github倉庫里面的代碼。

權限界面比較簡單(參考上面的成品展示圖),HTML結構如下,使用element-ui的柵格布局,同時用了另外一個動態背景組件star-flow。

div#authstar-flowdiv#auth-inputel-row(:gutter="20")? ? ? el-col(:span="8", :offset="8")? ? ? ? el-tooltip(:disabled="disabled", :content="errorTip", placement="bottom-start", effect="light")? ? ? ? ? el-input(placeholder="請輸入密碼", v-model="password",type="password")? ? ? ? ? ? template(slot="append")? ? ? ? ? ? ? el-button(@click="signin") Go

樣式如下,設置一下背景圖、寬高度之類的。

#authwidth:100%height:100%background: url(../../assets/auth-bg.jpg) no-repeatbackground-size:100%100%background-attachment: fixed#auth-inputposition: absolute? ? width:100%height:10%top:45%

下面是js部分了,使用es6的寫法,為了使用另一個組件,需要先將其import進來然后添加到components里面。export是將當前的組件導出,其他模塊才能使用到。data里面寫該組件用到的數據項,methods則是這個組件里面需要的方法函數了。(有點類似angular的controller)

import StarFlow from'./StarFlow'exportdefault{? name:'auth',? components: { StarFlow },? data () {return{? ? ? password:'',? ? ? disabled:true,? ? ? errorTip:''}? },? methods: {? ? setTip (tip) {// 消息提示,1.5秒后自動關閉this.errorTip = tipthis.disabled =falsesetTimeout(() => {this.disabled =truethis.errorTip =''},1500)? ? },? ? signin () {// 驗證密碼解除鎖屏if(!this.password) {this.setTip('密碼不能為空')? ? ? }else{this.$store.dispatch('unlockScreen',this.password)? ? ? ? .then((err) => {if(err)this.setTip('密碼錯誤')elsethis.$router.replace('/main')? ? ? ? })? ? ? }? ? }? }}

5、改善UI

調整組件的樣式,并且改進應用的樣式,添加過渡動畫。過渡動畫直接在router-view外面套一個transition,然后編寫相應的過渡樣式即可,很簡便。

6、數據狀態管理

該項目由6個組件需要用到同一份數據,1個記錄編輯組件、2個時光展示組件和3個數據分析組件。為了方便數據管理,同時也好制造機會學習Vuex,因此我這里引入vuex來進行應用的狀態管理。安裝vuex,然后在store/index.js里面導入vuex。

npm install vuex --save

import Vue from'vue'import Vuex from'vuex'Vue.use(Vuex)

定義1個store存放應用的全局狀態:鎖屏變量和時間記錄。默認開啟鎖屏,所以lockScreen設置為true,而timeRecords則是一個時間記錄數據,里面包含多條記錄。這些數據在應用啟動接觸鎖屏之后向服務器獲取,在還沒有開發服務器的時候,為了完成前端開發可以先在這里寫一些偽數據進去。

conststore =newVuex.Store({? state: {? ? lockScreen:true,? ? timeRecords: []? },? mutations,? actions})

在store/actions.js和store/mutations.js里面定義這些全級狀態可能發生的變化。如果涉及到異步操作,則將這些涉及異步的變化放到actions.js里面,例如向服務器獲取數據這個操作就是一個異步的,應該將其代碼放在action里面。根據Vuex文檔的介紹,mutation的代碼必須要是同步的。

由于涉及跟服務器的交互,所以我們還需要一個提供http服務模塊。上網查了查,有vue-resource這個東西可以用,不過好像更推薦使用axios,因此我這里也選擇使用axios。下面進行安裝和導入。

npm install axios --save

import axios from'axios'

準備好了之后可以開始編寫了,下面是actions.js的代碼,其他代碼請參考github倉庫。實現了后臺交互功能,然后通過commit相應的mutation來更新store里面的狀態。注釋部分的代碼是在前端開發還沒有服務器的時候使用的開發代碼。

exportdefault{? unlockScreen ({commit}, password) {// 驗證密碼,接觸鎖屏// 使用"npm run dev"啟動時候請解除下面代碼的注釋,注釋后面的POST代碼// return new Promise((resolve, reject) => {//? commit('UNLOCK')//? resolve(false)// })returnaxios.post('/api/check', {? ? ? password: password? ? }).then((res) => {if(!res || res.status !==200|| res.data.err) {returntrue}else{? ? ? ? commit('UNLOCK')returnfalse}? ? })? },? addRecord ({commit}, record) {// 添加記錄// 使用"npm run dev"啟動時候請解除下面代碼的注釋,注釋后面的POST代碼// return new Promise((resolve, reject) => {//? commit('UPDATE_RECORD', record)//? resolve(false)// })returnaxios.post('/api/add', record).then((res) => {if(!res || res.status !==200|| res.data.err) {returntrue}else{? ? ? ? commit('UPDATE_RECORD', record)returnfalse}? ? })? },? fatchData ({commit}) {// 獲取數據axios.get('/static/data/data.json').then((res) => {if(res.status ===200) {? ? ? ? commit('FATCH_DATA', res.data)? ? ? }? ? })? }}

7、準備偽數據

為了讓應用有更多數據可以呈現,需要自行編造一些偽數據,我寫了一個偽數據生成器,即static/data/data-generator.js。運行之后產生100多條時間記錄并存放到json文件里面。具體請參考github倉庫

8、完善鎖屏

實現鎖屏功能其實不難,只要在權限界面檢驗之后更新store里面的鎖屏狀態為false,在主界面點擊頂欄的鎖屏之后更新store里面的鎖屏狀態為true即可。但為了更完善,還需要在路由里面設置一個全局鉤子,在進入相應界面之前檢查一下store的鎖屏狀態,例如,在訪問主界面的時候需要檢查store里面的鎖屏狀態是否為true,如果是的話強行給它重定向到權限界面,因為這可能是用戶通過手動修改URL來訪問的。

這里有一個坑,在router的全局鉤子里面訪問不到store里面的狀態。在stack-overflow里面找到了這個解決方案,把store也給import到router里面去,這樣就可以訪問到了。不知道有沒有其他更優秀的方案,歡迎交流。

import store from'../store'router.beforeEach((to, from, next) => {// 對特定路徑進行驗證,增強鎖屏功能if(to.path ==='/') {? ? next('/auth')? }elseif(to.path ==='/auth'&& !store.state.lockScreen) {? ? next('/main')? }elseif(to.path !=='/auth'&& store.state.lockScreen) {? ? next('/auth')? }else{? ? next()? }})

9、后臺開發

前端開發基本完成之后就可以開始后臺開發了,我后端使用的是express框架,按照MVC模式進行開發。由于本項目關注的是前端開發,所以后端就寫得比較簡單,也沒有用上數據庫,沒有什么好講的。主要有一點需要注意,為了方便,我更改了build的目標路徑。用vue-cli生成的webpack項目build之后是在主目錄下面生成一個dist文件夾來存放產品文件,我將其改成build之后靜態文件放到server里面的static文件夾,而index.html則放到server里面的views文件夾,這樣就不用手動去搬dist里面的文件給服務器用了。改動很簡單,只需要該config/index.js里面的7-8行即可。

index: path.resolve(__dirname,'../server/views/index.html'),assetsRoot: path.resolve(__dirname,'../server'),

10、前后對接

對接前端和后臺的接口,調整代碼,修正bug。如果一開始將接口想清楚、設計好的話這里基本沒有什么難。本項目只有2個post數據和1個get數據的接口,沒有難度。

11、改進,修正小問題

五、結束

大概用了5天寫這個項目,基本入門了Vue,還是一次蠻不錯的體驗。為了多點練習強行加入了vuex,雖然官方推薦不要在小項目里面使用vuex,但我覺得引入vuex之后還是可以解決很多問題,思路也清晰了很多。在用vuex之前的想法是在一個外層的組件里面獲取數據然后傳遞給子組件。后來發現如果我在編輯記錄組件里面更新或者添加了一條記錄,父組件和其他兄弟組件的數據不會收到更新。如果通過$emit來讓父親組件更新數據然后再使得兄弟組件更新,整個過程又太過繁瑣。而Vuex的思路是弄一個全局狀態來對數據進行管理,組件樹上的組件都可以更新狀態,狀態變化之后會反饋到相應的其他組件上。這個思路很清晰,代碼寫起來也很順利,也體驗了vuex的強大,確實可以省事很多。

部分內容可能無法講得很清楚,有興趣了解的話請參考github倉庫的代碼。下面說說幾點收獲:

es6寫起來感覺超棒

webpack比gulp優雅

vue值得嘗試

?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,119評論 6 531
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,382評論 3 415
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,038評論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,853評論 1 309
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,616評論 6 408
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,112評論 1 323
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,192評論 3 441
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,355評論 0 288
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,869評論 1 334
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,727評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,928評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,467評論 5 358
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,165評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,570評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,813評論 1 282
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,585評論 3 390
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,892評論 2 372

推薦閱讀更多精彩內容