vue-router的学习

vue-router

基于Vue做单页面应用时,vue-router可以帮我们将url地址和组件绑定,在我们切换路由组件时,url改变,页面无需从服务端重新加载,即不用刷新,打个比方,我们用美团外卖点外卖时,切换点击左边的菜品标签,若页面总是重新加载,每次重新加载整个页面都闪烁一下,用户的体验很不好。

1. 基本使用

1.1 安装 vue-router:

使用vue2安装对应的router3版本

npm i vue-router@3

使用vue3安装对应的router4版本

npm i vue-router@4

1.2 引入router

在 src 下创建router文件夹,在router文件夹里创建 index.js

/src/router/index.js

//引入Vuerouter
import VueRouter from 'vue-router'
//引入想要展示的路由组件
const router = new VueRouter({
  	routes:[
        {
            path: '/xxx',//url
            component: [路由组件名],//对应的组件名
        },
    ]  
})
export default router

在 main.js 文件中引入并注册路由

main.js

import Vue from 'vue'
import App from './App.vue'
//1. 引入
import VueRouter from 'vue-router'
import router from './router'
Vue.use(VueRouter)

new Vue({
  render: h => h(App),
  //2. 注册
  router
}).$mount('#app')

1.3 使用router

一般在/src/pages下存放路由组件,在/src/components下存放其他组件

1.3.1 路由导航 <router-link>

<router-link> 用来导航显示想展示的组件,本质上就是个超链接标签<a>,有如下属性

:to=“/xxx” --> 去展示对应url对应的组件

active-class=“[class名]” --> 当导航被激活时想展示的class样式

replace --> 切换路由时替换当前浏览器的历史记录

push --> 默认为push,再切换路由时追加浏览器历史记录

1.3.2 路由组件展示<router-view>

<router-view>用于把选择了<router-link>对应的组件展示到<router-view>放置的位置

1.4 简单的路由例子

下方的例子就是一个简单的路由,如果导航被激活,就会显示如图的红色,并在下方展示子组件数据

App.vue

<template>
  <div id="app">
    <ul>
        <li v-for="(item,index) in list" 
            :key="item.id">
        <router-link 
            active-class="router-active" 
            :to="item.path">
        {{ item.name }
        </router-link>
         </li>
    </ul>
    <router-view/>
  </div>
</template>

<script>
export default {
  name: 'App',
  data() {
    return {
        list: [
          { id: 2, name: '人员', path: '/persons'},
          { id: 3, name: '新闻', path: '/news' }
        ],
    }
  }
}
</script>

<style scoped>
    * {
      margin: 0;
      padding: 0;
    }
    #app ul {
      display: flex;
      padding: 0 10px;
    }
    #app ul li {
      width: 100px;
      height: 50px;
      line-height: 50px;
      list-style: none;
      text-align: center;
      border: 1px solid black;
    }
    #app ul li a {
      display: block;
      text-decoration: none;
      font-weight: bold;
      color: #333333;
    }
     .router-active{
      background-color: #e01222;
      color: #fff;
     }
</style>

/router/index.js

import VueRouter from "vue-router"
//引入想要用的组件
import PersonList from "@/pages/PersonList.vue"
import News from "@/pages/News.vue"
const router = new VueRouter({
    routes: [
        {
            path: '/persons',
            component: PersonList
        },
        {
            path: '/news',
            component: News
        }
        
    ]
})
export default router

/pages/News.vue

<template>
    <div>
        <h3>新闻列表</h3>
        <li v-for="item in NewsList" :key="item.id">
            {{item.title}}
        </li>
    </div>
</template>

<script>
    
    export default{		
        name: '',
        data(){
            return{
                NewsList: [
                    {id:'001',title:'新闻1', path: '/new'},
                    {id:'002',title:'新闻2', path: '/new'},
                    {id:'003',title:'新闻3', path: '/new'},
                ]
            }
        },
    }
</script>

/pages/PersonList.vue

<template>
    <div>
        <ul>
            <li v-for="(item) in personList" :key="item.id">
                {{item.id}} - {{ item.pName }} - {{ item.age }}
            </li>
        </ul>
    </div>
</template>

<script>
    export default{		
        name: '',
        data(){
            return{
                personList : [
                    {id:'001',pName:'tom',age:18},
                    {id:'002',pName:'jerry',age:19},
                    {id:'003',pName:'tony',age:12},
                ],
            }
        }
    }
</script>

在这里插入图片描述

在这里插入图片描述

2. 进阶使用

2.1 多级路由

多级路由是在/router/index.js中routes中的对象中配置children属性,在children里配置下一级路由的映射规则

import VueRouter from "vue-router"
const router = new VueRouter({
    routes: [
        {
            path: '/xxx',
            component: xxx,
            //多级路由配置children属性
            children: [
                {
                    path: 'yy',//记住不要加/ 
                    component: yy
                }
            ]
        }
    ]
})
export default router

此时我们访问到配置的这个子路由的<router-link>的 :to 属性应该写完整的路径,即

<router-link :to="/xxx/yy"></router-link>

2.2 $router 和 $route

$route存放着该组件的路由信息,每个路由组件对象都有$route,可以传递接参数等等

$router是vue路由对象,只会存在一个,可以借助this.$router的api实现编程式路由导航

2.3 路由传参

传参有query传参和param传参两种方式,我们通过在路由组件里的 this.$route.[query / param]获取

二者的字符串写法都支持模板字符串,模版字符串用``围起来,里面可以通过 ${变量名} 获取变量,拼接成字符串

2.3.1 query传参

传递参数都是在<router-link>的 to 属性传递,传递方式有字符串写法和对象写法,获取则是通过 this.$route.query.[变量名]

//1.字符串写法
//传递:在<router-link>的to属性通过url传递,即 
			to=“/xx?a=a&b=b”
//2. 对象写法
// to="
{
	path: '/xx',
	query:{
		a:a,
		b:b
	}
}
"
2.3.2 params传参

传递参数都是在<router-link>的 to 属性传递,传递方式有字符串写法和对象写法,获取则是通过 this.$route.params.[变量名]

//1. 字符串写法
to="/xx/a/b"
//这种写法需要在route里匹配路径时占位
// /router/index.js

const router = new VueRouter({
    routes: [
        {
            path: '/xx/:school', // [/:变量名] 实现占位,传多少个参数就占多少位
            component: PersonList
        }    
    ]
})
//2. 对象写法
//这种写法需要配置route的name属性,见文章2.4 路由取名
// 配置 name 和 params
to="{
    name: [路由name属性名,即aa],
    params: {
        a : a,
        b : b
    }
}"

// /router/index.js
// 注意 name、path
const router = new VueRouter({
    routes: [
        {
        	name: 'aa'
            path: 'xx/:a', //占位
            component: PersonList
        }    
    ]
})

2.4 路由取名

我们可以给路由取名,通过 to=“[路由名]” 即可访问

const router = {
    routes: [
        {
        	//取名
        	name: 'aaa',
            path: '/xxx',
            component: xxx,
            //多级路由配置children属性
            children: [
                {
                    path: 'yy',//记住不要加/ 
                    component: yy
                }
            ]
        }
    ]
}
//访问
<router-link :to="aaa"></router-link>

2.5 缓存路由

我们在切换同级路由时,切换走的路由组件会被销毁,切换到的路由组件会被创建,有时候我们希望切换组件时,保留该组件现有的数据,即不销毁掉该路由组件,这就是缓存路由

缓存路由通过<keep-alive>标签的include属性控制,如果想缓存多个路由,则用 :include=“[‘a组件’, ‘b组件’]”,需要在组件里配置name属性,若没配置include则所有都缓存

<keep-alive :include="['xx']">
    <router-view></router-view>
</keep-alive>

2.6 路由组件的生命周期函数

引入: 一个路由组件有定时器,并且keep-alive 了,我们不希望定时器在切换的时候依旧执行

解决上述问题,我们可以通过路由组件的activated、deactivated 两个生命周期函数,在路由组件激活时开始,路由切换时关闭即可,这两个生命周期函数仅在<keep-alive>包含当前组件时才会有

activated 路由组件被激活时激活

deactivated 路由组件被切换的时候激活

2.7 路由守卫

引入 : 有些路由组件需要判断权限,没权限就不给看

2.7.1 全局前置路由守卫

配置在 /router/index.js 里,路由组件的初始化和每次切换时调用

一般用于权限控制

/router/index.js

// to : 目标路由
// from : 从哪个路由切换的,是一个Object对象
// next	: 要切换到哪个路由,是一个Object对象
router.beforeEach((to, from, next) -> {
	//权限验证
	next(); //放行
})
2.7.2 全局后置路由守卫

配置在 /router/index.js 里,路由组件的初始化和每次切换后调用

/router/index.js

// to : 目标路由,是一个Object对象
// from : 从哪个路由切换的,是一个Object对象
//由于是在路由器切换后调用的,所以不需要 next
router.afterEach((to, from) -> {
    
})
2.7.3 独享前置路由守卫

只有前置,没有后置,配置在 /router/index.js 里,存在该独享前置路由守卫的路由组件被激活时触发

/router/index.js

routes = new VueRouter({
{
    path: '/xx',
    beforeEnter:(to, from, next) => {
    	
    	next();//放行
    }
})
2.7.4 组件内路由守卫

配置在路由组件里

beforeRouteEnter() 在切换到该路由组件时调用

beforeRouteLeave() 在离开该路由组件时前调用

//通过路由规则进入时调用
beforeRouteEnter(to, from, next) {
	
	next(); //放行
}
//通过路由规则离开前调用
beforeRouteLeave(to, from, next) {

	next(); //放行
}
2.7.5 路由守卫的执行顺序

如果各种守卫都配置了,

路由组件初始化时,触发顺序如下:

全局前置路由守卫 -> 全局后置路由守卫

组件被激活时,触发顺序如下:

全局前置路由守卫 -> 独享前置路由守卫 -> 组件内路由前置守卫 -> 全局后置路由守卫

组件被切换走时,触发顺序如下:

组件内路由离开守卫 -> 全局前置路由守卫 -> 全局后置路由守卫

2.8 路由器的工作模式

工作模式通过router的mode属性配置,有history 和 hash 两种,默认是hash

hash : 只有#之前的url会随着请求会发给服务器,不会带上路由组件的url

history : 会把我们配置的路由组件的url也带上

打个比方:

// 我们想请求的地址 : https://localhost:8080/students
// 此时,我们在路由组件Person准备发送请求,即此时的url为:  https://localhost:8080/#/person
// 我们发送 /students 的请求
// history : https://localhost:8080/person/students
// hash : https://localhost:8080/person
// 此时,history当前请求不到资源

修改路由的工作模式如下:

const router = new VueRouter({
	mode: ['hash' / 'history'],
	routes: [
		
	]
})

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/753137.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

一文带你彻底搞懂设计模式之单例模式!!由浅入深,图文并茂,超超超详细的单例模式讲解!!

一文带你彻底搞懂设计模式之单例模式&#xff01; 一、什么是单例模式&#xff1f;单例模式分类饿汉式创建单例对象懒汉式创建单例对象 多问一个为什么&#xff1f; 二、为什么要有单例模式&#xff1f;使用单例模式的原因单例模式的应用场景 三、多线程下的单例模式饿汉式懒汉…

【高级篇】InnoDB引擎深入:核心机制与实战优化(十五)

引言 在探索了MySQL集群与分布式技术之后,我们进入了数据库引擎的核心地带——InnoDB。作为MySQL的默认存储引擎,InnoDB凭借其对事务的支持、行级锁定、高效的恢复机制以及复杂的内存管理,成为众多应用场景的首选。本章,我们将深入InnoDB的内部机制,透彻理解锁管理、事务…

【C++】动态内存管理new和delete

文章目录 一、C的内存管理方式二、new和delete的用法1.操作内置类型2.操作自定义内置类型 三、new和delete的底层实现1.operator new和operator delete函数2.new和delete的实现原理 四、定位new表达式五、malloc/free和new/delete的区别 一、C的内存管理方式 之前在C语言的动态…

找不到vcomp140.dll怎么办,总结多种解决方法

​在日常使用电脑的过程中&#xff0c;我们可能会遇到一些错误提示&#xff0c;其中之一就是“vcomp140.dll丢失”。那么&#xff0c;vcomp140.dll是什么&#xff1f;它为什么会丢失&#xff1f;丢失后对电脑有什么影响&#xff1f;又该如何解决呢&#xff1f;本文将详细介绍vc…

leetcode 动态规划(基础版)单词拆分

题目&#xff1a; 题解&#xff1a; 一种可行的dp做法是基于完全背包问题&#xff0c;将s看成是一个背包&#xff0c;wordDict看作是物品&#xff0c;然后往s中放入物品判断最终是否可以变为给定的s即可。这道题和上一题都用到了在dp如何枚举连续子串和状态表示&#xff1a;枚…

一个 API 客户端和一份 TS 学习手册

第75期&#xff1a; Insomnia&#xff1a;超好看的 API 客户端 项目介绍&#xff1a; 一款适用于 GraphQL、REST、WebSockets 和 gRPC 的开源 API 客户端&#xff0c;颜值超高。 跨平台&#xff0c;支持 Mac、Windows 和 Linux。但不支持网页版&#xff0c;需要下载客户端。…

如何借助ai(文心一言)获取tushare的数据

1. 准备工作 确保已安装python &#xff0c;安装Tushare库 和文心一言的地址&#xff08;文心一言&#xff09;&#xff1a; 注册Tushare账号并获取Token&#xff1a;在Tushare官方网站注册账号&#xff0c;并获取个人Token。如下 tushare地址&#xff1a;&#xff08;点击即…

PD快充诱骗芯片工作原理,USB-C充电器出不来电压是什么原因?

一般使用Type-C接口的充电器基本上都是采用新的快充协议——PD快充协议&#xff0c;它不同于以前的USB-A的QC协议&#xff0c;这种协议&#xff0c;默认是没有快充电压输出的&#xff0c;VBUS和GND是0V。 所以&#xff0c;我们可以使用电阻的方式&#xff08;电流小&#xff09…

【Apache Doris】如何实现高并发点查?(原理+实践全析)

【Apache Doris】如何实现高并发点查&#xff1f;&#xff08;原理实践全析&#xff09; 一、背景说明二、原理介绍三、环境信息四、Jmeter初始化五、参数预调六、用例准备七、高并发实测八、影响因素九、总结 本文主要分享 Apache Doris 是如何实现高并发点查的&#xff0c;以…

突破SaaS产品运营困境:多渠道运营如何集中管理?

随着数字化时代的到来&#xff0c;SaaS&#xff08;软件即服务&#xff09;产品已成为企业日常运营不可或缺的工具。然而&#xff0c;在竞争激烈的市场环境下&#xff0c;SaaS产品运营越来越重视多渠道、多平台布局&#xff0c;以更广泛地触及潜在用户&#xff0c;然而&#xf…

《昇思25天学习打卡营第10天 | 昇思MindSporeFCN图像语义分割》

第10天 本节学习了FCN图像语义分割。全卷积网络是用于图像语义分割的一种框架。FCN是首个端到端&#xff08;end to end&#xff09;进行像素级&#xff08;pixel level&#xff09;预测的全卷积网络。FCN有两大明显的优点&#xff1a;一是可以接受任意大小的输入图像&#xff…

2024年跨境电商关键数据统计:市场规模将达到1.976万亿美元

预计2024年跨境电商消费市场规模将达到1.976万亿美元&#xff0c;占全球网上销售总额的31.2%。这一数据无疑展示了跨境电商市场的巨大潜力和迅猛增长趋势。 全球跨境电商的现状与未来 现状 2023年&#xff0c;全球跨境电商市场规模预计达到1.56万亿美元&#xff0c;占全球电子…

JAVA毕业设计145—基于Java+Springboot+vue+uniapp的驾校预约小程序(源代码+数据库+15000字论文)

毕设所有选题&#xff1a; https://blog.csdn.net/2303_76227485/article/details/131104075 基于JavaSpringbootvueuniapp的驾校预约小程序(源代码数据库15000字论文)145 一、系统介绍 本项目前后端分离&#xff0c;分为用户、教练、管理员三种角色 1、用户&#xff1a; …

PHP爬虫类的并发与多线程处理技巧

PHP爬虫类的并发与多线程处理技巧 引言&#xff1a; 随着互联网的快速发展&#xff0c;大量的数据信息存储在各种网站上&#xff0c;获取这些数据已经成为很多业务场景下的需求。而爬虫作为一种自动化获取网络信息的工具&#xff0c;被广泛应用于数据采集、搜索引擎、舆情分析…

unity-特效-雷达扫描效果

使用后处理方式制作 using System; using System.Collections; using System.Collections.Generic; using UnityEngine;public class GlobalScanEffect : MonoBehaviour {public float startScanRange 0;public float maxScanRange 20;public float scanWidth 3;public flo…

洁盟超声波清洗机怎么样?横向测评希亦、洁盟、苏泊尔超声波清洗机谁是实力派

生活中大多数人戴眼镜&#xff0c;但是很多人都不注意眼镜的保养&#xff0c;导致镜片越来越模糊&#xff0c;从而引发多边的状况发生&#xff0c;比如长久戴模糊不清的眼镜&#xff0c;视力会受到影响随之下降。甚至是眼镜长期不清洗&#xff0c;上面的灰尘、细菌会影响眼部健…

极限竞速地平线4卡顿?这样做快速解决地平线4卡顿问题

极限竞速地平线4全新开放式剧情的设计让玩家的每一次行动都能推动游戏的进程。时间、天气和四季的变化&#xff0c;都将在极限竞速地平线4这里得到真实的呈现。玩家将有机会在壮丽的原生4K和HDR画质下&#xff0c;欣赏到英国那湖泊、山谷、城堡和无数美景&#xff0c;体验一段从…

使用 Rustup 管理 Rust 版本

文章目录 安装 Rustup配置镜像源安装 Rustup 安装 RustVS Code插件创建项目代码示例 Rust 官网&#xff1a;https://www.rust-lang.org/zh-CN/Crates 包管理&#xff1a;https://crates.io/Rust 程序设计语言&#xff1a;https://kaisery.github.io/trpl-zh-cn/通过例子学 Rust…

docker 搭建 AI大数据模型 --- 使用GPU

docker 搭建 AI大数据模型 — 使用GPU方式 搭建本地大模型&#xff0c;最简单的方法&#xff01;效果直逼GPT 服务器GPU系统HP580 G8P40Rocky9.2 安装程序AnythingLLM前端界面Open WebUIChatOllamaollama 一、AnythingLLM 介绍 AnythingLLM 是 Mintplex Labs Inc. 开发的一…

根据后端返回的省市区重新封装树结构(省市区通过children表示)

对比图&#xff08;截取部分&#xff09;&#xff1a; 注&#xff1a;先看分步&#xff0c;最后会附上完整代码&#xff08;如果有用&#xff0c;可以给小编点个赞吗&#xff1f;十分感谢&#xff09; 1.首先将前端返回相同的省份只展示一次 const obj {}; let keyList []r…