vue-Router(组件间过渡跳转数据传输)

路由是通过互联的网络把信息从源地址传输到目的地址的活动(主要分前端路由和后端路由)

 

// 路由模式  hash 和history
// hash:
// 1. 通过监听浏览器的 onhashchange() 事件变化,查找对应的路由变化规则
// 2. 浏览器地址带 '#'
// 3. location.hash 改变 '#' 后面的跳转地址

// history:
// 1. 利用html5 historyInterface 中新增的 pushState() 和 replaceState() 方法
// 2. 通过 history.pushState({传递数据},"标题","URL地址(例:/home)")    跳转页面地址
// 3. 通过 history.back()    返回上一个跳转页面
// 4. 通过 history.replaceState({传递数据},"标题","URL地址(例:/home)")    替换要跳的页面
// 5. history.go(1)    正数代表往前跳几个页面,负数代表往后
// 6. history.forward()    往前走一个页面

 

在项目中使用VUE Router

1. 安装(以安装4.0版本为例,npm 和 yarn 两种安装方法)  

npm install vue-router@4 

yarn add vue-router@4

 

2. 创建router 路由对象(文件路径:src/router/index.js)

2-1. 使用顺序,router/index.js 中引入,创建,导出
2-2. man.js中全局引入,use注册
2-3. 页面中使用
// router/index.js

//
1.引入 import { nextTick } from 'vue'; import { createRouter, createWebHashHistory, createWebHistory } from 'vue-router' // import Home from './../components/Home.vue' // import Mine from './../components/Mine.vue' // import News from './../components/News.vue' // 使用路由懒加载引入 // const Home = () => // import ('./../components/Home.vue') // const Mine = () => // import ('./../components/Mine.vue') // const News = () => // import ('./../components/News.vue') // 2.创建路由对象 const routes = [ // 路由重定项 { path: '/', redirect: '/home', meta: { title: '首页' } }, { path: '/home', name: 'home', meta: { title: '首页' }, component: () => import ('./../components/Home.vue') }, { path: '/mine', name: 'mine', meta: { title: '我的', keepAlive: true }, component: () => import ('./../components/Mine.vue'), // 二级嵌套路由 children: [ { path: '/mine', redirect: '/mine/order' }, { path: 'msg', name: 'msg', component: () => import ('./../components/MineMsg.vue') }, { path: 'order', name: 'order', component: () => import ('./../components/MineOrder.vue') }, ], // beforeEach:(to,from,next) => {} // 独享路由守卫(此场景较少使用) }, { // 动态路由配置 path: '/news/:id', name: 'News', meta: { title: '新闻' }, component: () => import ('./../components/News.vue') }, { path: '/circle', name: 'Circle', meta: { title: '圈子' }, component: () => import ('./../components/Circle.vue') }, ] // 3.创建路由(在此配置对象,使用hash 模式还是history 模式) const router = createRouter({ // history: createWebHashHistory(), //hash 模式 history: createWebHistory(), // history 模式 routes, // 映射对象 linkActiveClass: 'current' }) // 全局路由的前置守卫 router.beforeEach((to, from, next) => { console.log(from, '从哪来...'); console.log(to, '到哪去....') document.title = to.meta.title // 替换浏览器的title名称 // 放行 next() }) // 全局路由的后置守卫 // 4.导出路由对象 export default router

 

// 在页面中使用
// router-link 作用相当于a 标签(导航),加上属性 to="/home"(配置的路由path) 然后router-vuew 作用路由出口,显示对应导航的展示页面内容

<template> <!-- 导航 --> <div id="nav"> <!-- <router-link to="/home" active-class="current">首页</router-link> <router-link to="/mine" active-class="current">我的</router-link> --> <!-- 使用底层的默认选中样式类 --> <!-- <router-link to="/home" >首页</router-link> <router-link to="/mine" >我的</router-link> --> <!-- 通过代码实现跳转,不用routerLink --> <!-- <button @click="home()">首页</button> <button @click="mine()">我的</button> --> <!-- 动态路由 --> <router-link to="/home" >首页</router-link> <router-link to="/mine" >我的</router-link> <!-- <router-link to="/news/001" >新闻</router-link> --> <router-link :to="'/news/'+newsId" >新闻</router-link> <!-- 通过query方式路由传参 --> <router-link :to="{path:'/circle',query:{name:'tom',sex:'男'}}" >圈子</router-link> </div> <!-- 路由出口 --> <!-- <router-view></router-view> --> <!-- 组件缓存方式的路由出口--vue2写法 --> <!-- <keep-alive> <router-view></router-view> </keep-alive> --> <!-- 组件缓存方式的路由出口--vue3写法(所有业务页面均被缓存) --> <router-view v-slot="{Component}"> <!-- 只缓存的组件,也可以用数组的形式:exclude="['Home','Circle']" --> <keep-alive :exclude="Home,News"> <component :is='Component'/> </keep-alive> <!-- 当router/index.js中设置了keepAlive:true --> <!-- <keep-alive> <component :is='Component' v-if="$router.meta.keepAlive"/> </keep-alive> <component :is='Component' v-if="!$router.meta.keepAlive"/> --> </router-view> </template> <script> import { useRouter } from "vue-router" import router from "./router" import {ref} from 'vue' export default{ setup(){ const newsId = ref('001') // 跳转首页 const home = () => { router.push('/home') } // 跳转我的 const mine = () => { router.push('/mine') } return{home,mine,newsId} } } </script> <style> /* 默认的底层样式类 */ .router-link-active{ font-size: 18px; color: red; font-weight: bolder; } .current{ font-size: 18px; color: orange; font-weight: bolder; } </style>

hash 和 history 两种模式的区别:

hash:

1. 内部传递的实际 url 之前使用一个哈希字符(#),路由系统匹配时直接截取 # 号后面的,回车不会发起http请求(# 兼容IE8,兼容性更好)

2. 这部分 url 从未被送到服务器,不需要在服务器后面上进行任何特殊的处理

3. 它在SEO 中确实有不存的影响

history:

1. 因为应用是一个单页的客户端应用,H5新推出的,兼容到IE10 ,回车会发起HTTP 请求

2. 用户在浏览器中直接访问嵌套路由时会报404错误

3. 需要在任务器上添加一个回退路由

 

路由参数传递

params:配置理由格式(/router/:params);传递方式,在path 侯曼跟上传递的参数;传递后形成路径,/router/001 或 /router/002

query:属于 url 地址的一部分,带 ?(问号)拼接键值对传参

            1. 配置路由方式 /router

            2. 传递方式  对象中使用query 的key 作为传递方式

            3. 传递后形成路径  /router ? id=001

 

<router-link :to="{path:'home',query:{name:'tom',sex:'男'}}"></router-link>

会将query 对象内键值对去除转换成地址栏上的内容拼接显示,如果想拿到传递的数据在 HTML 代码页面中通过 $router.query.name 拿

在实例中(JS 中),import 引入 useRoute 从 vue-router 中  let route = useRoute()   route.query.name(获取)

涉及到路由嵌套 hash 不需要服务器做任何处理,因为在onhashchange() 事件中会做相应处理,history会影响到后端,因为后端要在这种嵌套路由的层级中加一个回退路由

router-link 常用属性:to -- 对应的路径(目标路由)点击后to 把值传到router.push()

                                   replace -- 禁止回退(直接在标签上添加即可) 点击时调用 router.replace() 而不是 router.push() ,导航后不会留下历史记录

                                   activeClass -- 选中的样式(一个对应的样式类)也可以直接使用底层的默认样式类名 .router-link-active 定义,还可以在 router/index.js 中的 createRouter 中配置:(全局) linkActiveClass:‘页面中的自定义样式类名’

 

* 不用routerlink 用其他标签实现跳转(使用点击方式JS)

vue3 中引入useRouter 可以拿到路由配置的 js 文件的所有router(全局信息),useRoter 是可以拿到当前页面的路由path配置信息,通过 router.push (‘路径地址’)跳转自己想要跳转的页面

 

*动态路由:在一些场景下,一个页面的path 路径可能是不确定(例如商品,新闻详情页),router/index.js 中配置 routes 的path:“/news/:id”(通过:(冒号)匹配对应id 展示),跳转页面中<router-link to="/news/00">新闻</router-link>(这里的to 的值也可以动态拼接动态路由 :to="'/news/'+id")

template 内获取当前页面的对应id 值:$route.params.id

setup 中获取当前路由:引入 useRoute 从 vue-router 中   const route = useRoute()    console.log(route.params.id)

 

 路由懒加载

 当打包构建应用时,JS 包会变得非常大,影响页面加载,如果能把不同路由对应的组件分割成不同的代码块,当路由被访问的时候才加载对应组件,这样会更高效,因为 vue 是单页面应用,所有的页面代码最终都汇集在根页面(index.html 中)展示这样就会造成页面非常大。在 router/index.js 中,不用 import 直接引入对应的页面模块,而是使用箭头函数引入(对应的component配置)实现懒加载

 

路由嵌套

一些应用程序的 UI 由多层嵌套的组件组成,在 router/index.js 中的对应的一级路由下添加 children:[ ] 继续配置二级路由的path 及 component 属性,以及进入一级路由的重定向设置,注意:二级以下的path 路径不用带 ‘/’,重定向的路径要带上一级的path 路径地址,然后在对应的一级页面内,继续添加 router-link 和router-view 标签展示(router-link to 属性的地址为“/一级路由path/二级path”,再有三级或四级继续 children 配置下去即可

 

全局守卫

beforeEach 全局路由的前置守卫:通过router.beforeEach((to,from,next) =>{ })  做一些权限控制

ro -- 到哪去  from -- 从哪来  next() -- 放行

通过 routes 的每个也没按路由内加属性meta(源信息配置,对象,内配置键值对信息),在路由守卫中通过 document.title = to.meta.title 这种获取对应信息值(这里最好放在after 里,用于分析,更改页面标题,声明页面等)

这里举例,用户登录验证ok 后通过进入:afterEach 代表已经进入到路由对应的组件内,通过router.afterEach((to,from) => { })

 

在开发过程中还有可能有一种路由独享守卫(此情况较少出现),就是在routes 的单个路由中配置路由守卫,即与 path.meta. 等平级配置 beforEach:(to,from,next) => { }

 

组件内路由守卫(此情况较少使用):在业务页面引入 onBeforeRouteLeave,onBeforeRouteUpdate 从 vue-router 中,在setup 中使用这两个钩子方法,

例如:onBeforeRouteLeave((to,from,next) => { })

 

keep-alive:vue的一个内置组件,可以使被包含的组件保留状态,避免被重复渲染

// vue2 中

<keep-alive>
    <router-view></router-view>
</keep-alive>

// 现 vue3

<router-view v-slot="{component}">
    <keep-alive>
        <component :is="component"/>
    </keep-alive>
</router-view>

为了验证缓存效果可以引入onMounted,onUnmounted from “vue”

onMounted(() => { })       onUnmounted(() => { })

以上两个周期内验证被缓存的组件页面是否会频繁的销毁和创建

引入onActivated,onUeactivated from “vue”(一旦用keep-alive 包裹后,就会触发这两个生命周期)

keep-alive 常用属性:1. include(string/RegExp/Array)只有名称匹配的组件被缓存

                                    2. exclude(string/RegExp/Array)任何名称匹配的组件都不被缓存

                                    3. max(number/string)最多可以缓存多少组件实例

除了在APP.vue 中全局设置,也可在 router/index.js 中的 meta 中添加keepAlive:true 属性,然后在APP.vue 中的路由出口处设置

<keep-alive>
    <component :is="compinent" v-if="$router.meta.keepAlive"/>
</keep-alive>

<component :is="component" v-if="!$router.meta.keepAllive"/>

 

posted on 2022-07-10 22:08  一名小学生呀  阅读(420)  评论(0编辑  收藏  举报

导航