Vue全家桶開發(fā)的CNode社區(qū)單頁web應(yīng)用

為什么要寫這篇文章呢墓怀?其目的標(biāo)題寫的也很明了,就是為了記錄一下我的學(xué)習(xí)過程抬驴。在以后回顧此項目時炼七,也可以更方便地發(fā)現(xiàn)此項目中的不足和精華。在此布持,感謝VNode社區(qū)提供的API豌拙。

源碼在此Vue-CNode
預(yù)覽地址使勁點我
你也可以掃描下面的二維碼預(yù)覽線上項目:

一、需求分析

要做一個項目之前题暖,我覺得首先要把功能做一個總結(jié)按傅,根據(jù)需求來寫項目,從而做到有的放矢胧卤。

所以我根據(jù)API寫了項目的需求唯绍,可見下圖:

CNode功能需求分析
CNode功能需求分析

二、技術(shù)棧

本項目使用的技術(shù)棧就是標(biāo)準(zhǔn)的Vue全家桶枝誊,即:

Vue2.0: 構(gòu)建項目况芒,屬于底層框架。
Vue-Router: 通過hash值的變化侧啼,從而改變頁面結(jié)構(gòu)的路由牛柒。
Vuex: Vue官方提供的狀態(tài)管理模式堪簿。
Axios, Vue-Axios: http請求模塊。
ES6: 應(yīng)用于生產(chǎn)環(huán)境皮壁,普及度較高的新Javascript語法椭更。
Sass: CSS預(yù)編譯器。
Webpack: 用于打包項目蛾魄。

三虑瀑、項目初始化

利用Vue-cli提供的初始化工具,運行以下代碼:

# install vue-cli
$ npm install --global vue-cli
# create a new project using the "webpack" template
$ vue init webpack my-project
# install dependencies and go!
$ cd my-project
$ npm install
$ npm run dev

此時打開http://localhost:8080/就可以訪問初始化后的頁面了滴须。

四舌狗、項目編寫

注意:詳細(xì)內(nèi)容可以去源碼自行查看。

完成初始化之后呢扔水,我們就可以開始編寫項目了痛侍。
代碼分為四塊,分別是:components(組件)魔市、vue-router(路由)主届、vuex(狀態(tài)管理模式)common(放置公共樣式,字體和通用的功能代碼)待德。
在項目編寫之前君丁,受限于要安裝依賴,代碼如下:

# 安裝vuex将宪,vue-router绘闷,axios,vue-axios
$ npm install vuex vue-router axios vue-axios --save
// 安裝sass依賴
# npm install node-sass sass-loader --save-dev

1.common公用文件

包括樣式(style)较坛,字體(fonts)還有工具函數(shù)(utils, 包括時間格式化還有cookie存取功能)印蔗。

2.Components組件

現(xiàn)在暫時一共有14個組件,包括:

AboutMe
Article
ArticleCard
BackBar
BottomBar
Content
Loading
Login
MessageCard
MyCollect
navBar
Notification
Publish
UserDetail

具體內(nèi)容可以參見后面的項目目錄燎潮。

3. Vue-Router 路由配置

通過路由喻鳄,分為一下七個頁面:
① 主頁
② 文章詳情頁
③ 用戶詳情頁
④ 用戶登錄頁
⑤ 發(fā)布文章頁
⑥ 用戶收藏頁
⑦ 我的通知頁

5. Vuex:狀態(tài)管理模式

狀態(tài)管理分為六個模塊:content(主頁)扼倘、article(文章頁)确封、navbar(導(dǎo)航欄)、user(用戶詳情狀態(tài))再菊、login(用戶登錄狀態(tài))和notification(通知)爪喘。

五、項目目錄

.
├── build                               // webpack設(shè)置
│   ├── build.js
│   ├── check-versions.js
│   ├── dev-client.js
│   ├── dev-server.js
│   ├── utils.js
│   ├── vue-loader.conf.js
│   ├── webpack.base.conf.js
│   ├── webpack.dev.conf.js
│   └── webpack.prod.conf.js
├── config                              // 項目開發(fā)和打包設(shè)置
│   ├── dev.env.js
│   ├── index.js
│   └── prod.env.js
├── docs                                // 靜態(tài)資源地址
│   ├── index.html
│   └── static
│       ├── css
│       │   └── app.d99bca81a0eef77c7e0d8c70f520707c.css
│       ├── fonts
│       │   ├── iconfont.8553d3c.ttf
│       │   └── iconfont.b29ac85.eot
│       ├── img
│       │   └── iconfont.d4553f2.svg
│       └── js
│           ├── app.cb09e437ae0bec6205b9.js
│           ├── manifest.aa9548ef140031379c30.js
│           └── vendor.f3d0844a66c0c2cabe0b.js
├── src                                 // 項目文件位置
│   ├── App.vue                         // 組件總?cè)肟?│   ├── common                          // 通用文件
│   │   ├── fonts                       // 字體
│   │   │   ├── iconfont.eot
│   │   │   ├── iconfont.svg
│   │   │   ├── iconfont.ttf
│   │   │   └── iconfont.woff
│   │   ├── style                       // 樣式
│   │   │   ├── animation.scss          // 動畫
│   │   │   ├── base.scss               // 基本樣式
│   │   │   └── icon.scss               // iconfont的字體圖標(biāo)樣式
│   │   └── utils                       // 工具函數(shù)
│   │       ├── cookie.js               // cookie存取和刪除
│   │       └── timeFormat.js           // 格式化時間函數(shù)
│   ├── components                      // 所有組件
│   │   ├── AboutMe                     // 關(guān)于
│   │   │   └── AboutMe.vue
│   │   ├── Article                     // 文章詳情頁
│   │   │   └── Article.vue
│   │   ├── ArticleCard                 // 文章列表的單個文章卡片
│   │   │   └── ArticleCard.vue
│   │   ├── BackBar                     // 頂部的返回欄(返回主頁和后退)
│   │   │   └── BackBar.vue
│   │   ├── BottomBar                   // 底部的回復(fù)欄(還包含收藏和編輯文件)
│   │   │   └── BottomBar.vue
│   │   ├── Content                     // 主頁
│   │   │   └── Content.vue
│   │   ├── Loading                     // 正在加載組件
│   │   │   ├── Loading.vue
│   │   │   └── loading.svg
│   │   ├── Login                       // 登錄
│   │   │   └── Login.vue
│   │   ├── MessageCard                 // 單個通知的詳情卡片
│   │   │   └── MessageCard.vue
│   │   ├── MyCollect                   // 我的收藏頁
│   │   │   └── MyCollect.vue
│   │   ├── Notification                // 通知頁
│   │   │   └── Notification.vue
│   │   ├── Publish                     // 發(fā)布文章和發(fā)布更新頁
│   │   │   └── Publish.vue
│   │   ├── UserDetail                  // 用戶詳情頁
│   │   │   └── UserDetail.vue
│   │   └── navBar                      // 主頁的頂部導(dǎo)航欄
│   │       ├── cnodejs_light.svg
│   │       └── navBar.vue
│   ├── main.js                         // 項目的總?cè)肟?│   ├── pic                             // 和代碼無關(guān)纠拔,README.md中的圖片
│   │   ├── CNode?\212\237?\203??\234\200?\202?\210\206?\236\220.png
│   │   └── QR-Code.png
│   ├── router                          // 路由設(shè)置
│   │   └── index.js
│   └── store                           // 狀態(tài)管理
│       ├── modules
│       │   ├── article                 // 文章詳情頁
│       │   │   ├── article-mutation-types.js
│       │   │   └── article.js
│       │   ├── content                 // 主頁
│       │   │   ├── content-mutation-types.js
│       │   │   └── content.js
│       │   ├── login                   // 登錄頁
│       │   │   ├── login-mutation-types.js
│       │   │   └── login.js
│       │   ├── navbar                  // 主頁導(dǎo)航欄
│       │   │   ├── navbar-mutation-types.js
│       │   │   └── navbar.js
│       │   ├── notification            // 通知頁
│       │   │   ├── notification-mutation-types.js
│       │   │   └── notification.js
│       │   └── user                    // 用戶詳情頁
│       │       ├── user-mutation-types.js
│       │       └── user.js
│       └── store.js                    // 狀態(tài)管理總?cè)肟?├── README.md
├── index.html
└── package.json

六秉剑、過程中遇到的問題

本項目算是本人第一個完整的手機和pc都兼容,有關(guān)于文章展示的項目稠诲。整個項目做下來侦鹏,遇到的Bug很多诡曙,自然收獲也是很多÷运總結(jié)下來如下:

1.很長的單詞會超出邊界价卤,導(dǎo)致可視區(qū)域變寬。

解決辦法:通過word-wrap: break-word;實現(xiàn)打斷效果渊涝。

2.第二次進(jìn)入文章時慎璧,會殘留(暫未解決)。

解決辦法:通過路由的鉤子函數(shù)beforeRouteEnter跨释,來獲取數(shù)據(jù)胸私,未成功獲取數(shù)據(jù)時,顯示Loading頁面鳖谈,加載完成后岁疼,顯示文章詳情頁,從而解決這個問題缆娃。

3.回到首頁時五续,不能保留原來的狀態(tài)(暫未解決)。

解決辦法:

①此方法為容易固定高度的解決辦法龄恋。(具體方法:用vuex和vue-router的鉤子函數(shù)來解決這個問題疙驾,即通過scroll事件動態(tài)保存此時的scrollTop直,當(dāng)路由的beforeRouteEnter出發(fā)時郭毕,恢復(fù)其scrollTop的值它碎。)

② 如果沒有固定高度,直接通過Vue自帶的keep-alive組件显押,保留組件狀態(tài)扳肛。

4.載入中的動畫效果如何做?

解決辦法:之前是通過CSS3繪制一個圖形乘碑,但是后來發(fā)現(xiàn)太丑了挖息,就直接用了Iconfont上的svg圖,并添加了動畫效果兽肤。

5.如何實現(xiàn)主頁文章列表的懶加載套腹?

解決辦法:判斷滑動的總高度 - 滑動距離頂部的距離 <= 屏幕的可用高度,也就是以下公式:

document.documentElement.offsetHeight - window.scrollY
<= window.screen.height

這里會出現(xiàn)一個bug资铡,滿足條件時电禀,繼續(xù)滑動,會加載多次笤休。在此可以加入一個狀態(tài)尖飞,表示此時正在加載(詳細(xì)參見源代碼),從而解決此bug。

6.回到頂部的動畫怎么做政基?

解決辦法:可以把現(xiàn)在的window.scrollY分成n份贞铣,然后再設(shè)置一個定時器,每隔m秒沮明,向上滾動一份的高度咕娄,當(dāng)window.scrollY >= 0時,再終止定時器珊擂。(其中的m, n為任意數(shù)圣勒,根據(jù)情況設(shè)定)

7.如何控制正在加載頁面的顯示?

解決辦法:因為加載數(shù)據(jù)是異步的摧扇,可以在加載之前和加載之后圣贸,分別更改一個類似于isLoading(名稱自己設(shè)定)的狀態(tài),從而控制加載頁面的顯示扛稽。

8.如何設(shè)置登錄功能吁峻?

解決辦法:因為官方只提供了access-token,所以可以將此值和一些用戶相關(guān)的數(shù)值在张,存入document.cookie中用含,存入的函數(shù)我單獨寫了一個cookie的工具函數(shù),代碼如下:

/**
* Created by jerryshen on 2017/7/15.
* 用戶本地cookie的存取以及清空
* 函數(shù)的功能分別是:
* 設(shè)置單個帮匾,獲取所有啄骇,獲取單個,刪除所有瘟斜,刪除單個
*/

export function setCookie (name, value, exdays = 30) {
 var time = new Date()
 time.setTime(time.getTime() + exdays * 24 * 3600 * 1000)
 var expires = 'expires=' + time.toGMTString()
 document.cookie = name + '=' + value + ';' + expires
}

export function getAllCookies () {
 if (document.cookie === '') {
   return {}
 }
 const cookies = document.cookie.split(';')
 const newCookies = {}
 for (let i = 0; i < cookies.length; i++) {
   let cookie = cookies[i].trim()
   const splitCookie = cookie.split('=')
   newCookies[splitCookie[0]] = splitCookie[1]
 }
 return newCookies
}

export function getCookie (name) {
 const cname = name + '='
 const cookies = document.cookie.split(';')
 for (let i = 0; i < cookies.length; i++) {
   let cookie = cookies[i].trim()
   if (cookie.indexOf(cname) === 0) {
     return {
       success: true,
       cookie: {
         name,
         value: cookie.split(cname)[1]
       }
     }
   } else {
     return {
       success: false,
       cookie: {
         name,
         value: undefined
       }
     }
   }
 }
}

export function deleteAllCookie () {
 document.cookie += ';expires=Thu, 01 Jan 1970 00:00:00 GMT'
}

export function deleteCookie (name) {
 document.cookie = `${name}=;expires=Thu, 01 Jan 1970 00:00:00 GMT`
}

9.如何將API中的時間轉(zhuǎn)換成 => ..年前锐涯,..月前委粉,..天前等等,這種類型的格式呢舔株?

解決辦法:我自己寫了一個格式化的工具函數(shù)广凸,代碼如下:

export default function timeFormat (date) {
  // 獲取當(dāng)前時間和所傳時間的Date對象
  const nowTime = new Date()
  const inDate = new Date(date)
  if (nowTime.getYear() - inDate.getYear() > 0) {
    // 年份差值 > 0碗脊,返回年
    return `${nowTime.getFullYear() - inDate.getFullYear()}年前`
  } else if (nowTime.getMonth() - inDate.getMonth() > 0) {
    // 月份差值 > 0窝爪,返回月
    return `${nowTime.getMonth() - inDate.getMonth()}個月前`
  } else if (nowTime.getDate() - inDate.getDate() > 0) {
    // 日期差值 > 0塘匣,返回日
    return `${nowTime.getDate() - inDate.getDate()}天前`
  } else if (nowTime.getHours() - inDate.getHours() > 0) {
    // 小時差值 > 0,返回時
    return `${nowTime.getHours() - inDate.getHours()}個小時前`
  } else if (nowTime.getMinutes() - inDate.getMinutes() > 0) {
    // 分鐘差值 > 0取劫,返回分鐘
    return `${nowTime.getMinutes() - inDate.getMinutes()}分鐘前`
  } else {
    // 其他情況匆笤,也就是秒數(shù)差值 > 0,返回秒鐘
    return `${nowTime.getSeconds() - inDate.getSeconds()}秒前`
  }
}

10.BUG:當(dāng)進(jìn)入其他路由時勇凭,仍然會觸發(fā)主頁的scroll事件疚膊。

解決辦法:之前生命周期鉤子用的是mounted义辕,因此進(jìn)入其他路由時虾标,scroll事件仍然存在。所以現(xiàn)在改用beforeRouteEnterbeforeRouteLeave這兩個路由的生命周期鉤子,分別實現(xiàn)載入路由時的scroll事件掛載璧函、離開路由時的scroll事件卸載傀蚌。從而防止主頁內(nèi)容的懶加載一直觸發(fā)。

11.發(fā)布新文章或更新跳轉(zhuǎn)至文章詳情頁面后蘸吓,再按后退善炫,怎么實現(xiàn)回到主頁?

解決辦法:現(xiàn)在初步是使用库继,路由跳轉(zhuǎn)的時候箩艺,先跳到主頁,再跳到文章詳情頁宪萄,再按后退時艺谆,就會回到主頁。

12.如何實現(xiàn)點擊評論右側(cè)的回復(fù)按鈕拜英,添加@信息静汤,并focus輸入框?

解決辦法:通過vuex來實時記錄回復(fù)相關(guān)的信息居凶,并通過watch輸入框的value來判斷是否focus虫给。

13.有一個很奇怪的bug:ios下,如果在文章詳情頁返回主頁時侠碧,此時的window.scrollY會保持文章詳情頁時的window.scrollY抹估,如果此值滿足異步加載更多數(shù)據(jù)的條件時,會導(dǎo)致異常加載數(shù)據(jù)弄兜。

解決辦法:不得已棋蚌,只好在beforeRouteEnter鉤子中,綁定滾動事件的函數(shù)加一個定時器挨队,使其在100ms后綁定事件谷暮,所以此時的window.scrollY就會變成之前的值。

七盛垦、后記

本人新手一枚湿弦,還在苦逼的找工作中T_T。如過您在代碼中發(fā)現(xiàn)了bug腾夯,可以通過評論和我交流颊埃,互相學(xué)習(xí)!有什么好的想法蝶俱,也可以提出來班利,一起討論。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末榨呆,一起剝皮案震驚了整個濱河市罗标,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖闯割,帶你破解...
    沈念sama閱讀 221,198評論 6 514
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件彻消,死亡現(xiàn)場離奇詭異,居然都是意外死亡宙拉,警方通過查閱死者的電腦和手機宾尚,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,334評論 3 398
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來谢澈,“玉大人煌贴,你說我怎么就攤上這事∽斗蓿” “怎么了崔步?”我有些...
    開封第一講書人閱讀 167,643評論 0 360
  • 文/不壞的土叔 我叫張陵,是天一觀的道長缎谷。 經(jīng)常有香客問我井濒,道長,這世上最難降的妖魔是什么列林? 我笑而不...
    開封第一講書人閱讀 59,495評論 1 296
  • 正文 為了忘掉前任瑞你,我火速辦了婚禮,結(jié)果婚禮上希痴,老公的妹妹穿的比我還像新娘者甲。我一直安慰自己,他們只是感情好砌创,可當(dāng)我...
    茶點故事閱讀 68,502評論 6 397
  • 文/花漫 我一把揭開白布虏缸。 她就那樣靜靜地躺著,像睡著了一般嫩实。 火紅的嫁衣襯著肌膚如雪刽辙。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,156評論 1 308
  • 那天甲献,我揣著相機與錄音宰缤,去河邊找鬼。 笑死晃洒,一個胖子當(dāng)著我的面吹牛慨灭,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播球及,決...
    沈念sama閱讀 40,743評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼氧骤,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了吃引?” 一聲冷哼從身側(cè)響起筹陵,我...
    開封第一講書人閱讀 39,659評論 0 276
  • 序言:老撾萬榮一對情侶失蹤刽锤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后惶翻,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體姑蓝,經(jīng)...
    沈念sama閱讀 46,200評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡鹅心,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,282評論 3 340
  • 正文 我和宋清朗相戀三年吕粗,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片旭愧。...
    茶點故事閱讀 40,424評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡颅筋,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出输枯,到底是詐尸還是另有隱情议泵,我是刑警寧澤,帶...
    沈念sama閱讀 36,107評論 5 349
  • 正文 年R本政府宣布桃熄,位于F島的核電站先口,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏瞳收。R本人自食惡果不足惜碉京,卻給世界環(huán)境...
    茶點故事閱讀 41,789評論 3 333
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望螟深。 院中可真熱鬧谐宙,春花似錦、人聲如沸界弧。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,264評論 0 23
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽垢箕。三九已至划栓,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間条获,已是汗流浹背茅姜。 一陣腳步聲響...
    開封第一講書人閱讀 33,390評論 1 271
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留月匣,地道東北人钻洒。 一個月前我還...
    沈念sama閱讀 48,798評論 3 376
  • 正文 我出身青樓,卻偏偏與公主長得像锄开,于是被迫代替她去往敵國和親素标。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,435評論 2 359

推薦閱讀更多精彩內(nèi)容

  • 轉(zhuǎn)載 :OpenDiggawesome-github-vue 是由OpenDigg整理并維護(hù)的Vue相關(guān)開源項目庫...
    果汁密碼閱讀 23,135評論 8 124
  • 來源:github.com Vue.js開源項目速查表:https://www.ctolib.com/cheats...
    zhangtaiwei閱讀 11,626評論 1 159
  • 再見成都萍悴,不是別離的再見头遭,而是再次相見的再見寓免,成都,我學(xué)習(xí)生活了四年的城市计维,時隔半年袜香,我又回到你的懷抱,你的懷抱是...
    無痛不青春閱讀 1,138評論 0 3
  • 誰不想一直保持一副20歲的面容?尤其是女性欠母,臉蛋是女人最大的門面欢策,不管走到哪里,漂亮的女人永遠(yuǎn)是最受關(guān)注的赏淌。保持年...
    小蕾拉閱讀 549評論 0 0
  • 這張照片2015年正月十五拍攝于東莞踩寇。朋友問我怎樣拍的?喜歡攝影的人一定嘗試一下拍煙花這一課×現(xiàn)在簡單幾句分享一下...
    深圳男人閱讀 252評論 0 2