vue2.0---vue-router總結(項目基於vue-cli)


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;

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM