浅谈vue-router

路由 VueRouter

  • 官网:https://router.vuejs.org/zh/
  • 概念:就是url路径,使用#在一个页面之中跳转,类似于a标签的锚链接!
    • 代表的是网页的一个位置,而#后面的的字符就是该位置的标志符!

    注意点:这种hash # 不会刷新页面,也不会发起新的请求,只是实现客户端页面的跳转!
    注意点2:就是http请求之中,不携带#,那么就是说不能向服务器发起请求
    注意点3:# 会修改浏览器的历史记录!

前端路由和后端路由的区别

  • 前端路由:就是根据#/ 后面的hash值,去匹配不同的path路径,显示不同的组件,达到页面跳转效果! hash => 组件
    • 目的:是为了单页面应用程序!(Single Page Application)
  • 后端路由:就是根据前端发送请求的url路径,去匹配url所对应的操作处理函数方法,待操作后,把数据返回给前端(渲染页面),实现前端页面的刷新!

路由的原理

 <div id="app">
    <a href="#/a">a</a>
    <a href="#/b">b</a>
    <a href="#/c">c</a>

    <!-- 显示当前的某个组件 -->
    <component :is="comname"></component>
  </div>

  <script src="../vue.js"></script>
  <script>
    Vue.component("com1", {
      template: "<div>a组件</div>"
    })
    Vue.component("com2", {
      template: "<div>b组件</div>"
    })
    Vue.component("com3", {
      template: "<div>c组件</div>"
    })

    let data = {
      comname: "com1"
    }
    let methods = {}
    new Vue({
      el: "#app",
      data,
      methods,
      mounted() {
        let self = this;
        window.onhashchange = function () {
          let hash = location.hash;
          console.log(hash, self.comname); //注意点:这边的this指向的是window

          switch (hash) {
            case "#/a":
              self.comname = "com1"
              break;
            case "#/b":
              self.comname = "com2"
              break;
            case "#/c":
              self.comname = "com3"
              break;
          }
        }
      }
    })
  </script>

路由的安装和使用

第一种方式使用
引入:以cnd的方式引入 <script src="https://lib.baomitu.com/vue-router/3.1.3/vue-router.min.js"></script>
第二种方式使用

  • 安装:npm i vue-router
  • 引用:
    import Vue form vue
    import VueRouter form vue-router
  • 使用:
    Vue.use(VueRouter)

使用第一种方式

路由的基本使用
  • 注意点:导入vue-router之后,就有这一个VueRouter构造函数了(全局的) 参数为一个对象
  • 创建一个路由对象 const router = new VueRouter({})
    • 里面的参数为一个对象 对象里面有着一个路由规则的数组 routes(路线)
    • routes:[{}] => 对象里面的有着path => 指向的是hash的路径 component => 指向的是路由的组件对象!还有redirect 重定向!
    • 注意点:需要把当前创建的router对象挂载在Vue实例对象之中
  • 需要呈现给用户的时候,则需要使用到 还有 这两个标签
    • router-view => 表示的是路由的坑,显而易见的是,就是需要等待匹配路由路径后,才能显示这个路由组件
    • router-link => 表示的是路由的链接,点击当前的链接,去往里面to属性所匹配的路由!
      • to属性所设置的路由链接!
      • tag属性,设置该link以哪种标签显示,默认为a链接! <router-link to="/login" tag="span" >去登录</router-link>
  <div id="app">
    <router-link to="/login">登录</router-link>
    <router-link to="/reg">注册</router-link>
    <router-view></router-view>
  </div>

  <script>
    //定义路由组件对象!
    const login = { //这种方式 只是适合路由对应的组件才能创建的路由对象! 
      template: "<div>登录组件</div>"
    }
    const reg = {
      template: "<div>注册组件</div>"
    }
    const router = new VueRouter({
      routes: [{
        path: "/login", //这是hash路径
        component: login //这是hash路径所对应的组件对象 也就是说,需要从组件之中,抽离出这个单独的对象
      }, {
        path: "/reg",
        component: reg
      }]
    })
    let data = {}
    let methods = {}
    new Vue({
      el: "#app",
      data,
      methods,
      router, //把路由对象 挂载在vue实例对象身上!
    })
  </script>
普通组件和路由组件对象的区别
  <div id="app">
    <!-- 这是引用普通组件 -->
    <login></login>

    <!-- 这是路由组件的引用 -->
    <!-- 这是路由的链接  to 去往哪里 -->
    <router-link to="/login">去登录</router-link>
    <router-link to="/reg">去注册</router-link>

    <!-- 这是路由的坑,将来是匹配组件呈现的坑! -->
    <router-view></router-view>
  </div>
//定义一个普通组件
    Vue.component("login", { //这种定义的普通组件,仅仅在标签之中引用! 无法在hash之中的组件使用!
      template: "<div>注册组件</div>"
    })

//定义一个路由组件
    //路由之中的组件设置!  就是把Vue.component中的对象抽离出来!
    const login = {
      template: "<div>我是登录组件</div>"
    }
    const router = new VueRouter({ //router为路由规则 path为hash路径 component为hash要对应的组件对象
      //匹配到的路由路径,想要展示给用户看,那么需要在html之中,引用一个<router-view>标签!
      routes: [{
        path:"/",
        redirect:"/login"
        },{ //routes => 路线是复数哦!
        path: "/login",
        component: login
      }, {
        path: "/reg",
        component: reg
      }, ]
    })

    new Vue({
      el: "#app",
      data:,
      methods: {

      },
      router, //把router 路由对象挂载在vm实例对象上
    })
路由的高亮显示和重定向
  • 第一种高亮的显示,使用默认的类名: => router-link-active 给这个类名添加样式!
  • 已经设置好类名的方式,那么就在new VueRouter构造函数内部,使用 linkActiveClass: “my-active”
    • //配置路由的活跃的样式 默认类名为 router-link-active
  • 重定向的话:就是在vue路由规则配置之中,添加一个对象
    {
           path: "/",
            redirect: "/login"
          }
    
  <div id="app">
    <!-- router-link-active 当你点击的路由链接的时候,自动给你添加了这个类名!因此可以在这个类名上添加活跃的样式! -->
    <router-link to="/login">登录</router-link>
    <router-link to="/reg">注册</router-link>
    <router-view></router-view>
  </div>


  <script src="../vue.js"></script>
  <script src="https://unpkg.com/vue-router@2.0.0/dist/vue-router.js"></script>

  <script>
    //定义登录和注册的路由对象
    const login = { 
      template: "<div>登录组件</div>",
    }
    const reg = {
      template: "<div>注册组件</div>"
    }

    const router = new VueRouter({
      routes: [{
          path: "/",
          redirect: "/login"
        },
        {
          path: "/login",
          component: login
        }, {
          path: "/reg",
          component: reg
        }
      ],
      linkActiveClass: "my-active" //配置路由的活跃的样式 默认类名为 router-link-active

    })
    new Vue({
      el: "#app",
      data: {},
      methods: {},
      router
    })
  </script>

路由的传递参数

  • 注意点:不管如何,都是在route组件的传递参数,那么其存储的值在于route之中!,而this可以省略!
  • 第一种方式:?参数
    • 在router-link中的to属性中以?后面拼接参数,不需要修改路由规则!
      <router-link to="/login?id=10">登录</router-link>
    • 获取?后面的参数 => 这是因为在路由规则下的参数,存储在route之中!
      this.$route.query.id id还是其他的参数等!
  • 第二种方式:/:id/:name
    • 在router-link中的to属性中以/:id/:name后面拼接参数,不需要修改路由规则!
      <router-link to="/login/10/asx">登录</router-link>
    • 获取这种方式的参数:this.$route.params
  • 第三种方式:开启一个props传递参数
    • (在需要传递参数的组件中把props设置为true)
              {
              path: "/login/:id/:name",
              component: login,
              props: true //开启props传递参数!
            }
      
    • 引用的时候,在路由对象之中使用一个props数组的形式存储这些参数 然后可以使用!
        props: ["id", "name"],
        template: "<div>登录组件 {{id}}--{{name}}</div>",
      

方式1:?参数

 <div id="app">
    <!-- router-link-active 当你点击的路由链接的时候,自动给你添加了这个类名!因此可以在这个类名上添加活跃的样式! -->
    <router-link to="/login?id=10">登录</router-link>
    <router-link to="/reg">注册</router-link>
    <router-view></router-view>
  </div>

  <script>
    //定义登录和注册的路由组件对象
    const login = { //注意点:在组件之中,也有生命周期函数
      template: "<div>登录组件 {{ this.$route.query.id}}</div>",
      created() {//这是data和methods初始化后的!
        console.log(this.$route.query)

      }
    }
    const reg = {
      template: "<div>注册组件</div>"
    }

    const router = new VueRouter({
      routes: [{
          path: "/",
          redirect: "/login"
        },
        {
          path: "/login",
          component: login
        }, {
          path: "/reg",
          component: reg
        }
      ],
      linkActiveClass: "my-active" //配置路由的活跃的样式 默认类名为 router-link-active

    })
    new Vue({
      el: "#app",
      data: {},
      methods: {},
      router
    })
  </script>

方式2:/:id/:name

 <div id="app">
    <!-- router-link-active 当你点击的路由链接的时候,自动给你添加了这个类名!因此可以在这个类名上添加活跃的样式! -->
    <router-link to="/login/10/asx">登录</router-link>
    <router-link to="/reg">注册</router-link>
    <router-view></router-view>
  </div>
  <script>
    //定义登录和注册的路由对象
    const login = { //注意点:在组件之中,也有生命周期函数
      template: "<div>登录组件 {{ $route.params.id}}--{{ this.$route.params.name}}</div>",
      created() {
        console.log(this.$route.params)

      }
    }
    const reg = {
      template: "<div>注册组件</div>"
    }

    const router = new VueRouter({
      routes: [{
          path: "/",
          redirect: "/login"
        },
        {
          path: "/login/:id/:name",
          component: login
        }, {
          path: "/reg",
          component: reg
        }
      ],
      linkActiveClass: "my-active" //配置路由的活跃的样式 默认类名为 router-link-active

    })
    new Vue({
      el: "#app",
      data: {},
      methods: {},
      router
    })
  </script>

方式3

 <div id="app">
    <!-- router-link-active 当你点击的路由链接的时候,自动给你添加了这个类名!因此可以在这个类名上添加活跃的样式! -->
    <router-link to="/login/10/asx">登录</router-link>
    <router-link to="/reg">注册</router-link>
    <router-view></router-view>
  </div>

  <script>
    //定义登录和注册的路由对象
    const login = { //注意点:在组件之中,也有生命周期函数
      props: ["id", "name"],
      template: "<div>登录组件 {{id}}--{{name}}</div>",
      created() {
        console.log(this);
      }
    }
    const reg = {
      template: "<div>注册组件</div>"
    }

    const router = new VueRouter({
      routes: [{
          path: "/",
          redirect: "/login"
        },
        {
          path: "/login/:id/:name",
          component: login,
          props: true //开启props传递参数!
        }, {
          path: "/reg",
          component: reg
        }
      ],
      linkActiveClass: "my-active" //配置路由的活跃的样式 默认类名为 router-link-active

    })
    new Vue({
      el: "#app",
      data: {},
      methods: {},
      router
    })
  </script>

路由的嵌套

  • 在router对象里面的routes(路由规则)里面定义每一个路由规则,但是路由规则内还有子路由规则,那么需要使用到children属性了
    注意点:就是使用children属性定义的子路由,证明是在当前路由的之路由了,因此所匹配的组件路径,不需要添加 /
    const router = new VueRouter({
        routes: [{ //routes:定义路由规则 children:定义的是子路由规则 在children内的路径不需要添加/ 因为children已经代表是当前路由孩子了!
            path: "/account",
            component: account,
            children: [ {
              path: "login",
              component: login
            }]
        }]
      })
    
 <div id="app">
    <router-link to="/account">显示账号组件</router-link>
    <router-link to="/newlist">显示新闻组件</router-link>
    <router-view></router-view>
  </div>

  <template id="account">
    <div class="account">
      <!-- 这是路由的链接 -->
      <router-link to="/account/login">登录</router-link>
      <router-link to="/account/reg">注册</router-link>
      <!-- 这是路由匹配后,显然的容器 -->
      <router-view></router-view>

    </div>
  </template>

  <template id="login">
    <div>这是登录组件</div>
  </template>
  <template id="reg">
    <div>
      这是注册组件
    </div>
  </template>
  <script src="../vue.js"></script>
  <script src="https://lib.baomitu.com/vue-router/3.1.3/vue-router.min.js"></script>
  <script>
    // 显示账号组件
    const account = {
      template: "#account",

    }
    // 新闻列表的组件
    const newlist = {
      template: `
      <div class="newlist">新闻列表组件</div>
      `
    }
    //登录组件对象
    const login = {
      template: "#login"
    }
    //注册组件对象
    const reg = {
      template: "#reg"
    }
    const router = new VueRouter({
      routes: [{ //routes:定义路由规则 children:定义的是子路由规则 在children内的路径不需要添加/ 因为children已经代表是当前路由孩子了!
          path: "/account",
          component: account,
          children: [{
            path: "/",
            redirect: "login"
          }, {
            path: "login",
            component: login
          }, {
            path: "reg",
            component: reg
          }]
        },
        {
          path: "/newlist",
          component: newlist
        }
      ]
    })
    new Vue({
      el: "#app",
      data: {},
      methods: {},
      router
    })
  </script>

路由懒加载

  • 打包构建项目的时候,js包会变得越来越大,影响页面的加载速度
    • 因此可以使用路由的懒加载方式处理,就是用到的时候就加载(把路由模块分为几个模块)
    • 比如首页 - 我的 - 购物车 - 商品列表 (这是个大的路由,分为4个打包模块!)
      const Home = ()=> import("路径")
      然后把Home组件,在路由规则之中配置!

路由的传递参数 => 方式之编程式导航

  • 声明式导航
  • 编程式导航

方式1 某个组件之中.vue => 编程式导航

  • 需求:点击新闻,跳转到新闻这个路由,并且传递id过去
  <!-- 声明式的路由导航 借助内部组件 router-link-->
    <router-link to="/news/20">新闻</router-link>
    <router-link to="/profile/222/菲菲">档案</router-link>

    <!-- 编程式的按钮 -->
    <button @click="goNews(122)">新闻</button>
    <button @click="goProfile(222,'啦啦')">档案</button>
    <router-view></router-view>
  • 编程式导航的处理 跳转
  methods: {
    goNews(id) {
      this.$router.push({
        name: "News",
        params: { id },
      });
    },
    goProfile(id, name) {
      this.$router.push({
        name: "Profile",
        params: { id, name },
      });
    },
  },
  • 在具体组件之中接受参数Profile.vue
<template>
  <div>
    我是档案
    {{$route.params.id}} --- {{$route.params.name}}
    <router-view></router-view>
  </div>
</template>
  • 路由的配置
const routes = [{
    path: '/',
    name: 'Home',
    component: Home
  },{
    path: '/profile/:id/:name',
    name: 'Profile',
    component: () => import('../views/Profile.vue')
  }, {
    path: '/news/:id',
    name: 'News',
    component: () => import('../views/News.vue')
  }
]

路由导航守卫

  • 官网:https://router.vuejs.org/zh/guide/advanced/navigation-guards.html#%E5%85%A8%E5%B1%80%E5%89%8D%E7%BD%AE%E5%AE%88%E5%8D%AB
  • 关于更新你点击的页面,显示对应的标题!
    • 这就需要在监听路由的跳转,实时的显示对应的标题!

全局前置路由守卫 => 带有next()

  • route/index.js文件
  • 01:需要在路由配置的时候,设置一个meta对象,里面有着title属性 => 这是关于需要显示的title
  • 02:需要使用路由守卫, => 取出从哪里跳转到哪里路由的title属性
  • to => 去往那个路由
    • 由于to去往的路由,可能存在路由的嵌套,那么最好的话,使用 to.matched[0] 取出第一个路由
  • from => 从那个路由跳转
  • next() => 就是一个管道运输,执行下一个的钩子函数,如果全部钩子执行完了,则导航的状态就是 confirmed (确认的)。
//路由守卫
router.beforeEach((to, from, next) => {
  document.title = to.matched[0].meta.title
   <!-- document.title = to.meta.title  -->
  next();
})
import Vue from 'vue'
import VueRouter from 'vue-router'
import Home from '../views/Home.vue'

Vue.use(VueRouter)

const routes = [{
    path: '/',
    name: 'Home',
    meta: {
      title: "首页"
    },
    component: Home
  }, {
    path: '/profile/:id/:name',
    name: 'Profile',
    meta: {
      title: "档案"
    },
    component: () => import('../views/Profile.vue')
  }, {
    path: '/news',
    name: 'News',
    meta: {
      title: "新闻"
    },
    component: () => import('../views/News.vue')
  }
]

const router = new VueRouter({
  // mode: 'history',
  // base: process.env.BASE_URL,
  routes
})

//路由守卫
router.beforeEach((to, from, next) => {
  document.title = to.matched[0].meta.title
  next();
})
export default router
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值