單頁應(yīng)用的優(yōu)缺點
每種技術(shù)都有其利弊,單頁應(yīng)用也是如此牢撼。
- 無刷新體驗惧浴,這個應(yīng)該是最顯著的有點肛鹏,由于路由分發(fā)直接在瀏覽器端完成骗村,頁面是不刷新飞涂,對用戶的響應(yīng)非常及時旦部,因此提升了用戶體驗祈搜;
- 完全的前端組件化,前端開發(fā)不再以頁面為單位士八,更多地采用組件化的思想容燕,代碼結(jié)構(gòu)和組織方式更加規(guī)范化,便于修改和調(diào)整婚度;
- API 共享蘸秘,如果你的服務(wù)是多端的(瀏覽器端、Android蝗茁、iOS醋虏、微信等),單頁應(yīng)用的模式便于你在多個端共用 API哮翘,可以顯著減少服務(wù)端的工作量颈嚼。容易變化的 UI 部分都已經(jīng)前置到了多端,只受到業(yè)務(wù)數(shù)據(jù)模型影響的 API饭寺,更容易穩(wěn)定下來阻课,便于提供魯棒的服務(wù);
- 組件共享艰匙,在某些對性能體驗要求不高的場景柑肴,或者產(chǎn)品處于快速試錯階段,借助于一些技術(shù)(Hybrid旬薯、React Native),可以在多端共享組件适秩,便于產(chǎn)品的快速迭代绊序,節(jié)約資源。
缺點:
- 首次加載大量資源秽荞,要在一個頁面上為用戶提供產(chǎn)品的所有功能骤公,在這個頁面加載的時候,首先要加載大量的靜態(tài)資源扬跋,這個加載時間相對比較長阶捆;
- 較高的前端開發(fā)門檻,MVC 前置钦听,對前端工程師的要求提高了洒试,不再是『切切圖,畫畫頁面這么簡單』朴上;同時工作量也會增加數(shù)倍垒棋,開發(fā)這類應(yīng)用前端工程師的數(shù)量往往多于后端;
- 不利于 SEO痪宰,單頁頁面叼架,數(shù)據(jù)在前端渲染畔裕,就意味著沒有 SEO,或者需要使用變通的方案乖订。
使用vue-router構(gòu)建單頁應(yīng)用
vue-router.js是Vue.js官方的路由插件用于構(gòu)建單頁面應(yīng)用扮饶。
vue的單頁應(yīng)用是基于路由和組件的。傳統(tǒng)的頁面應(yīng)用乍构,是用一些超鏈接來實現(xiàn)頁面切換和跳轉(zhuǎn)的甜无。在vue-router單面應(yīng)用中,則是路徑之間的切換蜡吧,也就是組件的切換毫蚓。
先來看一下官方提供的最簡單的例子:示例
HTML
<script src="https://unpkg.com/vue/dist/vue.js"></script>
<script src="https://unpkg.com/vue-router/dist/vue-router.js"></script>
<div id="app">
<h1>Hello App!</h1>
<p>
<!-- 使用 router-link 組件來導(dǎo)航. -->
<!-- 通過傳入 `to` 屬性指定鏈接. -->
<!-- <router-link> 默認(rèn)會被渲染成一個 `<a>` 標(biāo)簽 -->
<router-link to="/foo">Go to Foo</router-link>
<router-link to="/bar">Go to Bar</router-link>
</p>
<!-- 路由出口 -->
<!-- 路由匹配到的組件將渲染在這里 -->
<router-view></router-view>
</div>
- router-link標(biāo)簽:跳轉(zhuǎn)的鏈接,to=""是必須的屬性昔善,雙引號中的內(nèi)容是我們接下來在JS文件中定義的路由path元潘。
- router-view標(biāo)簽:展示我們匹配到的組件的區(qū)域。
JavaScript
// 0. 如果使用模塊化機(jī)制編程君仆,導(dǎo)入Vue和VueRouter翩概,要調(diào)用 Vue.use(VueRouter)
// 1. 定義(路由)組件。
// 也可以從其他文件 import 進(jìn)來
const Foo = { template: '<div>foo</div>' }
const Bar = { template: '<div>bar</div>' }
// 2. 定義路由
// 每個路由應(yīng)該映射一個組件返咱。 其中"component" 可以是
// 通過 Vue.extend() 創(chuàng)建的組件構(gòu)造器钥庇,
// 或者,只是一個組件配置對象咖摹。
const routes = [
{ path: '/foo', component: Foo },
{ path: '/bar', component: Bar }
]
// 3. 創(chuàng)建 router 實例评姨,然后傳 `routes` 配置
// 你還可以傳別的配置參數(shù), 不過先這么簡單著吧。
const router = new VueRouter({
routes // (縮寫)相當(dāng)于 routes: routes
})
// 4. 創(chuàng)建和掛載根實例萤晴。
// 記得要通過 router 配置參數(shù)注入路由吐句,
// 從而讓整個應(yīng)用都有路由功能
const app = new Vue({
router
}).$mount('#app')
// 現(xiàn)在,應(yīng)用已經(jīng)啟動了店读!
JavaScript文件主要做的事情是:
- 定義路由列表嗦枢,即routes。
- 創(chuàng)建router實例及router配置屯断,即router文虏。
- 創(chuàng)建和掛載根實例。
以上只是教我們用最簡單的方法使用vue-router殖演。但實際開發(fā)過程中氧秘,首先我們的vue組件顯然不會只有一個template模板這么簡單,會用到vue的單文件組件趴久;
其次我們通常會希望<router-view>的范圍是整個頁面敏储,而不是像現(xiàn)在這樣一直有幾個礙眼的導(dǎo)航存在于頁面上,這就需要先定義好默認(rèn)狀態(tài)下<router-view>顯示的內(nèi)容朋鞍。
既然是單頁應(yīng)用(SPA)已添,那么整個項目有以下三個文件是必要的:
- 一個html文件:index.html
- 一個webpack打包時的入口js文件:main.js
- 一個根vue組件妥箕,作為其他組件的掛載點:app.vue
接下來 我們就創(chuàng)建兩個自定義組件:index.vue和hello.vue。我們希望的結(jié)果是他們之間互相跳轉(zhuǎn)更舞。
我們利用官方提供的腳手架vue-cli
工具生成簡單的一個基于webpack打包的vue項目
準(zhǔn)備工作:
npm install webpack -g
npm install vue-cli -g
//打開要創(chuàng)建的項目路徑目錄畦幢,創(chuàng)建項目
vue init webpack-simple <項目名>
cd <項目名>
//安裝依賴
npm install
//安裝vue-router
npm install vue-router --save
npm run dev
生成的vue項目如下圖:
一、使用路由
- 首先在目錄下創(chuàng)建components文件夾缆蝉,然后再創(chuàng)建index.vue和hello.vue文件
//index.vue
<template>
<div>
<h2>Index</h2>
<hr>
<p>{{sContent}}</p>
</div>
</template>
<script>
export default{
data(){
return {
sContent:"This is index components"
}
}
}
</script>
//hello.vue
<template>
<div>
<h2>Hello Vue.js</h2>
<hr/>
<p>{{sContent}}</p>
</div>
</template>
<script>
export default{
data(){
return {
sContent:"This is hello components"
}
}
}
</script>
- 修改main.js文件
//引入并安裝vue-router插件
import Vue from 'vue';
import VueRouter from 'vue-router';
Vue.use(VueRouter);
//引入index.vue和hello.vue組件
import App from './App.vue';
import index from './components/index.vue';
import hello from './components/hello.vue';
//定義路由
const routes = [
{path:'/',component:App},
{ path: '/index', component: index },
{ path: '/hello', component: hello }
]
//創(chuàng)建 router 實例,然后傳 routes 配置
const router=new VueRouter({
routes
});
//創(chuàng)建和掛載根實例黍瞧。通過 router 配置參數(shù)注入路由原杂,從而讓整個應(yīng)用都有路由功能
new Vue({
el:"#app",
router
});
- 修改App.vue
<template>
<div>
![](./assets/logo.png)
<h1>{{msg}}</h1>
<ul>
<router-link to='/index' tag='li'><a href="/index">Index</a></router-link>
<router-link to='/hello' tag='li'><a href="/hello">Hello</a></router-link>
</ul>
</div>
</template>
- 修改index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>vue-webpack-simple</title>
</head>
<body>
<div id="app">
<router-view></router-view>
</div>
<script src="/dist/build.js"></script>
</body>
</html>
這樣就會把渲染出來的頁面掛載到這個id為app的div里了印颤。
修改后運行的效果如下:
二穿肄、重定向 redirect
const routes = [
{ path: '/', redirect: '/index'}, // 這樣進(jìn)/ 就會跳轉(zhuǎn)到/index
{ path: '/index', component: index }
]
三、嵌套路由
const routes = [
{ path: '/index', component: index,
children: [
{ path: 'info', component: {template:'<p>This is info component</p>'}}
]
}
]
四咸产、命名路由
const routes = [
{ path: '/index', component: index,
name:'index'
}
]
五矢否、<router-link>標(biāo)簽屬性
//to屬性 string|object
<!-- 字符串 -->
<router-link to="home">Home</router-link>
<!-- 渲染結(jié)果 -->
<a href="home">Home</a>
<!-- 使用 v-bind 的 JS 表達(dá)式 -->
<router-link v-bind:to="'home'">Home</router-link>
<!-- 同上 -->
<router-link :to="{ path: 'home' }">Home</router-link>
<!-- 命名的路由 -->
<router-link :to="{ name: 'user', params: { userId: 123 }}">User</router-link>
<!-- 帶查詢參數(shù)脑溢,下面的結(jié)果為 /register?plan=private -->
<router-link :to="{ path: 'register', query: { plan: 'private' }}">Register</router-link>
//replace屬性 true|false 不留下 history 記錄屑彻。
<router-link to="home" replace>Home</router-link>
//append屬性 true|false 追加路徑
<router-link to="home" append >Home</router-link>
//tag屬性 string 設(shè)置渲染標(biāo)簽
<router-link to="/foo" tag="li">foo</router-link>
<!-- 渲染結(jié)果 -->
<li>foo</li>
//active-class 屬性 string 激活時使用的 CSS 類名
五酱酬、路由信息對象
-
$route.path
字符串,對應(yīng)當(dāng)前路由的路徑挑社,總是解析為絕對路徑巡揍,如 "/foo/bar"痛阻。 -
$route.params
一個 key/value 對象,包含了 動態(tài)片段 和 全匹配片段腮敌,如果沒有路由參數(shù)阱当,就是一個空對象俏扩。 -
$route.query
一個 key/value 對象,表示 URL 查詢參數(shù)弊添。例如录淡,對于路徑 /foo?user=1,則有 $route.query.user == 1油坝,如果沒有查詢參數(shù)嫉戚,則是個空對象。 -
$route.hash
當(dāng)前路由的 hash 值 (不帶 #) 澈圈,如果沒有 hash 值彬檀,則為空字符串。 -
$route.fullPath
完成解析后的 URL瞬女,包含查詢參數(shù)和 hash 的完整路徑窍帝。 -
$route.matched
一個數(shù)組,包含當(dāng)前路由的所有嵌套路徑片段的 路由記錄 拆魏。路由記錄就是 routes 配置數(shù)組中的對象副本(還有在 children 數(shù)組)盯桦。
以上遍是vue-router基本使用方式了
更詳細(xì)的vue-router功能請參考文檔:https://router.vuejs.org/zh-cn/