美文网首页vue
vue-router 常用知识点一

vue-router 常用知识点一

作者: 我跟你蒋 | 来源:发表于2019-02-15 18:02 被阅读53次

    目录

    - 1.vue-router响应 路由参数 的变化

    - 2.vue-router如何定义嵌套路由?

    - 3.vue-router的几种实例方法以及参数传递


    - 1. vue-router响应 路由参数 的变化

    提醒一下,当使用路由参数时,例如从 /user/foo 导航到 /user/bar,原来的组件实例会被复用。因为两个路由都渲染同个组件,比起销毁再创建,复用则显得更加高效。不过,这也意味着组件的生命周期钩子不会再被调用

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

    const User = {
      template: '...',
      watch: {
        '$route' (to, from) {
          // 对路由变化作出响应...
        }
      }
    }
    

    或者使用 2.2 中引入的 beforeRouteUpdate 导航守卫

    const User = {
      template: '...',
      beforeRouteUpdate (to, from, next) {
        // react to route changes...
        // don't forget to call next()
      }
    }
    ```注意是:
    
    (1)从同一个组件跳转到同一个组件。
    
    (2)生命周期钩子created和mounted都不会调用。
    

    - 2.vue-router如何定义嵌套路由?

    大家都知道选项卡,在选项卡中,顶部有数个导航栏,中间的主体显示的是内容;这个时候,整个页面是一个路由,然后点击选项卡切换不同的路由来展示不同的内容,这个时候就是路由中嵌套路由。

    在实际项目中我们会碰到多层嵌套的组件组合而成,但是我们如何实现嵌套路由呢?因此我们需要在 VueRouter 的参数中使用 children 配置,这样就可以很好的实现路由嵌套。

    ① 为了演示,我们现在view文件夹下新建一个title1.vue和title2.vue用来存放不同的内容


    ② 现在我们在router 》 index.js 中将这上面两个新建的组件引入进来并填写路径,这里的Title1和Title2是作为test.vue页面的子路由,所以要写在children属性下



    ③ 然后我们再去到test.vue中敲:
    在这里提个醒,在to后面写路由路径的时候,一定到带上绝对路径,也就是要把test这个父路由路径写进去"/test/title1"

    ④ 最后我们进入浏览器点击不同的标题就可以看到不同内容的展示



    路由嵌套总结

    任何子路由都是在其父路由的组件中切换显示,不管是多少层的路由嵌套,都是这样的理解,所以父路由需要有以下两点,二者缺一不可

    有组件引用
    组件中有router-view组件

    父路由没有引用组件,导致子路由没有承载容器,自然而然就出现了两层路由跳不起来等不起效的情况

    - 3.vue-router的几种实例方法以及参数传递

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

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

    这个方法会向 history 栈添加一个新的记录,所以,当用户点击浏览器后退按钮时,则回到之前的 URL。
    注意:在 Vue 实例内部,你可以通过 router 访问路由实例。因此你可以调用 this.router.push。
    当你点击 <router-link> 时,这个方法会在内部调用,所以说,点击 <router-link :to="..."> 等同于调用 router.push(...)。

    声明式 编程式
    <router-link :to="..."> router.push(...)
    参数:字符串或者对象
    // 字符串
    router.push('home')
    
    // 对象
    router.push({ path: 'home' })
    
    // 命名的路由
    router.push({ name: 'user', params: { userId: '123' }})
    
    // 带查询参数,变成 /register?plan=private
    router.push({ path: 'register', query: { plan: 'private' }})
    

    注意:如果提供了 path,params 会被忽略,上述例子中的 query 并不属于这种情况。取而代之的是下面例子的做法,你需要提供路由的 name 或手写完整的带有参数的 path:

    const userId = '123'
    router.push({ name: 'user', params: { userId }}) // -> /user/123
    router.push({ path: `/user/${userId}` }) // -> /user/123
    // 这里的 params 不生效
    router.push({ path: '/user', params: { userId }}) // -> /user
    

    在 2.2.0+,可选的在 router.pushrouter.replace 中提供 onCompleteonAbort 回调作为第二个和第三个参数。这些回调将会在导航成功完成 (在所有的异步钩子被解析之后) 或终止 (导航到相同的路由、或在当前导航完成之前导航到另一个不同的路由) 的时候进行相应的调用。

    注意: 如果目的地和当前路由相同,只有参数发生了改变 (比如从一个用户资料到另一个 /users/1 -> /users/2),你需要使用 beforeRouteUpdate 来响应这个变化 (比如抓取用户信息)。

    #router.replace(location, onComplete?, onAbort?)

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

    声明式 编程式
    <router-link :to="..." replace> router.replace(...)

    #router.go(n)

    这个方法的参数是一个整数,意思是在 history 记录中向前或者后退多少步,类似 window.history.go(n)。

    例子
    
    // 在浏览器记录中前进一步,等同于 history.forward()
    router.go(1)
    
    // 后退一步记录,等同于 history.back()
    router.go(-1)
    
    // 前进 3 步记录
    router.go(3)
    
    // 如果 history 记录不够用,那就默默地失败呗
    router.go(-100)
    router.go(100)
    
    router.push router.replace router.go
    window.history.pushState window.history.replaceState window.history.go

    Browser History APIs

    • 参数传递

    一、使用冒号(:)的形式传递参数 或者说 采用url传参

    在路由文件里采用冒号的形式传参,这就是对参数的绑定

    1,路由列表的参数设置

    (1)路由列表的 path 是可以带参数的,我们在路由配置文件(router/index.js)里以冒号的形式设置参数。

    (2)下面样例代码中,在跳转到欢迎页面(/hello)时,带有两个参数:id 和 userName。

    | 
    
    import Vue from 'vue'
    
    import Router from 'vue-router'
    
    import index from '@/components/index'  //引入首页组件
    
    import hello from '@/components/hello'  //引入欢迎页组件
    
    //Vue全局使用Router
    
    Vue.use(Router)
    
    export  default new Router({
    
    routes: [ //配置路由,使用数组形式
    {
    path: '/',   //链接路径
    name: 'index',  //路由名称
    component: index  //映射的组件
    },
    
    {
    path: '/hello/:id/:userName',
    name: 'hello',
    component: hello
    }
    ]
    })
    
    

    2,参数的传递

    (1)如果使用 <router-link> 组件跳转的话,可以这么携带参数:

    <router-link to="/hello/123/hangge">跳转到 hello</router-link>
    

    (2)如果使用 js 代码跳转的话,可以这么携带参数:

    this.$router.push("/hello/123/hangge");
    

    3,参数的获取

    页面中通过 $route.params.xxx 获取传递过来的数据。

    <template>
    <div>
    <h1>ID:{{ $route.params.id}}</h1>
    <h1>用户名:{{ $route.params.userName}}</h1>
    </div>
    </template>
    

    4,运行效果

    可以看到点击首页链接进行跳转后,参数成功传递并显示。

    (参数传递)     (参数传递)

    二、使用 query 方式传递参数

    1,路由列表

    query 方式类似 get 传参,即通过 URL 传递参数。而路由列表的 path 不需要配置参数:

    import Vue from 'vue'
    import Router from 'vue-router'
    import index from '@/components/index'  //引入首页组件
    import hello from '@/components/hello'  //引入欢迎页组件
     
    //Vue全局使用Router
    Vue.use(Router)
     
    export default new Router({
      routes: [ //配置路由,使用数组形式
        {
          path: '/',   //链接路径
          name: 'index',  //路由名称
          component: index//映射的组件
        },
        {
          path: '/hello',
          name: 'hello',
          component: hello
        }
      ]
    })
    

    2,参数的传递

    (1)如果使用 <router-link> 组件跳转的话,可以这么携带参数:

    <router-link :to="{path:'/hello', query:{id:123, userName:'hangge'}}">
    跳转到 hello
    </router-link>
    

    (2)如果使用 js 代码跳转的话,可以这么携带参数:

    this.$router.push({`
    path:'/hello',
    query:{
    id:123, 
    userName:'hangge'
    }
    });
    
    

    3,参数的获取

    页面中通过 $route.query.xxx 获取传递过来的数据。

    <template>
    <div>
    <h1>ID:{{ $route.query.id}}</h1>
    <h1>用户名:{{ $route.query.userName}}</h1>
    </div>
    </template>
    

    4,运行效果

    可以看到点击首页链接进行跳转后,参数是自动拼接到 url 后面进行传递的。

    (参数传递)

    三、使用 params 方式传递参数

    1,路由列表

    params 方式类似于 post 传参,即传递的参数不会显示在 URL 上。同上面的 query 方式一样,路由列表的 path 不需要配置参数:
    注意:如果路由上面不写参数,也是可以传过去的,但不会在url上面显示出你的参数,并且当你跳到别的页面或者刷新页面的时候参数会丢失,那依赖这个参数的http请求或者其他操作就会失败。

    import Vue from 'vue'
    import Router from 'vue-router'
    import index from '@/components/index' //引入首页组件
    import hello from '@/components/hello' //引入欢迎页组件
    
    //Vue全局使用Router
    
    Vue.use(Router)
    
    export default new Router({
    
    routes: [ //配置路由,使用数组形式
    
    {
    path: '/',   //链接路径
    name: 'index',  //路由名称
    component: index//映射的组件
    },
    
    {
    path: '/hello',
    name: 'hello',
    component: hello
    }
    ]
    })
    

    2,参数的传递

    注意:params 只能用 name 来引入路由,而不能用 path。

    (1)如果使用 <router-link> 组件跳转的话,可以这么携带参数:

    <router-link :to="{name:'hello', params:{id:123, userName:'hangge'}}">
    跳转到 hello
    </router-link>
    
    

    (2)如果使用 js 代码跳转的话,可以这么携带参数:

    this.$router.push({
    name:'hello',
    params:{id:123, userName:'hangge'}
    });
    
    

    3,参数的获取

    页面中通过 $route.params.xxx 获取传递过来的数据。

    <template>
    <div>
    <h1>ID:{{ $route.params.id}}</h1>
    <h1>用户名:{{ $route.params.userName}}</h1>
    </div>
    </template>
    

    4,运行效果

    可以看到这种方式,参数的传递不会拼接到 url 后面。

    ( 参数传递)

    从上面的样例可以看出,当路由携带参数跳转时,页面这边通过 route.params.xxx 或route.query.xxx 来获取传递过来的数据。但这样有个问题,由于组件中使用 $route 会使之与其对应路由形成高度耦合,从而使组件只能在某些特定的 URL 上使用,限制了其灵活性。
    要解决这个问题,我们可以使用 props 将组件和路由解耦。props 共有如下三种模式。

    附使用 props将组件和路由解耦:

    取代与 $route 的耦合

    const User = {
      template: '<div>User {{ $route.params.id }}</div>'
    }
    const router = new VueRouter({
      routes: [
        { path: '/user/:id', component: User }
      ]
    })
    
    

    通过 props 解耦

    const User = {
      props: ['id'],
      template: '<div>User {{ id }}</div>'
    }
    const router = new VueRouter({
      routes: [
        { path: '/user/:id', component: User, props: true },
    
        // 对于包含命名视图的路由,你必须分别为每个命名视图添加 `props` 选项:
        {
          path: '/user/:id',
          components: { default: User, sidebar: Sidebar },
          props: { default: true, sidebar: false }
        }
      ]
    })
    
    

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

    #布尔模式

    (1)如果 props 被设置为 trueroute.params 将会被设置为组件属性。

    export default new Router({
    
    routes: [ //配置路由,使用数组形式
    {
    path: '/', //链接路径
    name: 'index',  //路由名称
    component: index  //映射的组件
    },
    {
    path: '/hello/:id/:userName',
    name: 'hello',
    component: hello,
    props: true
    }
    ]
    
    })
    

    (2)然后我们页面组件这边不再需要通过 route.params.xxx 或route.query.xxx 来获取传递过来的数据。

    <template>
    <div>
    <h1>ID:{{ id }}</h1>
    <h1>用户名:{{ userName}}</h1>
    </div>
    </template>
    <script>
    export default {
    name: 'hello',
    props: ['id', 'userName']
    }
    </script>
    

    #对象模式

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

    const router = new VueRouter({
      routes: [
        { path: '/promotion/from-newsletter', component: Promotion, props: { newsletterPopup: false } }
      ]
    })
    或
    export default new Router({
    
    routes: [ //配置路由,使用数组形式
    {
    path: '/', //链接路径
    name: 'index',  //路由名称
    component: index  //映射的组件
    },
    {
    path: '/hello/:id/:userName',
    name: 'hello',
    component: hello,
    props: {
    id: 1234,
    userName: "hangge"
    }
    }
    ]
    
    

    (2)然后页面组件这边获取数据方式和前面一样。

    <template>
    <div>
    <h1>ID:{{ id }}</h1>
    <h1>用户名:{{ userName}}</h1>
    </div>
    </template>
    <script>
    export default {
    name: 'hello',
    props: ['id', 'userName']
    }
    </script>
    

    #函数模式

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

    const router = new VueRouter({
      routes: [
        { path: '/search', component: SearchUser, props: (route) => ({ query: route.query.q }) }
      ]
    })
    ---------------------------
    function dynamicPropsFunc (route) {
      return {
        message: "欢迎您:"+ route.params.userName
      }
    }
    const router = new VueRouter({
      routes: [
        { path: '/search', component: SearchUser, props: dynamicPropsFunc }
      ]
    })
    

    (2)这里假设我们使用 JS 进行跳转,代码如下:

    this.$router.push({
    name:'hello',
    params:{id:123, userName:'hangge'}
    });
    

    (3)目标页面组件代码,以及运行结果如下:

    (参数传递)
    <template>
      <div>
        <h1>{{ message }}</h1>
      </div>
    </template>
     
    <script>
      export default {
        name: 'hello',
        props: ['message']
      }
    </script>
    

    URL /search?q=vue 会将 {query: 'vue'} 作为属性传递给 SearchUser 组件。

    请尽可能保持 props 函数为无状态的,因为它只会在路由发生变化时起作用。如果你需要状态来定义 props,请使用包装组件,这样 Vue 才可以对状态变化做出反应。
    例子https://github.com/vuejs/vue-router/blob/dev/examples/route-props/app.js

    相关文章

      网友评论

        本文标题:vue-router 常用知识点一

        本文链接:https://www.haomeiwen.com/subject/ffxmeqtx.html