zoukankan      html  css  js  c++  java
  • vue-router 实战了解这些就够了

    一. 安装

    1.1. 加入依赖

    npm install vue-router

    1.2. 项目中引入

    以最新的vue-cli3架构为例,在main.js中加入

    import Vue from 'vue'
    import VueRouter from 'vue-router'
    
    Vue.use(VueRouter)

    更普遍的,一般是有一个专门的路由js文件,如router.js

    在main.js中只是引入router.js。而在router.js中加入上述引用部分。以后相关路由配置都是router.js中配置的。

    以上涉及各js文件的目录组织如下:

    src

    ------ main.js

    ------ router

    ------------ router.js

    1.3. 示例

    先贴实战部分示例来了解一下直观的用法

    main.js

    import 'babel-polyfill'
    import Vue from 'vue'
    import Vuex from 'vuex'
    import App from './App.vue'
    import router from './router/router'
    import store from './vuex/store'
    import api from './api/api'
    import Vant from 'vant'
    import 'vant/lib/index.css'
    import infiniteScroll from 'vue-infinite-scroll'
    Vue.use(infiniteScroll)
    Vue.use(Vuex)
    Vue.use(Vant)
    Vue.prototype.$api = api
    
    new Vue({
      router, // 通过 router 选项,提供了一种机制将 “路由” 从根组件注入到每一个子组件中,子组件能通过 this.$router 访问
      store, // 通过 store 选项,提供了一种机制将 “状态” 从根组件注入到每一个子组件中,子组件能通过 this.$store 访问
      render: h => h(App)
    }).$mount('#app')

    router.js

    import Vue from 'vue'
    import Router from 'vue-router'
    
    const home = () => import('@/views/index/index.vue')
    const airport = () => import('@/components/airport/airport.vue')
    const orderDetail = () => import('@/views/order/order-detail.vue')
    
    Vue.use(Router)
    export default new Router({
      mode: 'hash',
      base: process.env.BASE_URL,
      routes: [
        {
          path: '/',
          name: 'home',
          component: home
        },
        {
          path: '/airport',
          name: 'airport',
          component: airport
        },
        {
          path: '/orderDetail/:orderNo',
          name: 'orderDetail',
          component: orderDetail
        }
      ]
    })
    

    二. 用法

    2.1. 第一个demo

    • HTML
    <script src="https://unpkg.com/vue/dist/vue.js"></script>
    <script src="https://unpkg.com/vue-router/dist/vue-router.js"></script>
    
    <div id="app">
      <h1>Hello App!</h1>
      <p>
        <router-link to="/foo">Go to Foo</router-link>
        <router-link to="/bar">Go to Bar</router-link>
      </p>
      <router-view></router-view>
    </div>
    • JS
    // 0. 如果使用模块化机制编程,导入Vue和VueRouter,要调用 Vue.use(VueRouter)
    
    // 1. 定义 (路由) 组件。
    // 可以从其他文件 import 进来
    const Foo = { template: '<div>foo</div>' }
    const Bar = { template: '<div>bar</div>' }
    
    // 2. 定义路由
    const routes = [
      { path: '/foo', component: Foo },
      { path: '/bar', component: Bar }
    ]
    
    // 3. 创建 router 实例,然后传 `routes` 配置
    const router = new VueRouter({
      routes // (缩写) 相当于 routes: routes
    })
    
    // 4. 创建和挂载根实例。
    // 通过 router 配置参数注入路由从而让整个应用都有路由功能
    const app = new Vue({
      router // (缩写) 相当于 router: router
    }).$mount('#app')

    通过注入路由器,我们可以在任何组件内通过 this.$router 访问路由器,也可以通过 this.$route 访问当前路由:

    // Home.vue
    export default {
      computed: {
        username () {
          return this.$route.params.username
        }
      },
      methods: {
        goBack () {
          window.history.length > 1
            ? this.$router.go(-1)
            : this.$router.push('/')
        }
      }
    }

    2.2. 动态路由匹配

    即请求url中包含动态参数时的匹配,类似这种形式: /user/:id,类似于springMVC中的@pathVariable

    下面举个基本的栗子了解下用法:

    1. 请求路径:/user/:id
    2. 应用场景:比如可以把不同ID的用户都映射到User组件上
    3. 然后再User组件中可以通过 this.$route.params.id 取到动态url上的params参数对象中的id属性

    可以在一个路由中设置多段“路径参数”,对应的值都会设置到 $route.params 中。例如:

    模式 匹配路径 $route.params
    /user/:username /user/evan { username: 'evan' }
    /user/:username/post/:post_id /user/evan/post/123 { username: 'evan', post_id: '123' }

    除了 $route.params 外,$route 对象还提供了其它有用的信息,例如,$route.query (如果 URL 中有查询参数)、$route.hash 等等。

    2.3. 嵌套路由

    例如通常在App.vue中有一个最顶层渲染出口 <router-view />

    <template>
      <div id="app" class="app">
        <router-view />
      </div>
    </template>

    当访问 /user/1 时会把User组件渲染到最顶层的出口<router-view />

    同时User组件中包含嵌套的渲染出口<router-view />

    例如,在 User 组件的模板添加一个 <router-view />

    const User = {
      template: `
        <div class="user">
          <h2>User {{ $route.params.id }}</h2>
          <router-view></router-view>
        </div>
      `
    }

    要在嵌套的出口中渲染组件,需要在 VueRouter 的参数中使用 children 配置:

    const router = new VueRouter({
      routes: [
        { path: '/user/:id', component: User,
          children: [
            {
              // 当 /user/:id/profile 匹配成功,
              // UserProfile 会被渲染在 User 的 <router-view> 中
              path: 'profile',
              component: UserProfile
            },
            {
              // 当 /user/:id/posts 匹配成功
              // UserPosts 会被渲染在 User 的 <router-view> 中
              path: 'posts',
              component: UserPosts
            }
          ]
        }
      ]
    })

    children 配置就是像 routes 配置一样的路由配置数组!

    此时,基于上面的配置,当你访问 /user/foo 时,User 的出口是不会渲染任何东西,这是因为没有匹配到合适的子路由。如果你想要渲染点什么,可以提供一个 空的 子路由:

    const router = new VueRouter({
      routes: [
        {
          path: '/user/:id', component: User,
          children: [
            // 当 /user/:id 匹配成功,
            // UserHome 会被渲染在 User 的 <router-view> 中
            { path: '', component: UserHome },
    
            // ...其他子路由
          ]
        }
      ]
    })

    2.4. 编程式的导航

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

    声明式 编程式
    <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' }})

    注意:如果提供了 pathparams 会被忽略!

    因为path选项就表示完整的URL,而params又是URL中的一部分,所以同时存在会有歧义!

    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.4.2. router.replace(location, onComplete?, onAbort?)

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

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

     

     

     

    2.4.3. 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)

    2.5. 命名路由

    const router = new VueRouter({
      routes: [
        {
          path: '/user/:userId',
          name: 'user', // 给路由起个名字而已
          component: User
        }
      ]
    })
    <router-link :to="{ name: 'user', params: { userId: 123 }}">User</router-link>

      或者 

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

      调用皆可以!

    2.6. 重定向

    当用户访问 /a时,URL 将会被替换成 /b,然后匹配路由为 /b

    const router = new VueRouter({
      routes: [
        { path: '/a', redirect: '/b' }
      ]
    })
    const router = new VueRouter({
      routes: [
        { path: '/a', redirect: { name: 'foo' }}
      ]
    })
    const router = new VueRouter({
      routes: [
        { path: '/a', redirect: to => {
          // 方法接收 目标路由 作为参数
          // return 重定向的 字符串路径/路径对象
        }}
      ]
    })

    2.7. 别名

    /a 的别名是 /b,意味着,当用户访问 /b 时,URL 会保持为 /b,但是路由匹配则为 /a,就像用户访问 /a 一样。

    const router = new VueRouter({
      routes: [
        { path: '/a', component: A, alias: '/b' }
      ]
    })

    2.8. 路由组件传参

    顾名思义,就是在路由的过程中,把路由参数转换成组件属性,按照组件间传值的方式进行传参!

    why do this?

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

    2.8.1. 用法对比

    与 $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 被设置为 trueroute.params 将会被设置为组件属性。

    对象模式

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

    const router = new VueRouter({
      routes: [
        { path: '/promotion/from-newsletter', component: Promotion, props: { newsletterPopup: false } }
      ]
    })

    函数模式

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

    const router = new VueRouter({
      routes: [
        { path: '/search', component: SearchUser, props: (route) => ({ query: route.query.q }) }
      ]
    })
    

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

  • 相关阅读:
    我要好offer之 二叉树大总结
    我要好offer之 字符串相关大总结
    楼层扔鸡蛋问题[转]
    Linux System Programming 学习笔记(十一) 时间
    Linux System Programming 学习笔记(十) 信号
    Linux System Programming 学习笔记(九) 内存管理
    Linux System Programming 学习笔记(八) 文件和目录管理
    Linux System Programming 学习笔记(七) 线程
    Linux System Programming 学习笔记(六) 进程调度
    APUE 学习笔记(十一) 网络IPC:套接字
  • 原文地址:https://www.cnblogs.com/codestarer/p/13635523.html
Copyright © 2011-2022 走看看