Vue 路由的使用

作者: YM雨蒙 | 来源:发表于2019-04-17 19:49 被阅读5次

    主要就结合我做的一个商户后台的应用来学习一下路由

    这个应用主要有

    • 登录页 /login
    • 注册页 /register
    • 404页面 404
    • 首页 /home
      • 以及在首页里面通过路由来跳转的各个页面 /home/xxx
    我们使用vue脚手架快速原型开发, 使用的是 @vue/cli 3.x 版本的
    1. 安装 
    npm install -g @vue/cli
    # OR
    yarn global add @vue/cli
    
    2. 创建项目
    vue create hello-world
    
    看到src/ 下的 main.js
    // main.js 来渲染 App 作为顶层出口
    import Vue from 'vue'
    import App from './App.vue'
    
    new Vue({
      router,
      render: h => h(App)
    }).$mount('#app')
    
    我们把 App 作为顶层, 来渲染登录, 注册, 首页等同一级的组件
    // App.vue
    <template>
      <div id="app">
        <router-view/>  // <router-view> 是最顶层的出口,渲染最高级路由匹配到的组件.
      </div>
    </template>
    
    每个路由映射一个组件
    // router.js
    import Vue from 'vue'
    import Router from 'vue-router'
    import Home from './views/Home.vue'
    Vue.use(Router)
    
    const router = new Router({
      routes: [   
        {
          path: '/login',  // path : 路径
          name: 'Login',  // 给某个路由设置名称。
          component: () => import('./views/login.vue')  // 动态加载对应路由
        },
        {
          path: '/register',
          name: 'Register',
          component: () => import('./views/register.vue')
        },
        {
          path: '/',
          name: 'home',
          redirect: '/home/index',   // 重定向, 从 / 重定向到 /home/index
          component: Home,
          meta: {  // 路由元信息
            requiresAuth: true
          },
        }
      ]
    })
    export default router
    

    这样我们就可以在浏览器url中输入不同的 path 值, 链接到对应的 vue 组件

    带 # 号是因为 url 是 hash 模式
    
    http://localhost:8080/#/login  // 对应登录组件
    http://localhost:8080/#/register  // 对应注册组件
    http://localhost:8080/#/home/index  // 对应首页
    
    我们来看一下 home 组件的组成
    <template>
      <div id="home">
        <y-header></y-header>  // 使用组件
        <Row class="center_view">
          <Col span="4">
            <y-side></y-side>
          </Col>
          <Col span="20">
            <router-view/>  // 又是一个 router-view, 可以渲染home 下 不同 url 的组件, 嵌套路由
          </Col>
        </Row>
      </div>
    </template>
    
    <script>
      import YHeader from './../components/YHeader'  // 引入组件
      import YSide from './../components/YSide'
      export default {
        name: 'home',
        components: {
          YHeader,YSide  // 注册组件到这个页面
        }
      }
    </script>
    
    要在嵌套的出口中渲染组件,需要在 Router 路由的参数中使用 children 配置
    // router.js
    
    import Vue from 'vue'
    import Router from 'vue-router'
    import Home from './views/Home.vue'
    Vue.use(Router)
    
    const router = new Router({
      routes: [   
        {
          path: '/login',  // path : 路径
          name: 'Login',  // 给某个路由设置名称。
          component: () => import('./views/login.vue')  // 动态加载对应路由
        },
        {
          path: '/register',
          name: 'Register',
          component: () => import('./views/register.vue')
        },
        {
          path: '/',
          name: 'home',
          redirect: '/home/index',   // 重定向, 从 / 重定向到 /home/index
          component: Home,
          meta: {  // 路由元信息
            requiresAuth: true
          },
          // children 配置就是像 routes 配置一样的路由配置数组,所以呢,你可以嵌套多层路由。
          children: [  // 配置嵌套路由的 Children
            {
              path: '/home/a',  // router-view 可以渲染 A
              name: 'A',
              component: () => import('./views/shopManagement/A.vue')
            },
            {
              path: '/home/b',  //  // router-view 可以渲染  B
              name: 'B',
              component: () => import('./views/shopManagement/B.vue')
            },         
          ]
        }
      ]
    })
    export default router
    
    对于后台, 我们可以设置侧边栏有不同的分级, 点击不同的跳转到对应的
    <!-- 使用 router-link 组件来导航. -->
    <!-- 通过传入 `to` 属性指定链接. -->
    <!-- <router-link> 默认会被渲染成一个 `<a>` 标签 -->
    
    <router-link to="/home/a">
      <span>跳转到a链接</span>
    </router-link>
    <router-link to="/home/b">
      <span>跳转到b链接</span>
    </router-link>
    
    我们也可以使用编程式导航
    
    想要导航到不同的 URL,则使用 router.push 方法
    上面的 router-link 等同于
    
    this.$router.push({path: '/a'})
    this.$router.push({name: 'A'})
    
    如果我们需要把 a 组件里值传给 b 组件, 我们可以使用路由传参
    • 可以使用 query 传参
    • 可以使用 params 传参
    // query 方式传参和接受参数
    
    query相当于get请求,页面跳转的时候,可以在地址栏看到请求参数
    
    传参
    this.$router.push({
      path: '/xxx', 
      query: {
        id: id
      }
    })
    
    接受参数
    this.$route.query.id
    
    ** 注意:传参是this.$router,接收参数是this.$route
    
    url 是这样的:  /xxx?id=123
    
    // params 方式传参和接受参数
    
    传参
    this.$router.push({
      name: 'xxx', // 命名路由的名字
      params: {
        id: id
      }
    })
    
    接收参数
    this.$route.params.id
    
    url 是这样的  /xxx/123
    
    • 两者的区别
    路由设置这里,当你使用 params 方法传参的时候,要在路由后面加参数名,并且传参的时候,参数名要跟路由后面设置的参数名对应
    {
      path: '/home/a/:id',  // 接收参数的路由, 使用 params传参要加参数名, id 就是参数名
      name: 'A',
      component: () => import('./views/shopManagement/A.vue')
    },
    
    使用query方法,就没有这种限制,直接在跳转里面用就可以
    
    ** 注意:如果路由上面不写参数,也是可以传过去的,但不会在url上面显示出你的参数,并且当
    你跳到别的页面或者刷新页面的时候参数会丢失(如下图所示),那依赖这个参数的http请求
    或者其他操作就会失败。
    
    
    
    1、params是路由的一部分,必须要有。query是拼接在url后面的参数,没有也没关系。
        params一旦设置在路由,params就是路由的一部分,如果这个路由有params传参,但是在
        跳转的时候没有传这个参数,会导致跳转失败或者页面会没有内容。
    

    上面路由基本就是Vue 的大部分功能可以使用了

    路由高级一点的也有一些导航守卫可以使用

    • 全局的
    router.beforeEach 注册一个全局前置守卫
    
    const router = new VueRouter({
      // ...
    })
    
    router.beforeEach((to, from, next) => {
    
    })
    // to: Route: 即将要进入的目标路由对象
    // from: Route: 当前导航正要离开的路由
    // 确保要调用 `next` 方法,否则钩子就不会被 resolved。
    
    
    router.afterEach 注册一个全局后置钩子
    
    router.afterEach((to, from) => {
      // ...
    })
    
    • 路由独享的
    const router = new VueRouter({
      routes: [
        {
          path: '/foo',
          component: Foo,
          beforeEnter: (to, from, next) => {
            // ...
          }
        }
      ]
    })
    
    • 组件内的守卫
    const Foo = {
      template: `...`,
      beforeRouteEnter (to, from, next) {
        // 在渲染该组件的对应路由被 confirm 前调用
        // 不!能!获取组件实例 `this`
        // 因为当守卫执行前,组件实例还没被创建
      },
      beforeRouteUpdate (to, from, next) {
        // 在当前路由改变,但是该组件被复用时调用
        // 举例来说,对于一个带有动态参数的路径 /foo/:id,在 /foo/1 和 /foo/2 之间跳转的时候,
        // 由于会渲染同样的 Foo 组件,因此组件实例会被复用。而这个钩子就会在这个情况下被调用。
        // 可以访问组件实例 `this`
      },
      beforeRouteLeave (to, from, next) {
        // 导航离开该组件的对应路由时调用
        // 可以访问组件实例 `this`
      }
    }
    
    
    beforeRouteEnter 守卫 不能 访问 this,因为守卫在导航确认前被调用,因此即将登场的新组件还没被创建。
    
    不过,你可以通过传一个回调给 next来访问组件实例。在导航被确认的时候执行回调,并且把组件实例作为回调方法的参数。
    
    beforeRouteEnter (to, from, next) {
      next(vm => {
        // 通过 `vm` 访问组件实例
      })
    }
    

    完整的导航解析流程

    • 导航被触发。
    • 在失活的组件里调用离开守卫。
    • 调用全局的 beforeEach 守卫。
    • 在重用的组件里调用 beforeRouteUpdate 守卫 (2.2+)。
    • 在路由配置里调用 beforeEnter。
    • 解析异步路由组件。
    • 在被激活的组件里调用 beforeRouteEnter。
    • 调用全局的 beforeResolve 守卫 (2.5+)。
    • 导航被确认。
    • 调用全局的 afterEach 钩子。
    • 触发 DOM 更新。
    • 用创建好的实例调用 beforeRouteEnter 守卫中传给 next 的回调函数。

    参考

    Vue Router 官方文档

    相关文章

      网友评论

        本文标题:Vue 路由的使用

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