前言
初學Vue,搜`Vue項目`時出現的幾乎都是TODO應用,音樂播放器之類複雜度并不如想象中高的應用,當然慢慢摸索實作出來也會知道Vue的一些功能,`v-on`,`v-bind`之類的綁定,`v-for`,`v-if` 等邏輯控制。但寫完總感覺意猶未盡... 于是想實作一個稍微複雜些的應用。
項目主要實作的是(前端頁面部分),資料來源于實驗樓原站,原站API不支援跨域調用,需要使用一個(轉發)。
效果展示
線上展示
- 實驗樓syl.cyr.buzz
從0開始到線上釋出的配套教程~(收費,優惠邀請碼
eee1ZIbn)
Vue.js 和 Django 仿簡易版實驗樓www.shiyanlou.com
技術棧Vue.js 和 Django 仿簡易版實驗樓技術棧
`vue2` + `vuex` + `vue-router` + `axios` + `flex`
知識點總結
vue-router 懶加載路由懶加載由(官方文檔)中說明的作用是打包應用時的按需加載:最終的目的總是要打包釋出,是以懶加載一定要知道。
const __import__ = file => () => import(`@/pages/${file}.vue`)
...
{
name: 'home',
component: __import__('home')
}
路由切換過渡動畫 單頁面應用可以很友善的制作切換不同頁面時使用的動畫效果,像是手機APP中的左滑右滑之類的。這裡實作的過渡動畫效果是透明度由0到1的緩慢漸變浮現效果。使用Vue的過渡動畫元件即可
<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秒漸變效果:
路由導航守衛(路由導航守衛)可以在每次路由變化時讓我們做一些功能性的調整,如切換的這個頁面如果需要登入那麼我們可以這樣:
...
{
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`,否則不會有元件加載出來。
每次切換路由頁面後我們很可能還需要一個
後置導航守衛來替我們将頁面滾到最上部
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`布局使用起來比較流暢,寫起來也很簡單,任意元素加上
.
這樣這個元素的内容就會按照預設的`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`更詳細的資料
Flex 布局文法教程 | 菜鳥教程www.runoob.com
最後完整的項目請看
Githubgithub.com
克隆後直接啟動即可:
git clone [email protected]:HuberTRoy/vue-shiyanlou.git
cd vue-shiyanlou
npm install
npm run dev
如果對您有幫助,希望可以得到一枚您的Star~。(〃'▽'〃)
有任何可以改進的地方希望您可以花費一些時間開啟一個Issue或者直接PR~。φ(>ω<*)