npm install vue-router --savevue
// The Vue build version to load with the `import` command
// (runtime-only or standalone) has been set in webpack.base.conf with an alias.
import Vue from 'vue';
import Vuex from 'vuex';
import VueResource from 'vue-resource';webpack
import App from './App';
import router from './router';
import store from './store';
// Resource
Vue.use(VueResource);web
// vuex
Vue.use(Vuex);vue-router
Vue.config.productionTip = false;vuex
/* eslint-disable no-new */
new Vue({
el: '#app',
router,
store,
template: '<App/>',
components: { App }
});npm
咱們先來看一下 router/index.js 代碼以下:編程
import Vue from 'vue';
import Router from 'vue-router';
import HelloWorld from '@/views/HelloWorld';瀏覽器
Vue.use(Router);app
export default new Router({
routes: [
{
path: '/',
name: 'HelloWorld',
component: HelloWorld
}
]
});函數
router常見的參數有以下:
3-1 mode 可選的參數有 hash 和 history:
hash: 默認爲hash, 若是使用hash的話,頁面的地址就會加上 # 號就會比較很差看,如咱們的地址變成以下:http://localhost:8080/#/
history: 咱們使用history的話,那麼訪問頁面的時候就和日常同樣,不帶井號的;以下地址也能夠訪問 http://localhost:8080/
router/index.js 配置代碼變成以下:
import Vue from 'vue';
import Router from 'vue-router';
import HelloWorld from '@/views/HelloWorld';
Vue.use(Router);
export default new Router({
mode: 'history', // 訪問路徑不帶井號
routes: [
{
path: '/',
name: 'HelloWorld',
component: HelloWorld
}
]
});
3-2 base
應用的基路徑,好比整個單頁應用服務在 /page/app/ 下,那麼base就應該設置爲 /page/app/. 通常寫成 __direname(在webpack中有配置),固然你也能夠寫成 /page/app/
router.js代碼以下配置:
import Vue from 'vue';
import Router from 'vue-router';
import HelloWorld from '@/views/HelloWorld';
Vue.use(Router);
export default new Router({
mode: 'history', // 訪問路徑不帶井號
base: '/page/app', // 配置單頁應用的基路徑
routes: [
{
path: '/',
name: 'HelloWorld',
component: HelloWorld
},
{
path: '/helloworld',
name: 'HelloWorld',
component: HelloWorld
}
]
});
所以頁面這樣訪問 http://localhost:8080/page/app/ 和 http://localhost:8080/ 訪問的效果是同樣的。
3-3 routers
基本的代碼以下:
routes: [
{
path: '/',
name: 'HelloWorld',
component: HelloWorld
},
{
path: '/helloworld',
name: 'HelloWorld',
component: HelloWorld
}
]
path: 就是咱們訪問這個頁面的路徑。
name: 給這個頁面路徑定義一個名字,當在頁面進行跳轉的時候也可使用名字跳轉。惟一性
component組件,就是使用import 引入的組件了。
引入組件還有一種懶加載的方式。懶加載引入的優勢是:當你訪問這個頁面的時候纔會去加載相關的資源,這樣的話能提升頁面的訪問速度。
好比以下這樣:component: resolve => require(['@/views/HelloWorld'], resolve) // 使用懶加載
所以router/index.js 能夠寫成以下:
import Vue from 'vue';
import Router from 'vue-router';
// import HelloWorld from '@/views/HelloWorld';
Vue.use(Router);
export default new Router({
mode: 'history', // 訪問路徑不帶井號
base: '/page/app', // 配置單頁應用的基路徑
routes: [
{
path: '/',
name: 'HelloWorld',
component: resolve => require(['@/views/HelloWorld'], resolve) // 使用懶加載
},
{
path: '/helloworld',
name: 'HelloWorld',
component: resolve => require(['@/views/HelloWorld'], resolve) // 使用懶加載
}
]
});
3-4 router傳參數
首先咱們在router/index.js 代碼作以下配置:
{
path: '/helloworld/:name', // 對路徑作攔截,這種類型的連接後面的內容會被vue-router映射成name參數了
name: 'HelloWorld',
component: resolve => require(['@/views/HelloWorld'], resolve) // 使用懶加載
}
當咱們在頁面上訪問 http://localhost:8080/page/app/helloworld/xx=1 的時候,而後咱們在 heeloworld這個組件內的created
的生命週期內,使用 console.log(this.$route.params.name); // xx=1 能夠獲取到/helloworld/ 後面的全部的參數了。
3-4-2 Get請求傳參數
好比在頁面訪問的時候,可使用問號(?)對參數進行傳遞;好比以下網址:
http://localhost:8080/page/app/helloworld?age=1
首先在router/index.js 代碼先還原成以下:
{
path: '/helloworld',
name: 'HelloWorld',
component: resolve => require(['@/views/HelloWorld'], resolve) // 使用懶加載
}
而後咱們在helloworld組件內 使用以下獲取:
let age = this.$route.query.age; //問號後面參數會被封裝進
this.$route.query; console.log(age); // 打印出1
3-5 編程式導航
如今看看頁面是如何跳轉的了,主要是利用 <router-link>來建立可跳轉連接,咱們還能夠利用 this.$router.push('xxx')進行跳轉。
首先咱們如今 router/index.js 添加 demo這個組件,而後從heeloworld這個頁面跳轉到demo這個組件頁面;以下router的配置:
routes: [
{
path: '/',
name: 'HelloWorld',
component: resolve => require(['@/views/HelloWorld'], resolve) // 使用懶加載
},
{
path: '/helloworld',
name: 'HelloWorld',
component: resolve => require(['@/views/HelloWorld'], resolve) // 使用懶加載
},
{
path: '/demo',
name: 'demo',
component: resolve => require(['@/views/demo'], resolve) // 使用懶加載
}
]
而後咱們在helloworld組件添加以下代碼:
<router-link to="/demo">點擊我跳轉</router-link>
所以點擊就能夠跳轉了;
咱們也可使用 router-link 像get方式那要傳遞一些參數過,好比以下router-link代碼:
<router-link :to="{path: '/demo', query:{'id': 22, 'name': 'kongzhi'}}"> 點擊我跳轉 </router-link>
而後咱們在demo組件內經過以下方式能夠獲取值:
console.log(this.$route.query.id); // 22
console.log(this.$route.query.name); // kongzhi
咱們也可使用 this.$router.push('xxx')進行跳轉; 以下代碼:
<div @click="func()">點擊進行跳轉</div>
JS代碼以下
methods: { func () { this.$router.push('/demo'); } }
能夠有以下方式:
// 字符串,這裏的字符串是路徑path匹配噢,不是router配置裏的name
this.$router.push('/demo')
// 對象
this.$router.push({path: '/demo'});
/*
* 命名的路由 跳轉到demo組件,所以地址欄變成 http://localhost:8080/page/app/demo
* 在demo組件內 經過 console.log(this.$route); 打印以下信息
{
fullPath: '/demo',
hash: '',
matched: [....],
name: 'demo',
params: {userId: 123},
path: '/demo',
query: {}
}
所以 咱們能夠經過 this.$route.params.userId 就能夠獲取到傳遞的參數 userId了。
*/
this.$router.push({name: 'demo', params: { userId: 123 }})
/*
帶查詢參數,跳到到demo組件內,所以地址欄會變成以下:http://localhost:8080/page/app/demo?userId=1234
而後咱們和上面同樣 能夠經過 this.$route.query.userId 就能夠獲取到傳遞的參數 userId了。
*/
this.$router.push({path: 'demo', query: { userId: '1234' }});
3-6 導航鉤子
導航鉤子函數,主要是在導航跳轉的時候作一些操做,好比跳轉頁面以前,進行判斷,好比跳轉的時候,判斷是否某個字段是否爲true,若是爲true,
則跳轉到A組件內,不然的話跳到B組件內。而鉤子函數根據其生效範圍能夠分爲 全局鉤子函數, 路由獨享鉤子函數 和 組件內鉤子函數。
3-6-1 全局鉤子函數
好比咱們能夠直接在 router/index.js 代碼編寫代碼邏輯,對一些全局性的東西進行攔截。
router.beforeEach((to, from, next)=>{
//do something
next();
});
router.afterEach((to, from, next) => {
console.log(to.path);
});
上面的鉤子方法接收三個採納數:
to: 即將要進入的目標路由對象。
from: 當前導航正要離開的路由。
next: 必定要調用該方法來 resolve這個鉤子。
next() 進行管道中的下一個鉤子。若是所有鉤子執行完了,則導航的狀態就是 confirmed(肯定的)。
next(false). 中斷當前的導航。
next('/')或next({path: '/'}), 跳轉到一個不一樣的地址。當前的導航被中斷,而後進行一個新的導航。
注意: 確保要調用 next 方法,不然鉤子就不會被 resolved。
咱們再來訪問 頁面地址 http://localhost:8080/page/app/helloworld,而後在router/index 配置以下:
import Vue from 'vue';
import Router from 'vue-router';
// import HelloWorld from '@/views/HelloWorld';
Vue.use(Router);
const router = new Router({
mode: 'history', // 訪問路徑不帶井號
base: '/page/app', // 配置單頁應用的基路徑
routes: [
{
path: '/',
name: 'HelloWorld',
component: resolve => require(['@/views/HelloWorld'], resolve) // 使用懶加載
},
{
path: '/helloworld',
name: 'HelloWorld',
component: resolve => require(['@/views/HelloWorld'], resolve) // 使用懶加載
},
{
path: '/demo',
name: 'demo',
component: resolve => require(['@/views/demo'], resolve) // 使用懶加載
}
]
});
router.beforeEach((to, from, next) => {
// do something
console.log(to.path); // 打印 /helloworld
console.log(from.path); // 打印 /
next();
});
router.afterEach((to, from, next) => {
console.log(to.path); // 打印 /helloworld
console.log(from.path); // 打印 /
});
export default router;
刷新下頁面就能夠看到調用 beforeEach 和 afterEach 的輸出了。
3-6-2 路由獨享鉤子函數
咱們能夠對單個的路由的跳轉進行攔截,對單個的路由使用 beforeEnter 函數,咱們在router/index的文件裏面能夠以下編寫代碼:
import Vue from 'vue';
import Router from 'vue-router';
// import HelloWorld from '@/views/HelloWorld';
Vue.use(Router);
const router = new Router({
mode: 'history', // 訪問路徑不帶井號
base: '/page/app', // 配置單頁應用的基路徑
routes: [
{
path: '/',
name: 'HelloWorld',
component: resolve => require(['@/views/HelloWorld'], resolve) // 使用懶加載
},
{
path: '/helloworld',
name: 'HelloWorld',
component: resolve => require(['@/views/HelloWorld'], resolve), // 使用懶加載
beforeEnter(to, from, next) {
console.log(111)
console.log(to.path); // 打印 /helloworld
console.log(from.path); // 打印 /
next(); // 跳到/helloworld 組件頁面
}
},
{
path: '/demo',
name: 'demo',
component: resolve => require(['@/views/demo'], resolve) // 使用懶加載
}
]
});
export default router;
3-6-3 組件內鉤子函數
更細粒度的路由攔截,只針對一個進入某一個組件的攔截。
咱們把 router/index的代碼還原成以下:
import Vue from 'vue';
import Router from 'vue-router';
// import HelloWorld from '@/views/HelloWorld';
Vue.use(Router);
const router = new Router({
mode: 'history', // 訪問路徑不帶井號
base: '/page/app', // 配置單頁應用的基路徑
routes: [
{
path: '/',
name: 'HelloWorld',
component: resolve => require(['@/views/HelloWorld'], resolve) // 使用懶加載
},
{
path: '/helloworld',
name: 'HelloWorld',
component: resolve => require(['@/views/HelloWorld'], resolve) // 使用懶加載
},
{
path: '/demo',
name: 'demo',
component: resolve => require(['@/views/demo'], resolve) // 使用懶加載
}
]
});
export default router;
而後對 helloworld 組件內的代碼 使用 beforeRouterEnter()方法進行攔截;以下HelloWorld.vue代碼
export default {
name: 'HelloWorld2',
data () {
return {
msg: 'Welcome to Your Vue.js App'
};
},
created () {
this.getInfo();
},
beforeRouteEnter(to, from, next) {
// 在渲染該組件的對應路由被 confirm 前調用
// 不!能!獲取組件實例 `this`
// 由於當鉤子執行前,組件實例還沒被建立
console.log(to.path); // 打印 /helloworld
console.log(from.path); // 打印 /
next(); // 跳轉到 /helloworld 指定的頁面
},
beforeRouteUpdate (to, from, next) {
// 在當前路由改變,可是該組件被複用時調用
// 舉例來講,對於一個帶有動態參數的路徑 /foo/:id,在 /foo/1 和 /foo/2 之間跳轉的時候,
// 因爲會渲染一樣的 Foo 組件,所以組件實例會被複用。而這個鉤子就會在這個狀況下被調用。
// 能夠訪問組件實例 `this`
},
beforeRouteLeave (to, from, next) {
// 導航離開該組件的對應路由時調用
// 能夠訪問組件實例 `this`
}
};
鉤子函數使用場景:
其實路由鉤子函數在項目開發中用的並非很是多,通常用於登陸態的校驗,沒有登陸跳轉到登陸頁;權限的校驗等等。
4. 滾動行爲
在利用 vue-router 去作跳轉的時候,到了新頁面若是對頁面的滾動位置有要求的話,可使用以下方法:
const router = new VueRouter({
routes: [...],
scrollBehavior (to, from, savedPosition) {
// return 指望滾動到哪一個的位置
}
});
scrollBehavior 方法接收 to 和 from 路由對象。
第三個參數 savedPosition 當且僅當 popstate 導航 (mode爲 history 經過瀏覽器的 前進/後退 按鈕觸發) 時纔可用。
//全部路由新頁面滾動到頂部:
scrollBehavior (to, from, savedPosition) {
return { x: 0, y: 0 }
}
//若是有錨點
scrollBehavior (to, from, savedPosition) {
if (to.hash) {
return {
selector: to.hash
}
}
}
好比在頁面是使用 <router-link> 作跳轉的時候,那麼到另外一個頁面須要滾動到100px的時候,咱們能夠對全局使用,也能夠對某個路由時候,或者對某個
組件使用,下面咱們是在 router/index.js 代碼內對代碼全局使用以下:
import Vue from 'vue';
import Router from 'vue-router';
// import HelloWorld from '@/views/HelloWorld';
Vue.use(Router);
const router = new Router({
mode: 'history', // 訪問路徑不帶井號
base: '/page/app', // 配置單頁應用的基路徑
routes: [
{
path: '/',
name: 'HelloWorld',
component: resolve => require(['@/views/HelloWorld'], resolve) // 使用懶加載
},
{
path: '/helloworld',
name: 'HelloWorld',
component: resolve => require(['@/views/HelloWorld'], resolve) // 使用懶加載
},
{
path: '/demo',
name: 'demo',
component: resolve => require(['@/views/demo'], resolve) // 使用懶加載
}
],
scrollBehavior (to, from, savedPosition) {
return { x: 100, y: 100 }
}
});
export default router;
當咱們從 heeloworld.vue 組件內 點擊跳轉到 demo.vue的時候,在demo.vue會滾動100px;