Vue(十三) 路由、路由嵌套、query、param传参、propos、replace属性。编程式路由导航,特有的生命周期函数,路由守卫

news2024/11/14 14:25:59

文章目录

  • 路由
    • 1. 基本使用
    • 2. 多级(嵌套)路由
    • 3. 路由query传参
    • 4. 命名路由
    • 5. 路由param传参
    • 6. propos属性
    • 7. replace属性
    • 8. 编程式路由导航
    • 9. 缓存路由组件
    • 10. actived,deactived生命周期函数
    • 11. 路由守卫
      • 1、全局路由
      • 2、独享路由
      • 3、组件内路由守卫
    • 12. 路由器工作的两种模式

路由

  • 路由就是一组key-value的对应关系

    • 前端路由: key是路径,value是组件component,用于展示页面内容
    • 后端路由: key是路径,value是函数。后端根据请求路径找到匹配的函数,处理请求。
  • 多个路由,需要经过路由器的管理。路由主要应用于SPA(Single page web application)应用

1. 基本使用

1、安装路由
vue2:npm i vue-router@3
vue3: npm i vue-router@4

2、编写路由器文件:src/router/index.js

// 该文件专门用于创建整个应用的路由器
import VueRouter from 'vue-router'
// About和Home都是路由组件,所以放在文件src/pages下,一般组件则放在src/components里
import About from '../pages/About'
import Home from '../pages/Home'

// 创建并暴露一个路由器
export default new VueRouter({
  routes: [
    {
      path: '/about',
      component: About
    },
    {
      path: '/home',
      component: Home
    }
  ]
})

main.js

import VueRouter from 'vue-router'
import router from './router/index'
Vue.use(VueRouter)
new Vue({
  // 将App组件放入容器中
  render: h => h(App),
  // 添加router配置项
  router,
}).$mount('#app') // 挂载容器

3、实现切换(active-class可配置高亮)
router-link标签实现路由组件的切换,to=...表示要切换的路径,根据路径对应到上边js文件中的路由组件。router-link本质上是a标签。

<router-link class="list-group-item" to="./home" active-class="active">Home</router-link>
 <router-link class="list-group-item" to="./about" active-class="active" >About</router-link

4、指定路由组件展示的位置

 <router-view></router-view>

router-link选择要展示哪个路由组件,将路由组件展示在router-view指定的位置中
在这里插入图片描述
注意:

  1. 路由组件通常存放在pages文件夹,一般组件通常存放在components文件夹。
  2. 通过切换,“隐藏”了的路由组件,默认是被销毁掉的,需要的时候再去挂载。
  3. 每个组件都有自己的$route属性,里面存储着自己的路由信息。
  4. 整个应用只有一个router(即About的router和Home的router是一回事),可以通过组件$router属性获取到。
  5. 项目中有多个router-linkrouter-view时,点击链接,到底跳转到哪一个router-view显示:
    参考博客:Vue中router-link与router-view的对应关系和映射特点

2. 多级(嵌套)路由

要实现的效果:
在这里插入图片描述
Home组件里多了两个组件:News和Message

routes:[
	{
		path:'/about',
		component:About,
	},
	{
		path:'/home',
		component:Home,
		children:[ //通过children配置子级路由
			{
				path:'news', //此处一定不要写:/news
				component:News
			},
			{
				path:'message',//此处一定不要写:/message
				component:Message
			}
		]
	}
]

跳转路径:

<router-link to="/home/news">News</router-link>
  • 由于子级路由在Home组件里,所以Home组件里有两个<router-link>,分别是News和Message。且Home组件里有一个<router-view>用来展示路由组件News或Message的内容。
  • 图中的消息1,消息2是点击Message展示的消息。所以消息1,消息2是Message组件里的内容
<!--Home.vue文件-->
<template>
  <div>
   <router-link to="/home/news" active-class="active">News</router-link>
   <router-link to="/home/message" active-class="active">Message</router-link>
    <!-- 展示组件内容的位置 --> 
    <router-view></router-view> 
  </div>
</template>
<!--Message.vue文件-->
<template>
  <div>
    <ul>
      <li><a href="/message1">message001</a>&nbsp;&nbsp;</li>
      <li><a href="/message2">message002</a>&nbsp;&nbsp;</li>
      <li><a href="/message/3">message003</a>&nbsp;&nbsp;</li>
    </ul>
  </div>
</template>

3. 路由query传参

实现效果:
在这里插入图片描述
Message组件里嵌套Detail组件,点击不同的消息时,将参数传递给Detail组件,Detail组件展示内容。
传递参数:

<!--Message.vue组件-->
<ul>
    <li v-for="m in message" :key="m.id">
     <!-- 跳转路由并携带参数,to的字符串写法 -->
     <router-link :to="`/home/message/detail?id=${m.id}&title=${m.title}`">{{m.title}}</router-link> 
     <!-- 跳转路由并携带参数,to的对象写法 -->
      <router-link
          :to="{
            path: '/home/message/detail',
            query: {
              id: m.id,
              title: m.title,
              }
            }"
          >{{ m.title }}</router-link>
    </li>
</ul>
 <div>
  <!-- Deatil组件展示在这儿 -->
   <router-view></router-view>
 </div>

接收数据

<!--Detail.vue组件-->
 <li>消息编号:{{ $route.query.id }}</li>
 <li>消息标题:{{ $route.query.title }}</li>

4. 命名路由

1、作用:跳转时简化编码,否则嵌套路由多了,路径很长
2、给路由命名

// 给谁起名字,就要把name写在谁的配置项里 
  routes: [
    {
      path: '/home',
      component: Home,
      children: [
        {
          path: 'message', component: Message,
          children: [
            { name: 'xiangqing', 
             path: 'detail', 
             component: Detail }
          ]
        }
      ]
    }
  ]

3、简化跳转

<!--简化前-->
 <router-link to="/home/message/detail">跳转</router-link> 
<!--简化后-->
<router-link :to="{name:'xiangqing'}">跳转</router-link> 
<!--简化后携带参数-->
<router-link
 :to="{
   name: 'xiangqing',
   query: {...},
  }"
>跳转</router-link>

5. 路由param传参

1、配置占位符,声明接收param参数

 {
   path: 'message', component: Message,
   children: [
       // 配置占位符;占位的时候用的title,id;用params取参数的时候就能用title,id
      { name: 'xiangqing', path: 'detail/:id/:title', component: Detail }
   ]
  }

2、传递参数

<!-- 跳转路由并携带参数,to的字符串写法 -->
<router-link :to="`/home/message/detail/${m.id}/${m.title}`">跳转</router-link>
<!-- 跳转路由并携带参数,to的对象写法 -->
<router-link
   :to="{
      name: 'xiangqing',
      params: {
       id: m.id,
       title: m.title,
       },
    }"
>跳转</router-link>

注:使用to的对象写法时,传参用params时,只能用name;而不能用path指定路径

3、接收参数

 $route.params.id
 $route.params.title

6. propos属性

组件中每次读取路由参数时,都是 $route.params...
propos属性的作用是少写重复项,让路由组件更方便的接收到参数。
接收参数的组件设置propos属性

{
	name:'xiangqing',
	path:'detail/:id/:title',
	component:Detail,

	//第一种写法:props值为对象,该对象中所有的key-value的组合最终都会通过props传给Detail组件
        // 缺点:传递的是死数据
	// props: { a: 1, b: 'hello' }

	//第二种写法:props值为布尔值,布尔值为true,则把路由收到的所有params参数通过props传给Detail组件
	// props:true
	
	//第三种写法:props值为函数,该函数返回的对象中每一组key-value都会通过props传给Detail组件,通过propos接收参数时,不需要占位符了
	props($route){
		return {
			id:$route.query.id,
			title:$route.query.title
		}
	}
}

Detail组件接收参数

<li>消息编号:{{ id }}</li>
<li>消息标题:{{ title }}</li> 
...
props: ['id', 'title']

7. replace属性

  1. 作用:路由跳转时操作浏览器历史记录的模式
  2. 浏览器历史记录有两种写入方式:分别为push:追加历史记录,replace:替换当前记录。路由跳转时默认为push
  3. 开启replace模式:<router-link replace...>News</router-link>

8. 编程式路由导航

  • 作用:不借助<router-link>实现路由跳转,让路由跳转更加灵活
  • 实现路由条件,可以采用$router下的几个API
//$router的两个主要API
this.$router.push({
    name: 'xiangqing',
    query: {
        id: m.id,
        title: m.title
    }
})

this.$router.replace({
    name: 'xiangqing',
    query: {
        id: m.id,
        title: m.title
    }
})
// 类似于历史记录的前进后退
this.$router.forward() //前进
this.$router.back() //后退
this.$router.go() //可前进也可后退

比如:
在这里插入图片描述
历史记录默认记录方式为push,所以依次点击:
About -> Home -> News -> Message -> 消息1的push查看 -> 消息2的replace查看 -> 消息3的replace查看

历史记录存储的是:
在这里插入图片描述
前进后退和go都是根据这个历史记录的顺序来进行跳转。比如点后退,则页面变成/home/messages页面

9. 缓存路由组件

作用:<keep-alive> 标签让不展示的路由组件保持挂载、不被销毁,标签里的include属性可用来指定缓存哪个路由组件
语法:

<!-- 如果不指定,则在这里展示的路由组件都被缓存 -->
<keep-alive>  
    <router-view></router-view>
</keep-alive>
<!-- 缓存多个 -->
<keep-alive :include="['News', 'Message']">
    <router-view></router-view>
</keep-alive> 
<!-- 缓存一个 -->
<keep-alive include="News">
    <router-view></router-view>
</keep-alive>

当缓存News组件时,由News组件切换到Message组件。News组件不会被销毁。

//这个函数不执行则证明不会被销毁
beforeDestroy () {
    alert('News组件即将被销毁');
}

注意点:
(1) include里写的是组件名,即创建组件时定义的name属性
在这里插入图片描述
(2)注意</keep-alive>要加在哪里
想要缓存News组件,则应该加载News路由组件展示的区域
在这里插入图片描述

10. actived,deactived生命周期函数

这两个是路由组件独有的生命周期钩子,用于捕获路由组件的激活状态

  • actived:路由组件被激活时触发。
  • deactived:路由组件失活时触发。

比如News组件里的某句话加一个透明度样式设置,采用定时器,透明度不断发生变化。当切换为其他组件时,透明度不再变化,切换回来时,透明度继续发生变化。

如果采用之前的mounted和beforeDestroy函数

<li :style="{ opacity }">透明度变化</li>
<script>
data () {
  return {
      opacity: 1
    }
  },
  mounted () {
    this.timer = setInterval(() => {
      console.log('@');
      this.opacity -= 0.01
      if (this.opacity <= 0) {
        this.opacity = 1
      }
    }, 16)
  },
  beforeDestroy () {
    clearInterval(this.timer)
  },
</script>

但是当News组件设置了缓存,即使切换为别的组件,News组件也不会被销毁,所以计时器仍旧在运行,透明度仍旧在变化。

这种情况下采用activeddeactived十分合适。

activated () {
    this.timer = setInterval(() => {
      console.log('@');
      this.opacity -= 0.01
      if (this.opacity <= 0) {
        this.opacity = 1
      }
    }, 16)
  },
  deactivated () {
    clearInterval(this.timer)
  },

11. 路由守卫

路由器文件router/index.js

const router = new VueRouter({
  routes: [
    {
      name: 'guanyu',
      path: '/about',
      component: About,
      meta: { isAuth: false, title: '关于' }
    },
    {
      name: 'zhuye',
      path: '/home',
      component: Home,
      meta: { isAuth: false, title: '主页' },
      children: [
        { name: 'xinwen', path: 'news', component: News, meta: { isAuth: true, title: '新闻' }, },
        {
          name: 'xiaoxi', path: 'message', component: Message, meta: { isAuth: true, title: '消息' },
        }
      ]
    }
  ]
})

给每个路由的meta配置项存放了key-value键值对;

1、全局路由

  • beforeEach()每次路由切换之前都会调用这个函数,函数里进行一些逻辑处理,判断是否可以跳转之类的
  • afterEach():每次路由切换之后被调用,可用来修改标签页的标题。
  • meta,在这个属性里配置isAuth,方便判断是否要对该路由进行权限控制
// 全局前置路由守卫--初始化的时候被调用,每次路由切换之前被调用
router.beforeEach((to, from, next) => {
  console.log('全局前置路由守卫',to, from);    
  if (to.meta.isAuth) {
    if (localStorage.getItem('school') === 'atguigu') {
      next() //放行,若不调用这个函数,则不进行路由切换
    } else {
      alert('学校名不对,无权限查看');
    }
  } else {
    next()
  }
})
// 全局后置路由守卫--初始化的时候被调用,每次路由切换之后被调用
router.afterEach((to, from) => {
  console.log('全局后置路由守卫');
  console.log(to, from);
  document.title = to.meta.title || '硅谷系统' 
})

在这里插入图片描述

2、独享路由

  • beforeEnter():给某一个路由单独配置
{
  name: 'xinwen', 
  path: 'news', 
  component: News, meta: { isAuth: true, title: '新闻' },
  beforeEnter (to, from, next) {
     if (to.meta.isAuth) {
       if (localStorage.getItem('school') === 'atguigu') {
          next()
       } else {
          alert('学校名不对,无权限查看');
         }
      } else {
        next()
      }
  },
},

3、组件内路由守卫

全局和独享路由守卫都是在路由配置文件里写,组件内路由守卫是在对应的组件内写

// About.vue
//进入守卫:通过路由规则,进入该组件之前被调用
beforeRouteEnter (to, from, next) {
    console.log('About--beforeRouteEnter');
    console.log(to, from);
    next()
},
//进入守卫:通过路由规则,离开该组件时之前
 beforeRouteLeave (to, from, next) {
    console.log('About--beforeRouteLeave');
    console.log(to, from);
    next()
}

注意是通过路由规则进入该组件时,这两个函数才会被调用
不通过路由规则进入该组件的情况,比如:作为一般组件直接被调用
在这里插入图片描述

12. 路由器工作的两种模式

1、hash模式
hash值:对于一个url来说,路径中#后边的内容统称为hash值。hash值不会包含在 HTTP 请求中,即:hash值不会带给服务器。

在这里插入图片描述
hash模式

  • 地址中永远带着#号
  • 兼容性较好
  • 刷新页面时,hash值不会包含在请求里,所以刷新页面发送请求不会出错。但若以后将地址通过第三方手机app分享,若app校验严格,则地址会被标记为不合法。

2、history模式

  • 地址中没有#号在这里插入图片描述
  • 兼容性略差
  • 应用部署上线时需要后端人员支持,解决刷新页面服务端404的问题。(刷新页面时,整个url都会发给服务器会报404错误)

3、设置模式

//index.js,默认是hash模式
const router = new VueRouter({
  mode: 'history',
   ...
})

拓展:
项目打包:npm run build
打包就是将vue文件转为基本的css,js,html等浏览器认识的文件。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

干货含源码!如何用Java后端操作Docker(命令行篇)

目录 干货含源码&#xff01;如何用Java后端操作Docker&#xff08;命令行篇&#xff09; 一、为什么要用后端程序操作Docker 二、安装Docker 1、安装Docker 2、启动Docker 三、使用Java后端操作docker 1、构建docker镜像并生成容器 2、执行完毕后删除容器和镜像 3、在…

怎么删除谷歌浏览器的下载记录

定期删除谷歌浏览器的下载记录&#xff0c;对于保护个人隐私和提升浏览器性能都非常的重要。为了帮助大家安全的进行谷歌浏览器下载记录的清除&#xff0c;本文为大家分享了实用的操作方法&#xff0c;一起来看看吧。 删除谷歌浏览器下载记录的原因说明 1、保护隐私&#xff1…

【算法 动态规划 简单多状态 dp 问题】打家劫舍题型

打家劫舍题型 按摩师 (easy)解题思路代码 打家劫舍II &#xff08;medium&#xff09;解题思路代码 删除并获得点数&#xff08;medium&#xff09;解题思路代码 按摩师 (easy) 题目链接 该题是打家劫舍的变形 解题思路 状态表示 分析: 注意题目, 对于当天的预约, 可以接受…

车辆远控功能自动化测试方案:打造高效可靠的测试流程

随着汽车逐步走向智能化、网联化&#xff0c;整车的功能已经不再局限于驾驶员在车内进行本地操作。在远离车辆时&#xff0c;驾驶员也可以通过手机APP下发控制指令来实现对车辆的远程控制。 近几年&#xff0c;伴随远控功能项不断增多&#xff0c;其功能逻辑也越来越复杂&…

python开发--信息的增删改

部门信息的增删改 1. 增加 点击新建部门 跳转到新建部门页面&#xff1a;http://127.0.0.1:8000/depart/add/ 在views.py里面增加如下代码&#xff0c;可以将用户输入的信息添加到数据库中 def depart_add(request):if request.method GET:return render(request, depart…

STL之my_list容器

前言&#xff1a;各位老铁好久不见了&#xff0c;今天分享的知识是自己实现一个简单的list容器&#xff0c;为什么我先跳过vector容器的自我实现呢&#xff1f;我个人觉得vector相对于list的自我实现简单一点&#xff0c;所以今天先分享实现my_list的知识 我们要实现my_list&a…

machine learning - 2

泛化误差 也可以认为是预测时的误差。 训练误差 并不是越小越好&#xff0c;太小会过拟合。 获得测试集合的方法&#xff1a; 1&#xff09;&#xff1a; 2&#xff09;&#xff1a;例如&#xff1a;k-折交叉验证法&#xff0c; 就的每k个数据取一个座位测试集 3&#xff0…

nginx容器映射配置文件后,启动一直报错提示:failed (13: Permission denied)的排查

问题现象&#xff1a; 使用harbor 的install.sh 创建docker-compose之后&#xff0c;出现nginx容器一直重启。 查看日志发现是&#xff1a;配置文件无权限。报错信息如下&#xff1a; Sep 2 16:43:13 172.28.0.1 nginx[1344]: 2024/09/02 08:43:13 [emerg] 1#0: open() “/e…

网站网站建设公司用什么

随着互联网的飞速发展&#xff0c;网站已经成为企业的重要门面和宣传工具。为了在网上展示自己的品牌形象和吸引更多的客户&#xff0c;越来越多的企业选择找专业的网站建设公司进行网站建设。那么&#xff0c;网站建设公司主要使用什么技术和方法呢&#xff1f; 首先&#xff…

四、基本电路设计笔记——4.1 DC-DC稳压电路

目录 4.1 DC-DC稳压电路 4.1.1 基于MT2492的DC-DC稳压电路 &#xff08;1&#xff09;芯片参数 &#xff08;2&#xff09;芯片引脚 &#xff08;3&#xff09;输出电压设置 4.1.2 基于MT2499A的DC-DC稳压电路 &#xff08;1&#xff09;芯片参数 &#xff08;2&#xf…

【Redis】Redis 主从复制

文章目录 1 前言2 主从模式介绍3 配置 Redis 主从结构3.1 建立复制3.2 断开复制3.3 其他特性3.4 拓扑结构 4 Redis 主从复制原理4.1 复制过程4.2 PSYNC 数据同步4.3 PSYNC 运行流程 5 主从复制流程5.1 全量复制流程5.2 部分复制流程5.3 实时复制流程 1 前言 分布式系统中存在一…

鸿誉移民:定制化移民服务,吹响全球高效率移民的嘹亮号角!

鸿誉移民&#xff1a;定制化移民服务&#xff0c;吹响全球高效率移民的嘹亮号角&#xff01; 作为国内知名海外移民服务机构&#xff0c;鸿誉移民历经多年行业沉淀&#xff0c;拥有着极其丰富的移民咨询以及移民办理经验&#xff0c;并以咨询及时精准&#xff0c;签证快捷、通…

Bean 的实例化(创建 | 获取)

Spring为Bean提供了多种实例化方式&#xff0c;包括如下4种方式&#xff1a; 第一种&#xff1a;通过构造方法实例化第二种&#xff1a;通过简单工厂模式实例化第三种&#xff1a;通过factory-bean实例化&#xff08;工厂方法模式实例化&#xff09;第四种&#xff1a;通过Fact…

智能未来:低代码与AI如何重塑企业应用开发

引言 在当今瞬息万变的商业环境中&#xff0c;企业面临着前所未有的挑战与机遇。数字化转型已经成为各行各业的必然趋势&#xff0c;而在这一过程中&#xff0c;应用开发的效率与智能化程度成为企业竞争力的重要衡量标准。传统的开发模式往往需要大量的时间和资源&#xff0c;而…

【Godot4.3】基于ShapePoints的Polygon2D扩展

概述 这同样是来自2023年7月份的一项实验性工作&#xff0c;基于最初版本的ShapePoints静态函数库&#xff0c;实现了对Polygon2D节点的扩展&#xff0c;用于创建参数化图形的Polygon2D节点。 Polygon2D节点本身只能通过顶点绘制工具&#xff0c;创建很随意的多边形。通过Sha…

MySQL数据库管理系统下载安装

一. MySQL概述&#xff1a; 1.数据库相关概念 数据库&#xff1a;存储数据的仓库&#xff0c;数据是有组织地进行存储&#xff08;DataBase 简DB&#xff09;数据库管理系统&#xff1a;操纵和管理数据库的大型软件 &#xff08;DataBase Management System 简DBMS)SQL:操…

一分钟创建自己的分班查询系统,家长扫码即可进群

开学后&#xff0c;老师们的忙碌也达到了顶峰。整理教材、准备课程计划、布置教室&#xff0c;这些工作已经让人应接不暇&#xff0c;更别提还要处理分班事宜。以往&#xff0c;老师们需要一个个通知家长分班结果&#xff0c;这不仅耗时耗力&#xff0c;还容易出错。家长们也常…

​数字IC设计基本概念之多时钟设计​

当设计中使用了多个时钟时&#xff0c;这些时钟域之间的关系可能是synchronous、asynchronous或者exclusive的。如下所示&#xff1a; Synchronous&#xff1a; Asynchronous&#xff1a; Exclusive&#xff1a; 需要人为地指定设计中时钟之间的关系&#xff0c;EDA工具才能正…

燃油车淘汰倒计时开始了?

文 | AUTO芯球 作者 | 璇子 新能源车要取代燃油车了&#xff1f; 油车车主先别喷啊 就在上个月 新能源乘用车月销量数据一经公布 我一看 渗透率居然达到了惊人的51% 啥概念啊 如果卖100台车 51台都是新能源 其他49台才是燃油车 看到这数据 有好多看热闹的人就在说 …

Vue组件:创建组件、注册组件、使用组件

1、创建组件 组件&#xff08;component&#xff09;是 Vue.js 最强大的功能之一。通过开发组件可以封装可服用的代码&#xff0c;将封装好的代码注册成标签&#xff0c;扩展 HTML 元素的功能。几乎任意类型应用的界面都可以抽象为一个组件树&#xff0c;而组件树可以用独立可…