vue $route及$router的区分

参考网站

https://www.cnblogs.com/czy960731/p/9288830.html

https://blog.csdn.net/qxb5215/article/details/80346820

https://www.jianshu.com/p/4ad2a6f7b6ff

vue-router学习

1.使用

 
  1. npm install vue-router

  2.  
  3. import Vue from 'vue'

  4. import VueRouter from 'vue-router'

  5. Vue.use(VueRouter)

2.入口

 
  1. <div id="app">

  2. <h1>Hello App!</h1>

  3. <p>

  4. <!-- 使用 router-link 组件来导航. -->

  5. <!-- 通过传入 `to` 属性指定链接. -->

  6. <!-- <router-link> 默认会被渲染成一个 `<a>` 标签 -->

  7. <router-link to="/foo">Go to Foo</router-link>

  8. <router-link to="/bar">Go to Bar</router-link>

  9. </p>

  10. <!-- 路由出口 -->

  11. <!-- 路由匹配到的组件将渲染在这里 -->

  12. <router-view></router-view>

  13. </div>

3.JavaScript

 
  1. // 0. 如果使用模块化机制编程, 要调用 Vue.use(VueRouter)

  2.  
  3. // 1. 定义(路由)组件。

  4. // 可以从其他文件 import 进来

  5. const Foo = { template: '<div>foo</div>' }

  6. const Bar = { template: '<div>bar</div>' }

  7.  
  8. // 2. 定义路由

  9. // 每个路由应该映射一个组件。 其中"component" 可以是

  10. // 通过 Vue.extend() 创建的组件构造器,

  11. // 或者,只是一个组件配置对象。

  12. // 我们晚点在讨论嵌套路由。

  13. const routes = [

  14. { path: '/foo', component: Foo },

  15. { path: '/bar', component: Bar }

  16. ]

  17.  
  18. // 3. 创建 router 实例,然后传 `routes` 配置

  19. // 你还可以传别的配置参数, 不过先这么简单着吧。

  20. const router = new VueRouter({

  21. routes // (缩写)相当于 routes: routes

  22. })

  23.  
  24. // 4. 创建和挂载根实例。

  25. // 记得要通过 router 配置参数注入路由,

  26. // 从而让整个应用都有路由功能

  27. const app = new Vue({

  28. router

  29. }).$mount('#app')

  30.  
  31. // 现在,应用已经启动了!

动态路由监听
$route.params.

 
  1. const User = {

  2. template: '...',

  3. watch: {

  4. '$route' (to, from) {

  5. // 对路由变化作出响应...

  6. }

  7. }

  8. }

4.嵌套路由

通过children属性设置子路由

 
  1. <div id="app">

  2. <p>

  3. <router-link to="/user/foo">/user/foo</router-link>

  4. <router-link to="/user/foo/profile">/user/foo/profile</router-link>

  5. <router-link to="/user/foo/posts">/user/foo/posts</router-link>

  6. </p>

  7. <router-view></router-view>

  8. </div>

  9.  
  10.  
  11. const User = {

  12. template: `

  13. <div class="user">

  14. <h2>User {{ $route.params.id }}</h2> // 通过$router.param获取id

  15. <router-view></router-view>

  16. </div>

  17. `

  18. }

  19.  
  20. const UserHome = { template: '<div>Home</div>' }

  21. const UserProfile = { template: '<div>Profile</div>' }

  22. const UserPosts = { template: '<div>Posts</div>' }

  23.  
  24. const router = new VueRouter({

  25. routes: [

  26. { path: '/user/:id', component: User, // 动态传参

  27. children: [

  28. // 这里设置子路由

  29. // UserHome will be rendered inside User's <router-view>

  30. // when /user/:id is matched

  31. { path: '', component: UserHome },

  32.  
  33. // UserProfile will be rendered inside User's <router-view>

  34. // when /user/:id/profile is matched

  35. { path: 'profile', component: UserProfile },

  36.  
  37. // UserPosts will be rendered inside User's <router-view>

  38. // when /user/:id/posts is matched

  39. { path: 'posts', component: UserPosts }

  40. ]

  41. }

  42. ]

  43. })

5.编程式的导航

Paste_Image.png

 
  1. // 字符串

  2. router.push('home')

  3. // 对象

  4. router.push({ path: 'home' })

  5. // 命名的路由

  6. router.push({ name: 'user', params: { userId: 123 }})

  7. // 带查询参数,变成 /register?plan=private

  8. router.push({ path: 'register', query: { plan: 'private' }})

router.replace(location)

跟 router.push
很像,唯一的不同就是,它不会向 history 添加新记录,而是跟它的方法名一样 —— 替换掉当前的 history 记录。

 

router.go(n)

 
  1. // 在浏览器记录中前进一步,等同于 history.forward()

  2. router.go(1)

  3.  
  4. // 后退一步记录,等同于 history.back()

  5. router.go(-1)

  6.  
  7. // 前进 3 步记录

  8. router.go(3)

  9.  
  10. // 如果 history 记录不够用,那就默默地失败呗

  11. router.go(-100)

  12. router.go(100)

6.命名路由

 
  1. import Vue from 'vue'

  2. import VueRouter from 'vue-router'

  3.  
  4. Vue.use(VueRouter)

  5.  
  6. const Home = { template: '<div>This is Home</div>' }

  7. const Foo = { template: '<div>This is Foo</div>' }

  8. const Bar = { template: '<div>This is Bar {{ $route.params.id }}</div>' }

  9.  
  10. const router = new VueRouter({

  11. mode: 'history',

  12. base: __dirname,

  13. routes: [

  14. { path: '/', name: 'home', component: Home },

  15. { path: '/foo', name: 'foo', component: Foo },

  16. { path: '/bar/:id', name: 'bar', component: Bar }

  17. ]

  18. })

  19.  
  20. new Vue({

  21. router,

  22. template: `

  23. <div id="app">

  24. <h1>Named Routes</h1>

  25. <p>Current route name: {{ $route.name }}</p>

  26. <ul>

  27. <li><router-link :to="{ name: 'home' }">home</router-link></li>

  28. <li><router-link :to="{ name: 'foo' }">foo</router-link></li>

  29. <li><router-link :to="{ name: 'bar', params: { id: 123 }}">bar</router-link></li>

  30. </ul>

  31. <router-view class="view"></router-view>

  32. </div>

  33. `

  34. }).$mount('#app')

7.命名视图

有时候想同时 (同级) 展示多个视图,而不是嵌套展示,如果 router-view 没有设置名字,那么默认为 default

如下情况

(同级)展示多个视图,而不是嵌套展示,例如创建一个布局,有 sidebar
(侧导航) 和main
(主内容) 两个视图,这个时候命名视图就派上用场了

 
  1. <script src="https://unpkg.com/vue/dist/vue.js"></script>

  2. <script src="https://unpkg.com/vue-router/dist/vue-router.js"></script>

  3.  
  4. <div id="app">

  5. <div id="app">

  6. <h1>Named Views</h1>

  7. <ul>

  8. <li><router-link to="/">/</router-link></li>

  9. <li><router-link to="/other">/other</router-link></li>

  10. </ul>

  11. <router-view class="view one"></router-view>

  12. <router-view class="view two" name="a"></router-view> // 展示router里的components的a属性

  13. <router-view class="view three" name="b"></router-view>

  14. </div>

  15. </div>

 
  1. const Foo = { template: '<div>foo</div>' }

  2. const Bar = { template: '<div>bar</div>' }

  3. const Baz = { template: '<div>baz</div>' }

  4.  
  5. const router = new VueRouter({

  6. mode: 'history',

  7. routes: [

  8. { path: '/',

  9. // a single route can define multiple named components

  10. // which will be rendered into <router-view>s with corresponding names.

  11. components: {

  12. default: Foo,

  13. a: Bar,

  14. b: Baz

  15. }

  16. },

  17. {

  18. path: '/other',

  19. components: {

  20. default: Baz,

  21. a: Bar,

  22. b: Foo

  23. }

  24. }

  25. ]

  26. })

  27.  
  28. new Vue({

  29. router,

  30. el: '#app'

  31. })

Paste_Image.png

8.重定向 和 别名

 
  1. 重定向也是通过 routes 配置来完成,下面例子是从 /a 重定向到 /b:

  2.  
  3. const router = new VueRouter({

  4. routes: [

  5. { path: '/a', redirect: '/b' }

  6. ]

  7. })

  8. 重定向的目标也可以是一个命名的路由:

  9.  
  10. const router = new VueRouter({

  11. routes: [

  12. { path: '/a', redirect: { name: 'foo' }}

  13. ]

  14. })

  15. 甚至是一个方法,动态返回重定向目标:

  16.  
  17. const router = new VueRouter({

  18. routes: [

  19. { path: '/a', redirect: to => {

  20. // 方法接收 目标路由 作为参数

  21. // return 重定向的 字符串路径/路径对象

  22. }}

  23. ]

  24. })

 
  1. import Vue from 'vue'

  2. import VueRouter from 'vue-router'

  3.  
  4. Vue.use(VueRouter)

  5.  
  6. const Home = { template: '<div><h1>Home</h1><router-view></router-view></div>' }

  7. const Foo = { template: '<div>foo</div>' }

  8. const Bar = { template: '<div>bar</div>' }

  9. const Baz = { template: '<div>baz</div>' }

  10.  
  11. const router = new VueRouter({

  12. mode: 'history',

  13. base: __dirname,

  14. routes: [

  15. { path: '/home', component: Home,

  16. children: [

  17. // absolute alias

  18. { path: 'foo', component: Foo, alias: '/foo' },

  19. // relative alias (alias to /home/bar-alias)

  20. { path: 'bar', component: Bar, alias: 'bar-alias' },

  21. // multiple aliases

  22. { path: 'baz', component: Baz, alias: ['/baz', 'baz-alias'] }

  23. ]

  24. }

  25. ]

  26. })

  27.  
  28. new Vue({

  29. router,

  30. template: `

  31. <div id="app">

  32. <h1>Route Alias</h1>

  33. <ul>

  34. <li><router-link to="/foo">

  35. /foo (renders /home/foo)

  36. </router-link></li>

  37. <li><router-link to="/home/bar-alias">

  38. /home/bar-alias (renders /home/bar)

  39. </router-link></li>

  40. <li><router-link to="/baz">

  41. /baz (renders /home/baz)</router-link>

  42. </li>

  43. <li><router-link to="/home/baz-alias">

  44. /home/baz-alias (renders /home/baz)

  45. </router-link></li>

  46. </ul>

  47. <router-view class="view"></router-view>

  48. </div>

  49. `

  50. }).$mount('#app')


1.导航钩子

vue-router
提供的导航钩子主要用来拦截导航,让它完成跳转或取消。有多种方式可以在路由导航发生时执行钩子:全局的, 单个路由独享的, 或者组件级的。
(1)全局钩子

 
  1. const router = new VueRouter({ ... })

  2.  
  3. router.beforeEach((to, from, next) => {

  4. // ...

  5. })

每个钩子方法接收三个参数:
**to: Route
**: 即将要进入的目标 路由对象

**from: Route
**: 当前导航正要离开的路由

**next: Function
**: 一定要调用该方法来 resolve 这个钩子。执行效果依赖 next
方法的调用参数。

 
  1. **next()

  2. **: 进行管道中的下一个钩子。如果全部钩子执行完了,则导航的状态就是 **confirmed**

  3. (确认的)。

  4.  
  5. **next(false)

  6. **: 中断当前的导航。如果浏览器的 URL 改变了(可能是用户手动或者浏览器后退按钮),

  7. 那么 URL 地址会重置到 from 路由对应的地址。

  8.  
  9. **next('/')

  10. 或者 next({ path: '/' })

  11. **: 跳转到一个不同的地址。当前的导航被中断,然后进行一个新的导航。

(2)某个路由独享的钩子
你可以在路由配置上直接定义 beforeEnter 钩子:

 
  1. const router = new VueRouter({

  2. routes: [

  3. {

  4. path: '/foo',

  5. component: Foo,

  6. beforeEnter: (to, from, next) => {

  7. // ...

  8. }

  9. }

  10. ]

  11. })

(3)组件内的钩子
最后,你可以使用 beforeRouteEnter 和 beforeRouteLeave,在路由组件内直接定义路由导航钩子,

 
  1. const Foo = {

  2. template: `...`,

  3. beforeRouteEnter (to, from, next) => {

  4. // 在渲染该组件的对应路由被 confirm 前调用

  5. // 不!能!获取组件实例 `this`

  6. // 因为当钩子执行前,组件实例还没被创建

  7. },

  8. beforeRouteLeave (to, from, next) => {

  9. // 导航离开该组件的对应路由时调用

  10. // 可以访问组件实例 `this`

  11. }

  12. }

beforeRouteEnter 钩子 不能 访问 this,因为钩子在导航确认前被调用,因此即将登场的新组件还没被创建。
不过,你可以通过传一个回调给 next来访问组件实例。在导航被确认的时候执行回调,并且把组件实例作为回调方法的参数。

 
  1. beforeRouteEnter (to, from, next) => {

  2. next(vm => {

  3. // 通过 `vm` 访问组件实例

  4. })

  5. }

可以 在 beforeRouteLeave 中直接访问 this。这个 leave 钩子通常用来禁止用户在还未保存修改前突然离开。可以通过 next(false) 来取消导航。

2.路由元信息

定义路由的时候可以配置 meta 字段:

 
  1. const router = new VueRouter({

  2. routes: [

  3. {

  4. path: '/foo',

  5. component: Foo,

  6. children: [

  7. {

  8. path: 'bar',

  9. component: Bar,

  10. // a meta field

  11. meta: { requiresAuth: true }

  12. }

  13. ]

  14. }

  15. ]

  16. })

下面例子展示在全局导航钩子中检查 meta 字段:

 
  1. router.beforeEach((to, from, next) => {

  2. if (to.matched.some(record => record.meta.requiresAuth)) {

  3. // this route requires auth, check if logged in

  4. // if not, redirect to login page.

  5. if (!auth.loggedIn()) {

  6. next({

  7. path: '/login',

  8. query: { redirect: to.fullPath }

  9. })

  10. } else {

  11. next()

  12. }

  13. } else {

  14. next() // 确保一定要调用 next()

  15. }

  16. })

3.滚动特效

<router-view> 是基本的动态组件,所以我们可以用 <transition>
组件给它添加一些过渡效果:

 
  1. <transition>

  2. <router-view></router-view>

  3. </transition>

单个路由的过渡

 
  1. const Foo = {

  2. template: `

  3. <transition name="slide">

  4. <div class="foo">...</div>

  5. </transition>

  6. `

  7. }

  8.  
  9. const Bar = {

  10. template: `

  11. <transition name="fade">

  12. <div class="bar">...</div>

  13. </transition>

  14. `

  15. }

动态路由

 
  1. import Vue from 'vue'

  2. import VueRouter from 'vue-router'

  3.  
  4. Vue.use(VueRouter)

  5.  
  6. const Home = {

  7. template: `

  8. <div class="home">

  9. <h2>Home</h2>

  10. <p>hello</p>

  11. </div>

  12. `

  13. }

  14.  
  15. const Parent = {

  16. data () {

  17. return {

  18. transitionName: 'slide-left'

  19. }

  20. },

  21. // dynamically set transition based on route change

  22. watch: {

  23. '$route' (to, from) {

  24. const toDepth = to.path.split('/').length

  25. const fromDepth = from.path.split('/').length

  26. this.transitionName = toDepth < fromDepth ? 'slide-right' : 'slide-left'

  27. }

  28. },

  29. template: `

  30. <div class="parent">

  31. <h2>Parent</h2>

  32. <transition :name="transitionName">

  33. <router-view class="child-view"></router-view>

  34. </transition>

  35. </div>

  36. `

  37. }

  38.  
  39. const Default = { template: '<div class="default">default</div>' }

  40. const Foo = { template: '<div class="foo">foo</div>' }

  41. const Bar = { template: '<div class="bar">bar</div>' }

  42.  
  43. const router = new VueRouter({

  44. mode: 'history',

  45. base: __dirname,

  46. routes: [

  47. { path: '/', component: Home },

  48. { path: '/parent', component: Parent,

  49. children: [

  50. { path: '', component: Default },

  51. { path: 'foo', component: Foo },

  52. { path: 'bar', component: Bar }

  53. ]

  54. }

  55. ]

  56. })

  57.  
  58. new Vue({

  59. router,

  60. template: `

  61. <div id="app">

  62. <h1>Transitions</h1>

  63. <ul>

  64. <li><router-link to="/">/</router-link></li>

  65. <li><router-link to="/parent">/parent</router-link></li>

  66. <li><router-link to="/parent/foo">/parent/foo</router-link></li>

  67. <li><router-link to="/parent/bar">/parent/bar</router-link></li>

  68. </ul>

  69. <transition name="fade" mode="out-in">

  70. <router-view class="view"></router-view>

  71. </transition>

  72. </div>

  73. `

  74. }).$mount('#app')

  75.  

4.导航完成后获取数据

假设我们有一个 Post 组件,需要基于 $route.params.id 获取文章数据:
导航完成之后获取:先完成导航,然后在接下来的组件生命周期钩子中获取数据。在数据获取期间显示『加载中』之类的指示。

导航完成之前获取:导航完成前,在路由的 enter
钩子中获取数据,在数据获取成功后执行导航。

 
  1. <template>

  2. <div class="post">

  3. <div class="loading" v-if="loading">

  4. Loading...

  5. </div>

  6.  
  7. <div v-if="error" class="error">

  8. {{ error }}

  9. </div>

  10.  
  11. <div v-if="post" class="content">

  12. <h2>{{ post.title }}</h2>

  13. <p>{{ post.body }}</p>

  14. </div>

  15. </div>

  16. </template>

 
  1. export default {

  2. data () {

  3. return {

  4. loading: false,

  5. post: null,

  6. error: null

  7. }

  8. },

  9. created () {

  10. // 组件创建完后获取数据,

  11. // 此时 data 已经被 observed 了

  12. this.fetchData()

  13. },

  14. watch: {

  15. // 如果路由有变化,会再次执行该方法

  16. '$route': 'fetchData'

  17. },

  18. methods: {

  19. fetchData () {

  20. this.error = this.post = null

  21. this.loading = true

  22. // replace getPost with your data fetching util / API wrapper

  23. getPost(this.$route.params.id, (err, post) => {

  24. this.loading = false

  25. if (err) {

  26. this.error = err.toString()

  27. } else {

  28. this.post = post

  29. }

  30. })

  31. }

  32. }

  33. }

在导航完成前获取数据

 
  1. export default {

  2. data () {

  3. return {

  4. post: null,

  5. error: null

  6. }

  7. },

  8. beforeRouteEnter (to, from, next) {

  9. getPost(to.params.id, (err, post) =>

  10. if (err) {

  11. // display some global error message

  12. next(false)

  13. } else {

  14. next(vm => {

  15. vm.post = post

  16. })

  17. }

  18. })

  19. },

  20. // 路由改变前,组件就已经渲染完了

  21. // 逻辑稍稍不同

  22. watch: {

  23. $route () {

  24. this.post = null

  25. getPost(this.$route.params.id, (err, post) => {

  26. if (err) {

  27. this.error = err.toString()

  28. } else {

  29. this.post = post

  30. }

  31. })

  32. }

  33. }

  34. }

5.滚动行为

只有在mode:history模式下有用

 
  1. import Vue from 'vue'

  2. import VueRouter from 'vue-router'

  3.  
  4. Vue.use(VueRouter)

  5.  
  6. const Home = { template: '<div>home</div>' }

  7. const Foo = { template: '<div>foo</div>' }

  8. const Bar = {

  9. template: `

  10. <div>

  11. bar

  12. <div style="height:500px"></div>

  13. <p id="anchor">Anchor</p>

  14. </div>

  15. `

  16. }

  17.  
  18. // scrollBehavior:

  19. // - only available in html5 history mode

  20. // - defaults to no scroll behavior

  21. // - return false to prevent scroll

  22. const scrollBehavior = (to, from, savedPosition) => {

  23. if (savedPosition) {

  24. // savedPosition is only available for popstate navigations.

  25. return savedPosition

  26. } else {

  27. const position = {}

  28. // new navigation.

  29. // scroll to anchor by returning the selector

  30. if (to.hash) {

  31. position.selector = to.hash

  32. }

  33. // check if any matched route config has meta that requires scrolling to top

  34. if (to.matched.some(m => m.meta.scrollToTop)) {

  35. // cords will be used if no selector is provided,

  36. // or if the selector didn't match any element.

  37. position.x = 0

  38. position.y = 0

  39. }

  40. // if the returned position is falsy or an empty object,

  41. // will retain current scroll position.

  42. return position

  43. }

  44. }

  45.  
  46. const router = new VueRouter({

  47. mode: 'history',

  48. base: __dirname,

  49. scrollBehavior,

  50. routes: [

  51. { path: '/', component: Home, meta: { scrollToTop: true }},

  52. { path: '/foo', component: Foo },

  53. { path: '/bar', component: Bar, meta: { scrollToTop: true }}

  54. ]

  55. })

  56.  
  57. new Vue({

  58. router,

  59. template: `

  60. <div id="app">

  61. <h1>Scroll Behavior</h1>

  62. <ul>

  63. <li><router-link to="/">/</router-link></li>

  64. <li><router-link to="/foo">/foo</router-link></li>

  65. <li><router-link to="/bar">/bar</router-link></li>

  66. <li><router-link to="/bar#anchor">/bar#anchor</router-link></li>

  67. </ul>

  68. <router-view class="view"></router-view>

  69. </div>

  70. `

  71. }).$mount('#app')

6.路由懒加载

结合 Vue 的 异步组件 和 Webpack 的 code splitting feature, 轻松实现路由组件的懒加载。

 
  1. 我们要做的就是把路由对应的组件定义成异步组件:

  2.  
  3. const Foo = resolve => {

  4. // require.ensure 是 Webpack 的特殊语法,用来设置 code-split point

  5. // (代码分块)

  6. require.ensure(['./Foo.vue'], () => {

  7. resolve(require('./Foo.vue'))

  8. })

  9. }

  10. 这里还有另一种代码分块的语法,使用 AMD 风格的 require,于是就更简单了:

  11.  
  12. const Foo = resolve => require(['./Foo.vue'], resolve)

  13. 不需要改变任何路由配置,跟之前一样使用 Foo:

  14.  
  15. const router = new VueRouter({

  16. routes: [

  17. { path: '/foo', component: Foo }

  18. ]

  19. })

把组件按组分块

 
  1. const Foo = r => require.ensure([], () => r(require('./Foo.vue')), 'group-foo')

  2. const Bar = r => require.ensure([], () => r(require('./Bar.vue')), 'group-foo')

  3. const Baz = r => require.ensure([], () => r(require('./Baz.vue')), 'group-foo')

另一种方法

const HelloWorld = ()=>import("@/components/HelloWorld")



作者:lmem
链接:https://www.jianshu.com/p/4ad2a6f7b6ff
来源:简书
简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。

问题集锦

1.vue2.0中的$router 和 $route的区别

最近在学习vue的单页面应用开发,需要vue全家桶,其中用到了VueRouter,在路由的设置和跳转中遇到了两个对象$router 和 $route ,有些傻傻分不清,后来自己结合网上的博客和自己本地的Vue devtools结构了解了他们的区别

1.router是VueRouter的一个对象,通过Vue.use(VueRouter)和VueRouter构造函数得到一个router的实例对象,这个对象中是一个全局的对象,他包含了所有的路由包含了许多关键的对象和属性。

举例:history对象

$router.push({path:'home'});本质是向history栈中添加一个路由,在我们看来是 切换路由,但本质是在添加一个history记录

方法:

$router.replace({path:'home'});//替换路由,没有历史记录

2.route是一个跳转的路由对象(单个对象),每一个路由都会有一个route对象,是一个局部的对象,可以获取对应的name,path,params,query等

我们可以从vue devtools中看到每个路由对象的不同

这两个不同的结构可以看出两者的区别,他们的一些属性是不同的。

    • $route.path 
      字符串,等于当前路由对象的路径,会被解析为绝对路径,如 "/home/news" 。
    • $route.params 
      对象,包含路由中的动态片段和全匹配片段的键值对
    • $route.query 
      对象,包含路由中查询参数的键值对。例如,对于 /home/news/detail/01?favorite=yes ,会得到$route.query.favorite == 'yes' 。
    • $route.router 
      路由规则所属的路由器(以及其所属的组件)。
    • $route.matched 
      数组,包含当前匹配的路径中所包含的所有片段所对应的配置参数对象。
    • $route.name 
      当前路径的名字,如果没有使用具名路径,则名字为空。
    • (meta属性是行业墨守成规的,$route对象上有啥属性,$route就可以访问到啥)

$route.path, $route.params, $route.name, $route.query这几个属性很容易理解,看示例就能知道它们代表的含义 

2Vue:hash模式 和 history模式区别

hash模式:在浏览器中符号“#”,#以及#后面的字符称之为hash,用window.location.hash读取;
特点:hash虽然在URL中,但不被包括在HTTP请求中;用来指导浏览器动作,对服务端安全无用,hash不会重加载页面。
hash 模式下,仅 hash 符号之前的内容会被包含在请求中,如 http://www.xxx.com,因此对于后端来说,即使没有做到对路由的全覆盖,也不会返回 404 错误。

history模式:history采用HTML5的新特性;且提供了两个新方法:pushState(),replaceState()可以对浏览器历史记录栈进行修改,以及popState事件的监听到状态变更。
history 模式下,前端的 URL 必须和实际向后端发起请求的 URL 一致,如 http://www.xxx.com/items/id。后端如果缺少对 /items/id 的路由处理,将返回 404 错误。Vue-Router 官网里如此描述:“不过这种模式要玩好,还需要后台配置支持……所以呢,你要在服务端增加一个覆盖所有情况的候选资源:如果 URL 匹配不到任何静态资源,则应该返回同一个 index.html 页面,这个页面就是你 app 依赖的页面。”

3vue路由钩子

1.全局钩子

主要包括beforeEach和aftrEach,

beforeEach函数

有三个参数:
to:router即将进入的路由对象
from:当前导航即将离开的路由
next:Function,进行管道中的一个钩子,如果执行完了,则导航的状态就是 confirmed (确认的);否则为false,终止导航。

afterEach函数

不用传next()函数
这类钩子主要作用于全局,一般用来判断权限,以及以及页面丢失时候需要执行的操作,例如:

 
  1. //使用钩子函数对路由进行权限跳转

  2. router.beforeEach((to, from, next) => {

  3.     const role = localStorage.getItem('ms_username');

  4.     if(!role && to.path !== '/login'){

  5.         next('/login');

  6.     }else if(to.meta.permission){

  7.         // 如果是管理员权限则可进入,这里只是简单的模拟管理员权限而已

  8.         role === 'admin' ? next() : next('/403');

  9.     }else{

  10.         // 简单的判断IE10及以下不进入富文本编辑器,该组件不兼容

  11.         if(navigator.userAgent.indexOf('MSIE') > -1 && to.path === '/editor'){

  12.             Vue.prototype.$alert('vue-quill-editor组件不兼容IE10及以下浏览器,请使用更高版本的浏

  13.             览器查看', '浏览器不兼容通知', {

  14.                 confirmButtonText: '确定'

  15.             });

  16.         }else{

  17.             next();

  18.         }

  19.     }

  20. })

2.单个路由里面的钩子

主要用于写某个指定路由跳转时需要执行的逻辑              

 
  1.  {

  2.     path: '/dashboard',

  3.     component: resolve => require(['../components/page/Dashboard.vue'], resolve),

  4.     meta: { title: '系统首页' },

  5.     beforeEnter: (to, from, next) => {

  6.                         

  7.     },

  8.     beforeLeave: (to, from, next) => {

  9.                         

  10.    }

  11.                 

  12. },

  13.  


3.组件路由

    主要包括 beforeRouteEnter和beforeRouteUpdate ,beforeRouteLeave,这几个钩子都是写在组件里面也可以传三个参数(to,from,next),作用与前面类似.


  beforeRouteEnter(to, from, next) {
    next(vm => {
      if (
        vm.$route.meta.hasOwnProperty('auth_key') &&
        vm.$route.meta.auth_key != ''
      ) {
        if (!vm.hasPermission(vm.$route.meta.auth_key)) {
          vm.$router.replace('/admin/noPermission')
        }
      }
    })
  },

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值