Vue-Router的使用详解

Posted coder斌

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Vue-Router的使用详解相关的知识,希望对你有一定的参考价值。

认识路由

渲染 & 路由

后端渲染 & 前端渲染

  • 后端渲染:在浏览器内输入地址,浏览器就可以展示一个页面,而页面内容展示的数据在后台服务器那边就已经渲染好了,浏览器只需要对返回的html做一个渲染就行了。
  • 前端渲染:在浏览器内输入地址,浏览器返回的是一些静态资源文件,内容里面的数据,由浏览器执行脚本,向服务器发送请求,浏览器拿到数据后,浏览器再渲染的页面上。

后端路由 & 前端路由

  • 后端路由:URL(唯一资源地址符),一个URL对应一个页面,浏览器地址栏的地址由服务器(后端)来处理URL和页面之间的映射关系。
  • 前端路由:URL和页面之间的映射关系由前端来处理。

URL的hash & HTML5的History

URL的hash

  • url的hash(锚点 # ):URL地址 # 后面的东西。
  • 改变hash不会引起页面的刷新,因为:hash会出现在url内,但是不会出现在HTTP请求中。
  • 点击浏览器页面刷新,会重新请求资源。

HTML5的History

  • HTML5的history模式,也不会引起页面的刷新。
  • history利用了浏览器的 历史记录栈,将每页面的信息放入的栈中。
  • 通过api对栈进行操作和展示浏览器显示的页面。
  • APIpushState、popState、replaceState、go、forward、back

使用 vue-router

基本使用

  • 安装:npm install vue-router@4
  • 配置映射关系:

image-20210707095311905

  • 注册路由

    将路由文件内导出的router在main.js内注册

import { createApp } from 'vue'
import App from './App.vue'
import router from "./router/index";
createApp(App).use(router).mount('#app')
  • 使用

    配置关系设置好了,注册完成,在使用时设置对应的路径,就会展示对应的组件页面出来。

    提供了内部组件:router-link(配置要跳转的路径)和router-view(占位标签,页面就在这里展示)。

<template>
  <div class="app">
    <router-link to="/home">首页</router-link>
    <router-link to="/about">关于</router-link>
    <router-view></router-view>
  </div>
</template>

其他小补充

  • meta添加信息。
{
    path: '/about',
    component: About,
    meta: {
        address: '湖南',
        university: '湖南中医药大学'
    }
}

先知道可以这样,后面会说到怎么取到其中的内容。

  • 重定向redirect。本来默认下页面打开就应该直接跳到主页,但是就上面配置还需手动点击才行,解决这个小问题,配置重定向。

    routes 内增加一个映射:

    {
      path: '/',
      redirect:'/home'
    }
    
  • history模式:将 createWebHashHistory()改为createWebHistory()

router-link属性

  • to
    • 字符串:要跳转的路径。
    • 对象:跳转和传参。
<template>
  <div class="app">
    <router-link to="/home">首页</router-link>
    <router-link :to="{ path:'/about', query:{name:'fzb',age:18}}">关于</router-link>
    <router-view></router-view>
  </div>
</template>
  • replace在history模式下默认是pushState的,设置 replace 转换成replaceSatate
  • active-class不设置此属性,默认条件下对应跳转页面的元素增加的类是 router-link-active。太复杂了不好记,使用 active-class设置自定义类名。
  • exact-active-class默认是 router-link-exact-active,这个是浏览器地址栏的路径和页面映射路径完全一致是才设置对应的class。太复杂了不好记,使用 exact-active-class设置自定义类名。

路由懒加载 (常用)

假如开发的时候,在配置映射关系时的component直接是像上面一样导入,那么打包后会打包到同一个js文件内。

其实这样不好,会增加首屏渲染时间,用户体验下降,其实可以其他页面在没有点开过就不需要加载。

如下操作:

// 改写成未注释写法
// import Home from "../page/Home.vue";
// import About from "../page/About.vue";

const Home = () =>
    import ('../page/Home.vue');
const About = () =>
    import ('../page/About.vue');

小补充webpack知识:魔法注释

设置自定义打包名

image-20210707105403993

动态路由

基本使用

image-20210707110510942

获取动态路由的值

  • template标签
<h2>{{$route.params.userid}}</h2>
  • options API中,通过 this
computed:{
  userId(){
    return this.$route.params.userid
    }
}
  • composition API中,是没有 this 的。
<script>
import { useRoute } from "vue-router";
export default {
  setup(){
      const routr = useRoute();
      const userId = routr.params.userid
      return {
          userId
      }
  }
}
</script>

匹配多个参数

匹配模式路径匹配$route.params
/user/:userid/user/0240{ “userid”: “0240” }
/user/:name/:userid/user/fzb/0240{ “name”: “fzb”, “userid”: “0240” }
/user/:name/id/:userid/user/fzb/id/0240{ “name”: “fzb”, “userid”: “0240” }

NotFound

在地址栏输入路径,没有匹配到,显示的页面。

image-20210707112708698

同样可以获取到路径内的信息。

image-20210707113014429

细节:pathMatch(.*)后加不加*

匹配模式路径匹配$route.params.pathMatch
/:pathMatch(.*)/home/111/home/111
/:pathMatch(.*)*/home/111[ “home”, “111” ]

路由的嵌套

配置

{
    path: '/home',
    component: Home,
    redirect: '/home/message',
    children: [{
        path: 'message',
        component: () = >import('../page/HomeMessage.vue')
    },
    {
        path: 'goods',
        component: () = >import('../page/HomeGoods.vue')
    }]
}

在Home.vue内增加router-linkrouter-view就可以了。

代码实现路由跳转

  • template
<button @click="$router.push('/home')">首页</button>
  • option API
<script>
export default {
  name: 'App',
  methods:{
    btnClic(){
      this.$router.push('/home')
    }
  }
}
</script>
  • composition API
<script>
import { useRouter } from "vue-router";
export default {
  name: 'App',
  setup(){
    const router =  useRouter();
    const btnClic = ()=> {
     router.push('/home')
    }
    return{
      btnClic
    }
  }
}
</script>

除了router由push方法外,还有pop、replace、go、back、forward方法。

query方式的参数

发送

<router-link :to="{ path:'/about', query:{name:'fzb',age:18}}"  active-class="fzb">关于</router-link>

或者

this.$router.push({
    path: '/home',
    query: {
        name: 'fzb',
        age: 18
    }
})

接收

  • template直接接收使用
<h2>$route.query</h2>
  • option API使用
this.$route.query
  • composition API 使用
<script>
import { useRoute } from "vue-router";
export default {
  setup(){
    const route = useRoute();
    const querys = route.query;
    return{
      querys
    }
  }
}
</script>

router-link的补充

在vue-router3.x的时候,router-link内有一个属性 tag 默认条件下,router-link会渲染成一个a标签,当设置其他标签的名字(包括组件名)都会渲染成相应标签。

router-link的插槽

  • 标签内设置custom属性,表自定义router-link。

  • 作用域插槽v-slot返回一个对象,对象内的值说明:

    • navigate:一个函数。指定渲染目标标签,须同时设置navigatecustom
    • href:跳转目标的路径。
    • route:目标页面的路由对象。
    • isActive:路径是否匹配的状态。
    • isExactActive:路径是否是精准匹配的状态;

router-view的补充

router-view的插槽

  • 作用域插槽v-slot返回一个对象,对象内的值说明:
    • Component:要渲染的组件
    • route:解析出的标准化路由对象

直接点击按钮,页面切换,太生硬,结合transition使用。

image-20210707142820546

动态添加路由

根据不同的权限,注册不同的路由,并不是注册死的路由。

  • 动态添加一级路由addRouter方法

    拿到 router 对象

const addOneRoute = {
    path: '/first',
    component: () =>
        import ('../page/AddOneRoute.vue')
}
router.addRoute(addOneRoute);
  • 动态添加二级路由addRouter方法

    第一个参数传入父级映射的 name属性。

const addOneRoute = {
    path: 'next',
    component: () =>
        import ('../page/AddOneRoute.vue')
}
router.addRoute('parentName', addOneRoute);

删除路由

  • 添加一个name相同的路由;
router.addRoute({path:'/category',name:'category',component:Category});
// 会将上面的路由覆盖掉
router.addRoute({path:'/other',name:'category',component:Other});
  • 删除路由方法removeRoute
router.addRoute({ path: '/category', name: 'category', component: Category });
router.removeRoute('category');
  • 删除路由函数addRoute后返回函数
const remove = router.addRoute({ path: '/category', name: 'category', component: Category });
//调用addRoute后返回的值,是一个函数,直接调用,删除路由。
remove();

其他方法

  • router.hasRoute():检查路由是否存在。
  • router.getRoutes():获取一个包含所有路由记录的数组。

路由守卫

在进行跳转前,可以进行拦截,可以进行一些操作。

全局守卫

  • 前置守卫 router.beforeEach(( to, from )=>{ ..... return xxx })

    • to:要进入的路由

    • from:当前导航要离开的路由

      每次跳转都会调用

    返回值情况分类

    返回值类型(return的类型)对应的操作
    字符串(’/home’)导航到 路径为 /home 对应的页面
    undefined或不写返回值默认跳转
    false不进导航
    对象类似于router.push({path: ‘/about’ , query:{ name:‘fzb’}})

接下来的我也不是很了解,用到是在去查,提供链接

路由独享的守卫守卫

在配置映射关系的对象内配置路由独享守卫:beforeEnter,接收 tofrom两参数,参数意思与上方一致。

组件内守卫

在组件内定义的守卫,和option API一样是一个选项。

  • beforeRouteEnter
  • beforeRouteUpdate
  • beforeRouteLeave

在这里插入图片描述

文章看了,动画看了,如果客官觉得可以,三连支持一下吧。(确实写了挺久的)

以上是关于Vue-Router的使用详解的主要内容,如果未能解决你的问题,请参考以下文章

Vue第七天学习笔记之vue-router详解

Vue3的vue-router路由详解

详解基于vue,vue-router, vuex以及addRoutes进行权限控制

项目集成 vue-router 和 vuex

详解vue-router 2.0 常用基础知识点之router-link

vue-router详解