Vue路由全解

路由基础

router-link

// 包装的 a 标签, router-link 组件
// to 属性

router-view

// router-view 组件 视图渲染

router.js

// router.js
// 配置路由列表
import Home from './views/Home.vue'
export default [
  {
    path: '/',  // url 路径
    component: Home  // 路径对应渲染组件
  },
  {
    path: '/about',
    component: () => import('views/About.vue')  // 懒加载,优化
  }
]

动态路由匹配

import Home from './views/Home.vue'
export default [
  {
    path: '/',  // url 路径
    component: Home  // 路径对应渲染组件
  },
  {
    path: '/about',
    component: () => import('views/About.vue')  // 懒加载,优化
  },
  // 动态路由匹配
  {
    path: '/argu/:name',
    component: () => import('views/argu.vue')
  }
]

// argu.vue


// url
http://localhost:8080/argu/yym    // $route.params.name == yym

嵌套路由

// parent.vue


// router.js
// 配置路由列表
import Home from './views/Home.vue'
export default [
  {
    path: '/',  // url 路径
    component: Home  // 路径对应渲染组件
  },
  {
    path: '/about',
    component: () => import('views/About.vue')  // 懒加载,优化
  },
  // 动态路由匹配
  {
    path: '/argu/:name',
    component: () => import('views/argu.vue')
  },
  {
    path: '/parent',
    component: () => import('views/parent.vue'),
    children: [
      {
        path: 'child',  // 不需要写斜杠, 在child 里自动补全
        component: () => import('views/child.vue') 
      }
    ]
  }
]

命名路由

// router.js
import Home from './views/Home.vue'
export default [
  {
    path: '/',  // url 路径
    name: 'home',  // 命名 设置 name 值
    component: Home  // 路径对应渲染组件
  },
  {
    path: '/about',
    name: 'about',   // 命名 设置 name 值
    component: () => import('views/About.vue')  // 懒加载,优化
  },
]

// App.vue

命名视图

// router.js
import Home from './views/Home.vue'
export default [
  {
    path: '/',  // url 路径
    name: 'Home',
    component: Home  // 路径对应渲染组件
  },
  {
    path: '/about',
    name: 'About',
    component: () => import('views/About.vue')  // 懒加载,优化
  },
  {
    path: '/named_view',
    components: {  // 加s 命名多个视图
      default: () => import('views/child.vue'),
      email: () => import('views/email.vue'),
      tel: () => import('views/tel.vue')
    }
  }
]

// App.vue

重定向

// router.js
import Home from './views/Home.vue'
export default [
  {
    path: '/',  // url 路径
    name: 'Home',
    component: Home  // 路径对应渲染组件
  },
  {
    path: '/about',
    name: 'About',
    component: () => import('views/About.vue')  // 懒加载,优化
  },
  {
    path: '/main',  // 进入 /main 路径
    redirect: '/'  // 重定向到 home
  },
  {
    path: '/main',
    redirect: {  // 对象形式
      name: 'Home'
    }
  },
  {
    path: '/main',
    redirect: to => {  // 函数形式
      return {  // return 一个路径
        name: 'Home'
      }
    }
  },
  {
    path: '/main',
    redirect: to => {  // 函数形式
      return '/'
    }
  }    
]

别名

// router.js
import Home from './views/Home.vue'
export default [
  {
    path: '/',  // url 路径
    alias: '/home_page', // 别名
    name: 'Home',
    component: Home  // 路径对应渲染组件
  },
]

编程式导航

// 通过 js 来控制路由跳转
// Home.vue



  


路由进阶

1. 路由传参

  • props: 布尔模式
// argu.vue


import Home from './views/Home.vue'
export default [
  // 动态路由匹配
  {
    path: '/argu/:name',
    name: 'argu'
    component: () => import('views/argu.vue'),
    props: true
    // props: true , 会使用 router.params 作为组件的属性,  name 插入到组件中,
  }
]
  • props 对象模式
// about.vue



import Home from './views/Home.vue'
export default [
  {
    path: '/about',
    name: 'about'
    component: () => import('views/about.vue'),
    props: {  // 对象模式传参
      food: 'banana'
    }
  }
]
  • props: 函数模式
// router.js
import Home from './views/Home.vue'
export default [
  {
    path: '/',  // url 路径
    name: 'Home',
    component: Home,  // 路径对应渲染组件
    props: route => ({
      food: route.query.food
    }) 
  },
]
// home.vue
// url:  /home?food=banana



2. history 模式

// src/router/index.js
import Vue from 'vue'
import Router from 'vue-router'
import routes from './router.js'
Vue.use(Router)
export default new Router({
  mode: 'hash',  // 默认 #/
  routes
})

// 有一个问题: 匹配不到页面静态资源, 匹配不到组件, 配置404
export default new Router({
  mode: 'history',  // 需要后端同学配合
  routes
})
// url:  /home/abc
// router.js
import Home from './views/Home.vue'
export default [
  {
    path: '/',  // url 路径
    name: 'Home',
    component: Home,  // 路径对应渲染组件
    props: route => ({
      food: route.query.food
    }) 
  },
  // 路由有优先级, 所以 404 放在最后不会影响其他路由的匹配
  {
    path: '*',
    component: () => import('views/error_404.vue')
  }
]

3. 导航守卫

  • 全局导航守卫
// src/router/index.js
import Vue from 'vue'
import Router from 'vue-router'
import routes from './router.js'
Vue.use(Router)

const router =  new Router({
  routes
})

// 假设登录判断
const HAS_LOGIN = true

// 全局路由前置守卫
router.beforeEach((to, from, next) => {
  // to 即将跳转到的路由对象
  // from 将要离开的路由对象
  // next() 函数
  
  // 开始是否进入登录
  if (to.name !== 'login') {
    if (HAS_LOGIN) next()  // 如果登录了, 继续
    else next({
      name: 'login'
    })
  } else { // 如果跳转到登录页面
    if (HAS_LOGIN) next({name: 'home'}) // 登录了, 到主页
    else next()  // 没有登录 next()
  }
})


// 全局路由后置守卫
router.afterEach((to, from) => {
  // 可以设置 loading 的进度 为 false
})


export default router
  • 路由独享守卫
// router.js
import Home from './views/Home.vue'
export default [
  {
    path: '/',  // url 路径
    name: 'Home',
    component: Home,  // 路径对应渲染组件
    beforeEnter: (to, from, next) => {
      // ...
      next()
    }
  }
]
  • 组件内的钩子
// home.vue



// argu.vue



  • 完整的导航解析流程
  1. 导航被触发。
  2. 在失活的组件里调用离开守卫。beforeRouteLeave
  3. 调用全局的 beforeEach 守卫。
  4. 在重用的组件里调用 beforeRouteUpdate 守卫 (2.2+)。
  5. 在路由配置里调用 beforeEnter
  6. 解析异步路由组件。
  7. 在被激活的组件里调用 beforeRouteEnter
  8. 调用全局的 beforeResolve 守卫 (2.5+)。
  9. 导航被确认。
  10. 调用全局的 afterEach 钩子。
  11. 触发 DOM 更新。
  12. 用创建好的实例调用 beforeRouteEnter 守卫中传给 next 的回调函数。

4. 路由元信息

// router.js
import Home from './views/Home.vue'
export default [
  {
    path: '/',  // url 路径
    name: 'Home',
    component: Home,
    meta: {  // 路由元信息
      title: '主页'
    }
  },
]
// src/router/index.js
import Vue from 'vue'
import Router from 'vue-router'
import routes from './router.js'
Vue.use(Router)

const router =  new Router({
  routes
})

// 全局路由前置守卫
router.beforeEach((to, from, next) => {
  // 元信息的判断
  if (to.meta && to.meta.title) {
    window.document.title = to.meta.title || 'admin'
  }
})

export default router

5. 过渡动效

  • 单个路由过渡




  • 动态过渡


  

// 接着在父组件内
// watch $route 决定使用哪种过渡
watch: {
  '$route' (to, from) {
    const toDepth = to.path.split('/').length
    const fromDepth = from.path.split('/').length
    this.transitionName = toDepth < fromDepth ? 'slide-right' : 'slide-left'
  }
}

你可能感兴趣的:(Vue路由全解)