Vue實現20+頁面的複雜單頁面應用(仿實驗樓)

前言

初學Vue,搜Vue項目時出現的幾乎都是TODO應用,音樂播放器之類複雜度並不如想象中高的應用,固然慢慢摸索實現出來也會知道Vue的一些功能,v-on,v-bind之類的綁定,v-for,v-if 等邏輯控制。但寫完總感受意猶未盡... 因而想實現一個稍微複雜些的應用。css

項目主要實現的是前端頁面部分,數據來源於實驗樓原站,原站API不支持跨域調用,須要使用一個轉發html

效果展現

路徑
課程
課程

線上演示(Github Page)前端

技術棧

vue2 + vuex + vue-router + axios + flexvue

知識點總結

vue-router

懶加載

路由懶加載由官方文檔中說明的做用是打包應用時的按需加載:最終的目的老是要打包發佈,因此懶加載必定要知道。ios

const __import__ = file => () => import(`@/pages/${file}.vue`)
...
{
    name: 'home',
    component: __import__('home') 
}
複製代碼

路由切換過渡動畫

單頁面應用能夠很方便的製做切換不一樣頁面時使用的動畫效果,像是手機APP中的左滑右滑之類的。這裏實現的過渡動畫效果是透明度由0到1的緩慢漸變浮現效果。使用Vue的過渡動畫組件便可 git

過渡

<template>
  <div id="app">
    <transition name="tab_router_view">
      <router-view></router-view>
    </transition>
  </div>
</template>
<style> .tab_router_view-enter-active, .tab_router_view-leave-active { transition: opacity .8s; } .tab_router_view-enter, .tab_router_view-leave-to { opacity: 0; } .tab_router_view-enter-to, .tab_router_view-leave { opacity: 1; } </style>
複製代碼

這樣每次切換路由時都會觸發一個透明度從0到1的0.8秒漸變效果: github

漸變

路由導航守衛

路由導航守衛能夠在每次路由變化時讓咱們作一些功能性的調整,如切換的這個頁面若是須要登陸那麼咱們能夠這樣:vue-router

...
{
    path: '/profile',
    name: 'profile',
    component: Profile,
    meta: {
        login: true
    }
}
router.beforeEach((to, from, next)=>{
    if (to.meta.login) {
        if (!store.state.loginState.isLogin) {
            next({name: 'login'})
        } else {
            next()
        }
    }
})
複製代碼

上面的守衛實現了若是當前頁面要求登陸但沒有登陸的話會跳轉到登陸頁面,這樣就不須要每一個頁面都設置一遍檢查了, 另外前置導航守衛必定要記得調用next,不然不會有組件加載出來。vuex

每次切換路由頁面後咱們極可能還須要一個後置導航守衛來替咱們將頁面滾到最上部npm

router.afterEach((to, from) => {
    window.scrollTo(0, 0)
})
複製代碼

區別於前置守衛,後置守衛沒有next須要調用。

vuex

vuex被用來進行狀態管理,這是一個全局的數據倉庫一類的東西,數據的下載,轉換,保存都放在裏面進行。Vue的組件裏固然也能夠進行數據的下載保存,也能夠進行不一樣組件件的傳遞,但隨着業務增多每每會變得至關麻煩。

不用vuex狀態管理的話通常會順着思路這麼寫:

數據由父組件下載並保存下來傳遞到子組件:

<SubComponent :data="dataOne">
</SubComponent>
...
data: function () {
    return {
        dataOne: {}
    }
},
created: async function () {
    let res = await get('http://www.ceshi.com')
    this.dataOne = res.data
}
複製代碼

子組件內有一個觸發填好後發起頁面修改,但子組件是不能直接修改父組件傳遞過來的數據的,因此又須要發送一個信號讓父組件接受後由父組件修改:

子組件

props: {
    data: {
        type: Object,
        require: true
    }
},
methods: {
    change: fucntion (data) {
        this.$emit('change', data)
    }
}
複製代碼

父組件

<SubComponent :data="dataOne"
              @change="change"
>
</SubComponent>
...
methods: {
    change: async function (data) {
        await get(...)
    }
}
複製代碼

多寫了一個change方法不說,還須要不忘記註冊子組件的事件,想一想這只是兩個組件間的通訊,隨着組件的增多,原本只須要一個方法的事情會須要兩個三個,事件的註冊也愈來愈多,取決於嵌套了多少子組件,稍微不注意忘了註冊哪一個事件就要debug很長時間。

若是用了vuex就會簡單不少,由於它是一個全局的狀態管理。

父組件只須要負責把觸發數據下載。

<SubComponent></SubComponent>
...
created: async function () {
    await this.$store.dispatch('dataStore/getData')
}
複製代碼

子組件內的數據就會跟隨更改,修改數據也不用再通知父組件

computed: {
    dataOne: function () {
        return this.$store.state.dataStore.dataOne
    }
},
methods: {
    change: async function (data) {
        await this.$store.dispatch('dataStore/getData', data)
    }
}
複製代碼

這樣的全局狀態管理不會由於嵌套的子組件而增長複雜度,並且具備良好的可讀性,如何操做數據在store裏進行修改,組件裏只須要觸發便可。

API跨域配置

實驗樓原站也是使用Vue編寫,先後端分離,使用API通信,咱們能夠把API抓取下來使用,固然我已經抓好了,實驗樓API後端,實驗樓的API與展現在同一個域名下,因此不存在跨域問題,但咱們開發的話就不是在同一個域名下,要使用的話繞不開的一環就是跨域了。因爲服務器端不支持跨域,要使用只能作一個轉發,先來了解一下跨域吧。

同源策略

同源策略限制了從同一個源加載的文檔或腳本如何與來自另外一個源的資源進行交互。這是一個用於隔離潛在惡意文件的重要安全機制。也就是說 在http://www.baidu.com的Js,若是沒有跨域配置是沒法與http://juejin.im進行通信的。

服務器端跨域配置

無論後端使用何種語言,要解決跨域就是要讓服務器的回覆中添加如下頭:

Access-Control-Allow-Origin:*
Access-Control-Allow-Methods:POST
Access-Control-Allow-Headers:x-requested-with,content-type
複製代碼

Access-Control-Allow-Origin 表示能夠請求的源,*表示任意一個均可以。

Access-COntrol-Allow-Methods 表示請求時的方法,POST表示只有POST請求才能夠進行跨域請求,GEt,PUT,DELETE之類的若是沒有標明通通不能夠。

Access-Control-Allow-Headers表示跨域容許的首部。

Vue中的配置

本地開發的話能夠在Vue的配置文件中進行配置config/index.js,下面是配置的開發環境的跨域請求:

dev: {
    proxyTable: {
          '/api': {  
            target: 'http://localhost:8000/api',// 設置你調用的接口域名
            changeOrigin: true,  
            pathRewrite: {  
              '^/api/': '' // 這裏替換的是 target 中的內容,使用的時候 '/api/demo' 就至關於'http://localhost:8000/api/demo'。
            }  
          }
    }
}
複製代碼

生產環境下的跨域:

生產環境下若是跨域不須要攜帶cookies認證那服務器配置了上面說的幾個響應頭便可,不然的話還須要

Access-Control-Allow-Credentials:true
複製代碼

以及

Access-Control-Allow-Origin
複製代碼

不能夠爲**與credentials是衝突的。

最後使用 axios 請求時須要配置withCredentials = true

CSS佈局

項目中使用了flex佈局,flex佈局使用起來比較流暢,寫起來也很簡單,任意元素加上

.box {
    display: flex
}
複製代碼

這樣這個元素的內容就會按照默認的flex進行佈局

佈局
默認水平走向,不會換行,從容器的最左端開始排列。 容器裏元素的如何排列咱們能夠經過這些屬性來設置:

flex-direction  排列方向 row | column
flex-wrap wrap | nowrap
flex-flow 上面兩個的簡寫 row nowrap
justify-content 指定元素主軸(main axis)對其方式 flex-start | flex-end | center | space-between | space-around
align-items 指定元素交叉軸(corss axis)對其方式 flex-start | flex-end | center | baseline | stretch
複製代碼

瞭解上面這一點就能夠把常規的佈局方式熟悉一下,只用上面這些就能夠搭建出首頁。

這裏是關於flex更詳細的資料

最後

完整的項目請看GitHub

克隆後直接啓動便可:

git clone git@github.com:HuberTRoy/vue-shiyanlou.git

cd vue-shiyanlou

npm install

npm run dev
複製代碼

若是對您有幫助,但願能夠獲得一枚您的Star~。(〃'▽'〃) 有任何能夠改進的地方但願您能夠花費一些時間開啓一個Issue或者直接PR~。φ(>ω<*)

相關文章
相關標籤/搜索