今天我們將學習如何用VUE構建一個簡單的單頁應用(SPA)
如果沒有其他特殊聲明,此教程中的VUE全部指的是VUE2.X版本
預覽
讓我們先看看最終的的單頁程序是什么樣子的

閱讀本教程之前希望你能有如下的基礎知識:
- VUE基礎
- 如何創(chuàng)建VUE組件
如果你沒有任何VUE或者VUE組件的知識,可以看我之前的文章
使用Vue CLI 腳手架
我們將使用VUE提供的腳手架模塊Vue CLI,它可以使我們構建的程序兼容ES5版本的瀏覽器。
NOTE: 當然這需要你在Node.js環(huán)境下進行開發(fā),如果你還沒有Node.js和NPM的基本知識,建議你花半個小時的時間配置好Node.js環(huán)境,相信我,很簡單,百度隨便一搜就出來一大把教程。
如何你還沒有安裝Vue CLI,你可以用下面的命令進行安裝
npm install -g vue-cli
NOTE: vue-cli已經有了3.0版本,改名為 @vue/cli, 但是當前vue-cli還是可以使用的,因為大部分用戶還是在用vue-cli,所以本教程也繼續(xù)使用vue-cli作為教學。
安裝完Vue CLI,我們將通過下面的命令構建我們的VUE項目。
vue init webpack spa
在上面的命令中,我們說明一下webpack和spa這兩個參數(shù).
Webpack是指你想用哪個腳手架模板,這里其實用很多模板供我們選擇,比如簡化版webpack-simple,具體使用方法可以參考這里
SPA指的是你要把項目放在哪個文件夾里,這里就是SPA這個文件夾,如果沒有系統(tǒng)會自動創(chuàng)建。
運行上面這個命令后,會有一些選項讓你選擇,比如項目的名字等等,全部默認就可以。
運行完上面的命令后,我們需要將當前路徑改變到SPA這個文件夾內,然后安裝需要的模塊:
//改變路徑到spa文件夾下
cd spa
//安裝所有項目需要的npm模塊
npm install
//在開發(fā)環(huán)境下運行程序
npm run dev
當上面的命令運行起來的時候,用瀏覽器訪問 http://localhost:8080 這個地址,我們會看到如下頁面:

VUE Router 的安裝與配置
在我們正式開始配置我們的單頁程序之前,還有一個東西必須安裝,vue-router。
vue-router 是VUE官方提供的一個路由組件,專門用來構建VUE的單頁程序,它包含如下一些特點:
- 支持嵌套路由
- 組件化路由配置
- 支持路由參數(shù)傳遞,支持通配符
- 比傳統(tǒng)路由更加優(yōu)化的導航控制
- 自動激活不同CSS樣式
- 支持HTML5歷史模式或哈希模式,支持IE9的自動回退功能
- 支持自定義的滾動軸特性
如果你之前接觸過angular router或者react-router,其實vue-router跟這兩個非常相似。
我們使用vue-router的原因就是它可以使我們的頁面在前端就完成切換,而不是每次切換頁面都要向服務器重新請求數(shù)據(jù),重載頁面。
換句話說,一個單頁程序就像是一個安裝在本地APP一樣,使用起來比傳統(tǒng)的網頁更加的流暢。
我們可以用下面的命令安裝vue-router.
npm install vue-router --save
現(xiàn)在讓我們打開 src/main.js 文件夾把路由模塊配置到我們的程序里.
復制下面的內容并替換原來的 src/main.js:
// 導入vue實例
import Vue from 'vue'
//導入 App 組件
import App from './App'
//導入 vue router
import VueRouter from 'vue-router'
//告訴vue使用vue-router路由組件
Vue.use(VueRouter)
//定義路由表
const routes = []
// 創(chuàng)建路由器實例,并且傳入`routes`變量作為路由。
// 你還可以傳入別的參數(shù),不過在這里盡量簡單化就可以了
const router = new VueRouter({
routes,
mode: 'history'
})
//實例化Vue實例
new Vue({
//定義Vue綁定的跟元素
el: '#app',
//用<App/>代替根元素
template: '<App/>',
//聲明App組件,這樣上面的<App/>元素就可以生效
components: { App },
//將上面聲明的路由器傳遞到根Vue實例
router
}).$mount('#app')//將這個實例掛載到id=app的根元素上
讓我們屢一下上面這一段代碼,首先我們從node模塊中導入了vue模塊,接著我們又導入了App模塊(這個是本地定義的模塊)。
這個App模塊是我們在用vue cli腳手架創(chuàng)建這個項目的時候默認幫我們創(chuàng)建的,作為我們整個項目的根模塊。
之后,我們導入了vue-router, 接著我們使用vue的靜態(tài)方法Vue.use,告訴vue我們將使用vue-router這個組件。
在下一行,我們定義了一個空的routes數(shù)組變量。每一個routes里面的元素為一條路由信息。當前里面還沒有路由信息,后續(xù)會添加。
NOTE:注意英文中routes和router的區(qū)別,router是一個組件,route是一條路由信息,routes是由多個路由信息(route)組成的路由表。
可以這么理解,把router當成一個工人,這個工人(router)拿到一張由很多路由信息(route)組成的路由表(routes),然后每一次用戶請求頁面變化時,工人(router)會逐條比對路由表(routes)上的路由信息(route),遇到第一條匹配的信息就將對應的頁面反饋給用戶
接下來我們做的是創(chuàng)建我們的路由器(router),一個vue-router的實例,在這里我們給它傳入了兩個參數(shù)。
第一個參數(shù)是一個我們之前聲明過的數(shù)組變量,路由表(routers),另一個參數(shù)在聲明一種路由模式,這種模式下我們在URL中不會看到前導的#號。
有興趣的讀者可以試試不加這個參數(shù)觀察一下URL有什么變化。同時,去掉這個#號也會使SEO優(yōu)化更加好。
最后,我們創(chuàng)建了一個Vue實例,傳入了根組件<App/>,聲明了Vue的掛載點。
現(xiàn)在,如果我們重新運行這個程序,會發(fā)現(xiàn)頁面沒有任何變化。下面我們將會開始設置路由。
我將會把路由管道標簽(<router-view></router-view>)加入到根組件<App/>中,也就是當url符合某個路由信息(route)時,對應的組件就會被渲染(render)到這個路由管道標簽內。
現(xiàn)在打開src/App.vue文件,也就是根組件文件,用下面的內容替換原有的內容:
<template>
<div id="app">
<!--路由管道標簽,任何符合某一路由(route)信息的組件都會在這個標簽內展示出來 -->
<router-view></router-view>
</div>
</template>
<script>
export default {
name: 'app',
}
</script>
<!-- css格式 -->
<style>
#app {
font-family: 'Avenir', Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
margin-top: 60px;
}
</style>
上面的代碼和用vue-cli自動生成的代碼有幾點不一樣:
- 多了 router-view 標簽用來渲染符合路由條件的組件
- 刪除了導入hello組件的語句
import hello - 刪除了
script中關于component的定義 - 刪除了默認的component是因為我們不需要了,因為我們在上面已經定義了路由管道標簽
<router-view>
這時候我們在重新運行程序,會發(fā)現(xiàn)是空白頁面
路由初始化
這時候我們需要定義Hello模塊作為我們的Home頁面,然后把相應的路由信息(route)加到路由表(routes)中
打開main.js文件,把routes變量修改成如下形式并導入Hello組件:
//導入hello組件
import Hello from './components/Hello'
//定義路由表
const routes = [
//將根URL加入到路由表并聲明對應Hello組件.
{ path: '/', component: Hello }
]
在上面的代碼中我們引入了腳手架默認添加的Hello組件,并且將根URL / 對應到了Hello組件上,這時候如果我們重新運行程序,會像下面這樣:

上面這個圖片里,Vue的logo已經不見了,這是因為之前在APP組件中已經將顯示VUE logo圖標的代碼刪除了。
現(xiàn)在,讓我們定義更多的路由,在這之前先再創(chuàng)建一個組件。
在 src/somponents 文件夾下創(chuàng)建一個 About.vue 文件,然后把下面的代碼放進去。
<template>
<div id="about">
When you have a great story about how your product or service was built to change lives, share it. The "About Us" page is a great place for it to live, too. Good stories humanize your brand, providing context and meaning for your product. What’s more, good stories are sticky -- which means people are more likely to connect with them and pass them on.
</div>
</template>
<script>
export default {
name: 'about'
}
</script>
<style>
#about {
font-family: 'Avenir', Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
margin-top: 60px;
}
</style>
讓我們來看看上面這個About組件,這個組件里面只有簡單的一段話,當URL正好對應這個組件的時候,它就會被渲染到<router-view>標簽里面。
在這之前,我們需要在路由表中加入這個組件對應的路由。
打開 main.js 然后把路由表(routes)改成如下形式。
//導入Hello組件
import Hello from './components/Hello'
//導入Aboiut組件
import About from './components/About'
//定義路由表
const routes = [
//對應Hello組件的路由地址
{ path: '/', component: Hello },
//對應About組件的路由地址
{ path: '/about', component: About }
]
上面代碼唯一的改動就是增加了About組件的引入和對應的路由信息。
這時候如果我們在瀏覽器中訪問 http://localhost:8080/about 這個地址,我們就會看到剛剛我們在About組件中寫的那段話。
在頁面中使用<router-link>標簽
但是我們不能總是手工在瀏覽器中輸入地址去切換頁面,所以我們需要用到另一個路由器標簽<router-link></router-link>。
打開 App.vue 文件,然后在<router-view>標簽上面加入兩個<router-link>標簽:
<router-link v-bind:to="'/'">Home</router-link>
<router-link v-bind:to="'/about'">About</router-link>
上面兩個標簽的作用就是創(chuàng)建兩個指向對應URL的超鏈接,用來做動態(tài)的路由轉換 (不用重載頁面的頁面轉換)。
這時候如果你重新啟動程序,會注意到頁面上多了兩個可以點擊的超鏈接,點擊任意一個,頁面和URL也會隨著變動,而且頁面并沒有重載。
程序看起來是這個樣子的:

總結
好了,這就是如何構建一個單頁程序(SPA)。
當然,這個程序也可以構建的更加復雜一些,比如:
- 添加更多的路由
- 通過路由傳遞參數(shù)信息
- 使用路由守護(route guards)來在保證沒有權限的用戶不能訪問特定頁面
在下一個教程中,我會分別介紹路由的參數(shù)傳遞和路由守護功能。
碼字不易,喜歡請點贊