基於vue搭建一個簡易版豆瓣

nh0007發表於2019-03-03

前言

前段日子業餘時看了下vue,想著怎麼也得寫個例項來加深一下,於是便基於vue構建了一個簡易版豆瓣。由於工作中使用的並不是vue框架,對vue的瞭解也不夠深入,這也是本人第一次寫技術博文,因此,有紕漏之處還請大家批評指正。

專案概述

專案地址:github.com/nh0007/vue-…

專案簡介:本專案主要是基於vue,構建一個簡易版豆瓣,實現將讀書、電影、音樂、同城活動等內容按不同型別顯示的功能。

技術棧:vue + vuex + vue-router + axios + webpack + ES6,本專案使用vue-cli搭建,以vue為基礎,使用vuex管理資料、vue-router分發路由、axios請求資料。

專案背景:本專案介面參考自豆瓣,選擇豆瓣有兩個原因:一是本身蠻喜歡豆瓣,無論是豆瓣的內容還是設計;二是豆瓣有較為詳細的開發文件,詳情可參見:developers.douban.com/wiki/?title…,這也能使得剛上手vue的朋友也可以更加專注於vue前端開發。

開發環境:node v8.1.2,npm 5.0.3,瀏覽器:Google Chrome 65.0.3325.146/Firefox 58.0.2

執行專案

執行專案前,請確保本機已經正確安裝好node環境。

  • 克隆專案到本地,如果沒有安裝git環境,也可以在 vue-douban 處直接下載壓縮包。
    git clone https://github.com/nh0007/vue-douban.git複製程式碼
  • 在專案根目錄下,執行以下語句下載依賴:
    npm install複製程式碼
  • 下載完成後,執行專案:
    npm run dev複製程式碼
  • 執行完畢後,根據命令列視窗提示在瀏覽器輸入訪問地址即可。

專案截圖

本專案主要分為四大模組:讀書、電影、音樂、同城活動,以下是各個模組的部分截圖:

基於vue搭建一個簡易版豆瓣

基於vue搭建一個簡易版豆瓣

基於vue搭建一個簡易版豆瓣

基於vue搭建一個簡易版豆瓣

基於vue搭建一個簡易版豆瓣

基於vue搭建一個簡易版豆瓣

基於vue搭建一個簡易版豆瓣

基於vue搭建一個簡易版豆瓣

開發流程

如果你還沒有接觸過vue,可以先看看vue官方教程,畢竟官方文件才是最好的學習資料。如果你對ES6語法還不是很熟,也可以看看阮一峰老師的ECMAScript 6入門,當然,邊做專案時邊學習才是最高效的。以下是我自己在本專案的開發流程與思路,僅供參考:

  • 使用vue-cli搭建基於webpack的新專案,修改、刪除部分無關的vue元件,比如HelloWorld.vue。當然前提是你已經安裝好了vue-cli;
    vue init webpack vue-douban複製程式碼
  • 規劃一下專案頁面結構,再根據頁面、功能分配路由;因為本專案頁面結構並不複雜,所以在專案之初便大致規劃好了路由,每個路由又關聯到2-3個元件,可以先建立好對應的空元件,以book模組為例,book模組頁面大致分為三部分:

基於vue搭建一個簡易版豆瓣

因此,一開始,我們先設定好這個頁面的路由,再根據頁面結構大致建立為三個空的元件,存放在相應位置上,再將路由對映到這些元件上,程式碼如下。關於路由的具體設定可以參見vue-router官方文件,更多關於路由的設定可以參見原始碼。

const BaseHeader = () => import(`../components/common/BaseHeader.vue`)
const BookTag = () => import(`../components/book/BookTag.vue`)
const BookTagContent = () => import(`../components/book/BookTagContent.vue`)

export default new Router({
    routes: [
        {
            path: `/`,
            redirect: `/book-tag`
        },
        {
            path: `/book-tag`
            name: `bookTag`,
            components: {
                default: BaseHeader,
                aside: BookTag,
                content: BookTagContent
            }
        }
    ]
})複製程式碼
  • 規劃好某個路由相對應的元件後,我們便可以開始著手寫對應的元件。但在寫元件時我們很快會發現有些資料是各個元件共用的,vuex可以讓更加方便地管理公用資料,因此我們可以通過vuex劃分公用資料和各個模組資料。關於vuex的使用可以參照vuex的官方文件,相關設定可以參見原始碼。
  • 設定好router和store後,便進入激動人心的編寫元件環節了,首先我們將元件程式碼大致分為五大模組:公用模組、讀書模組、電影模組、音樂模組、城市活動模組,每個模組下面再劃分相應的元件,具體元件的編寫可以參照原始碼,這裡就不再贅述了,畢竟Talk is cheap,show me the code.如果有啥疑惑或發現啥問題,歡迎討論。
  • 在開發元件過程中,我們會發現有一些公用的元件、js函式、css,這時我們便可以進行抽取,以便複用。

以上便是我個人在專案的開發流程,當然只是個人經驗,實際開發中並不一定要按照這個流程進行。

開發過程中遇到的問題

  • 跨域問題:在開發環境中使用豆瓣api請求資料會產生跨域問題,所幸vue-cli構建的專案中,我們可以通過配置簡潔優雅的解決這個問題,開啟根目錄下config資料夾裡的index.js檔案,給proxyTable引數新增配置如下:
    proxyTable: {
    `/api`: {
          target: `https://api.douban.com`,
          changeOrigin: true,
          pathRewrite: {
               `^/api`: `/v2`
          }
    }}複製程式碼

通過上述的設定,主要有兩個作用,一個是簡化url,請求時省略字首,一個是在本機開啟一個服務轉發你的請求,以解決跨域問題,詳情可參見ProxyTable設定,這樣,我們這樣傳送網路請求:

const actions = {
    getCurrentTagBooks ({commit, state}, {count = 10, start = 0, type}) {
        axios.get(`./api/book/search`, {
            params: {
                tag: state.currentBookTag,
                count,
                start
            }
        })
            .then(response => {
                commit(types.SET_TAG_BOOKS, {books: response.data.books, type})
                commit(types.SET_CURRENT_TAG_BOOKS, {books: response.data.books, type})
            })
    }
}複製程式碼
  • 輪播內容實現。本次專案中不少內容需要用到輪播效果,這裡直接使用了vue自帶的列表過渡功能進行實現,通過判斷內容滑動的方向切換transition-group標籤的name值,再通過設定相對應CSS值實現輪播效果。具體可以參照官方關於過渡動畫的教程和專案原始碼。
  • 滑鼠移上書本顯示詳細資訊功能的實現。輪播內容的實現其實有賴於容器的定位屬性,如圖,由於外部容器會剪下子容器的溢位內容,所以顯示更多詳情的容器不能是外部容器的子容器,而是外部容器,通過滑鼠mouseenter事件傳遞書本資訊給外部容器,再通過計算具體位置進行顯示,具體程式碼可以參見BookTagContent.vue元件,若有更好的實現還請多指教。

基於vue搭建一個簡易版豆瓣

  • 圖片防盜鏈問題。圖書、電影的介面返回的圖片不存在防盜鏈的問題,而音樂介面返回的圖片清晰度較低,且設定了防盜鏈,解決防盜鏈可以通過設定img標籤的referrerpolicy屬性來解決,如下:
    <img :src="music.image" class="music-image" referrerpolicy="no-referrer>複製程式碼

vue使用體驗

  • 專案結構更加清晰。協作過前端的朋友應該有體會,如果專案沒有統一的規範和約定,前端的協作會是一個混亂的過程,因為不同的人寫出的前端程式碼各式各樣,給協作與後期維護增加了很多成本。使用vue元件化使得專案結構更加清晰,且元件內的結構也相當清晰,比如視覺化用到的資料存放在data屬性中,需要監聽的大多數資料存放在computed屬性中,元件用到的方法存放在methods屬性中。vue為元件設定了一套規定,這樣專案合作起來就不至於太混亂。
  • 程式碼量更少。開發完本專案我掂量了一下,如果使用原生js或者jQuery開發同樣的功能,程式碼量至少翻三倍,畢竟通過後臺返回的資料構建元素,插入介面,再為某些元素繫結事件之類的程式碼就得一大坨。當然,程式碼量的減少有賴於vue在後臺為我們做了許多工作,感謝尤大。

專案不足之處

由於使用vue並不多,且本專案完成也較匆忙,所以專案存在不足之處或者哪些功能有更好的實現還請大家指出,我好學習改正,當然我自己也列舉了專案的一些不足:

  • 由於使用的是豆瓣api,頻繁請求會出現請求無效問題,但介面上並沒有為此設定友好的介面提示;
  • 在通過網路請求資料時,頁面在資料未返回時直接空白顯示,沒有loading提示,使用者體驗不佳。(其實我一開始是加了loading.gif進行提示的,但覺得有點難看就去掉了~)
  • 同城活動模組沒有設定快取,導致每次點選切換城市或者型別都要向豆瓣請求資料。

結語

這是本人第一次寫技術部落格,還是有些戰戰兢兢,寫的不好的地方,所以還請大家多批評指正。另外,歡迎向star本專案哦~

相關文章