Vue-router基础知识

1. 响应路由参数的变化

定义一个路由如下:

12345678910111213141516
export default new Router({  mode: ‘history‘,  base: process.env.BASE_URL,  routes: [    {      path: ‘/‘,      name: ‘home‘,      component: Home    },    {      path: ‘/project/:projectId‘,      name: ‘project‘,      component: () => import(‘./views/Project.vue‘)    }  ]})

在上面这段代码中以:号开头的(:projectId)是动态路由参数,当使用路由参数时,例如从 /project/1 导航到 /project/2,原来的组件实例会被复用。因为两个路由都渲染同个组件,比起销毁再创建,复用则显得更加高效。不过,这也意味着组件的生命周期钩子不会再被调用。

复用组件时,想对路由参数的变化作出响应的话,你可以简单地 watch (监测变化) $route 对象:

123456789
export default {  watch: {    ‘$route‘ (to, from) {      console.log("from:"+from.path);      console.log("to:"+to.path);      // 对路由变化作出响应...    }  }}

注意:上面这段代码只有在$route变化时才会执行。

2. 捕获所有路由或 404 Not found 路由

常规参数只会匹配被 / 分隔的 URL 片段中的字符。如果想匹配任意路径,我们可以使用通配符 (*):

12345
{  path: ‘*‘,  name: ‘page404‘,  component: () => import(‘./views/404.vue‘)}

当使用通配符路由时,请确保路由的顺序是正确的,也就是说含有通配符的路由应该放在最后。路由 { path: ‘*’ } 通常用于客户端 404 错误。

以上两小节的相关代码实例gitHub地址:
https://github.com/johnnynie/vue-demos/tree/master/vue-router-demos/demo1

3. 使用js实现路由跳转(导航)

除了使用 创建 a 标签来定义导航链接,我们还可以借助 router 的实例方法,通过编写代码来实现。

  • router.push(location, onComplete?, onAbort?)

在 Vue 组件实例内部,可以通过 $router 访问路由实例,因此在Vue组件实例内部,可以调用this.$router.push(location, onComplete?, onAbort?),下同。
这个方法会向 history 栈添加一个新的记录,所以,当用户点击浏览器后退按钮时,则回到之前的 URL。

当你点击 时,这个方法会在内部调用,所以说,点击 等同于调用 router.push(…)。它将会导航到不同的URL。
以下是一些实例:

12345678910111213
//home为定义的路由名称// 字符串router.push(‘home‘)// 对象router.push({ path: ‘home‘ })// 命名的路由,userId为路由参数router.push({ name: ‘user‘, params: { userId: ‘123‘ }})// 带查询参数,变成 /register?plan=privaterouter.push({ path: ‘register‘, query: { plan: ‘private‘ }})const userId = ‘123‘router.push({ name: ‘user‘, params: { userId }}) // -> /user/123router.push({ path: `/user/${userId}` }) // -> /user/123
  • router.replace(location, onComplete?, onAbort?)

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

  • router.go(n)

在 history 记录中向前或者后退多少步

4.使用嵌套视图与同级视图实现页面布局

为了实现一些复杂页面布局,我们经常需要用到嵌套视图,在定义路由时,通过children实现路由的嵌套关系。而在实现一些简单的页面时,如果不想为这个页面单独的创建一个.vue文件,我们也可以用同级视图,同级视图是指:一个界面中多个路由视图,可实现同级展示多个视图,而非嵌套。多个视图的情况下,需要给每个视图设置名字,如果 router-view 没有设置名字,那么默认为 default。
以下路由定义代码中实现了嵌套路由,其中在路由name为project的路由定义中使用了同级视图:

12345678910111213141516171819202122232425262728
{  path: ‘/index‘,  name: ‘layout‘,  component:  () => import(‘@/views/Layout.vue‘),  redirect: ‘/index/home‘,  children: [    {      path:‘home‘,      name: ‘home‘,      component: () => import(‘@/views/Home.vue‘)    },    {      path:‘projectlist‘,      name:‘projectlist‘,      component: () => import(‘@/views/ProjectList.vue‘),      children:[        {          path:‘project/:projectId‘,          name:‘project‘,          components: {            default: () => import(‘@/views/ProjectDetailHead.vue‘),            detail:() => import(‘@/views/ProjectDetailContent.vue‘)          }        }      ]    }  ]}

详细的实例代码请访问以下GitHub地址:
https://github.com/johnnynie/vue-demos/tree/master/vue-router-demos/demo2

5.使用props实现路由组件传参

在组件中使用 $route 会使之与其对应路由形成高度耦合,从而使组件只能在某些特定的 URL 上使用,限制了其灵活性。
使用 props 将组件和路由解耦:

1234567891011121314151617181920212223242526272829303132333435
{  path:‘projectlist‘,  name:‘projectlist‘,  component: () => import(‘@/views/ProjectList.vue‘),  //列表模式  props: { listTitle: "项目列表展示" },  children:[    {      path:‘project/:projectId‘,      name:‘project‘,      //布尔模式      props:true,      component: Project    }  ]},// 对于包含命名视图的路由,你必须分别为每个命名视图添加 `props` 选项:{  path:‘projectlist2‘,  name:‘projectlist2‘,  component: () => import(‘@/views/ProjectList2.vue‘),  //函数模式  props: (route) => ({ listTitle: route.query.title }),  children:[    {      path:‘project2/:projectId‘,      name:‘project2‘,      components: {        default: () => import(‘@/components/ProjectDetailHead.vue‘),        detail: () => import(‘@/components/ProjectDetailContent.vue‘)      },      props:{default:false,detail:true}    }  ]}

这样你便可以在任何地方使用该组件,使得该组件更易于重用和测试。

props的书写有三种模式:布尔模式、对象模式、函数模式

  • 布尔模式

如果 props 被设置为 true,route.params 将会被设置为组件属性。

1234567
{  path:‘project/:projectId‘,  name:‘project‘,  //布尔模式  props:true,  component: Project}
123456789
{  path:‘project2/:projectId‘,  name:‘project2‘,  components: {    default: () => import(‘@/components/ProjectDetailHead.vue‘),    detail: () => import(‘@/components/ProjectDetailContent.vue‘)  },  props:{default:false,detail:true}}
  • 对象模式

如果 props 是一个对象,它会被按原样设置为组件属性。当 props 是静态的时候有用。

1234567
{  path:‘projectlist‘,  name:‘projectlist‘,  component: () => import(‘@/views/ProjectList.vue‘),  //对象模式  props: { listTitle: "项目列表展示" }}
  • 函数模式

你可以创建一个函数返回 props。这样你便可以将参数转换成另一种类型,将静态值与基于路由的值结合等等。

1234567
{  path:‘projectlist2‘,  name:‘projectlist2‘,  component: () => import(‘@/views/ProjectList2.vue‘),  //函数模式  props: (route) => ({ listTitle: route.query.title })}

URL /projectlist2?title=项目列表展示 会将 {listTitle: ‘项目列表展示’} 作为属性传递给 projectlist2 组件。

详细的实例代码请访问以下GitHub地址:
https://github.com/johnnynie/vue-demos/tree/master/vue-router-demos/demo3

相关推荐