• 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 组件。

  • 相关阅读:
    ZooKeeper 相关知识
    zookeeper 启动和停止脚本
    es 6.4.3 版本的es的处理方式
    SpringBoot启动使用elasticsearch启动异常:Received message from unsupported version:[2.0.0] minimal compatible
    windows下安装elasticsearch-6.4.3和elasticsearch-head插件
    二项式公式
    计算公式
    大规模数据如何检索?
    设计数据服务:为报表服务提供服务接口
    win10 桌面快捷键技术
  • 原文地址:https://www.cnblogs.com/codestarer/p/13635523.html
Copyright © 2020-2023  润新知