vue2.0---vue-router總結(專案基於vue-cli)
1. 在專案中安裝:
npm install vue-router --save
2. 在專案中的引入:
// 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'; import App from './App'; import router from './router'; import store from './store'; // Resource Vue.use(VueResource); // vuex Vue.use(Vuex); Vue.config.productionTip = false; /* eslint-disable no-new */ new Vue({ el: '#app', router, store, template: '<App/>', components: { App } });
3. router.js的配置
我們先來看一下 router/index.js 程式碼如下:
import Vue from 'vue'; import Router from 'vue-router'; import HelloWorld from '@/views/HelloWorld'; Vue.use(Router); 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;