Vue——【路由】
一、什么是路由
1、VueRouter的作用
VueRouter是Vue.js官方提供的路由管理器,用于实现单页面应用中的路由跳转功能。通过VueRouter,我们可以声明式地定义页面之间的导航关系,然后根据这些定义的规则,VueRouter会监听浏览器的URL变化,并且根据定义的规则匹配到对应的组件进行渲染。同时,VueRouter还支持路由参数、动态路由、嵌套路由等功能,能够满足复杂的路由需求。通过使用VueRouter,我们可以实现页面的切换、前进、后退,还可以实现动态加载组件,提高应用的性能和用户体验。
2、VueRouter的基本概念
路由表示一个映射关系,即 URL 路径到组件的映射。在 VueRouter 中,一个路由对象通常包含两个主要部分:path
(路径)和 component
(组件)。
二、Vue路由的主要特点包括:
1. 嵌套路由:可以根据页面的层次结构定义嵌套的路由规则,方便管理复杂的页面布局和导航。
2. 动态路由:可以定义带有参数的路由规则,根据不同的参数来展示不同的页面内容。
3. 路由懒加载:可以按需加载页面组件,提高应用程序的性能和加载速度。
4. 导航守卫:可以在路由跳转前后执行一些逻辑操作,比如检查用户是否登录等。
5. 编程式导航:可以通过编写代码动态地进行页面导航,而不是通过用户的手动点击链接。
三、VueRouter的基本用法
1、创建路由实例
创建路由实例大概有以下几个步骤:
1.1安装VueRouter
npm install vue-router
或者
yarn add vue-router
1.2在index.js中引入vue和vueRouter
import Vue from "vue";
import VueRouter from "vue-router";
1.3在index.js中通知vue使用Router
Vue.use(VueRouter);
1.4定义路由
每个路由应该映射一个路径到一个组件。这些路由被定义在一个数组内,数组的每个元素都是一个路由记录(route record)。
const routes = [
{
path: '/',
name: 'Home',
component: () => import('@/components/Home.vue') // 懒加载组件
},
{
path: '/about',
name: 'About',
// component: About, // 如果不是懒加载,可以直接这样引入
component: () => import('@/components/About.vue') // 懒加载组件
}
// 定义更多的路由...
];
1.5创建路由实例
const router = new Router({
mode: 'history', // 使用HTML5 History模式
base: process.env.BASE_URL, // 基本路径,从环境变量中获取
routes // 简写,相当于 routes: routes
});
1.6导出路由实例
export default router;
1.7在Vue实例中使用路由实例
在你的Vue应用入口文件(如src/main.js
)中,引入并使用导出的路由实例。
import Vue from 'vue';
import App from './App.vue';
import router from './router'; // 引入路由实例
new Vue({
router, // 将路由实例注入到Vue实例中
render: h => h(App),
}).$mount('#app');
2、定义路由映射的基本步骤
2.1引入组件:
首先,你需要引入你想要通过路由访问的Vue组件。
// 引入组件
import Home from '@/components/Home.vue';
import About from '@/components/About.vue';
2.2定义路由:
然后,创建一个路由数组,并在其中定义你的路由。每个路由都是一个对象,它至少包含path
和component
属性。
// 定义路由
// 每个路由应该映射一个路径到一个组件
const routes = [
{
path: '/',
name: 'Home',
component: Home
},
{
path: '/about',
name: 'About',
// 可以使用异步组件来优化加载时间
component: () => import('@/components/About.vue')
}
2.3创建路由实例:
使用Vue Router的构造函数new Router()
,并传入一个包含routes
属性的配置对象来创建路由实例。routes
属性的值就是你之前定义的路由数组。
2.4导出路由实例:
最后,将路由实例导出,以便在你的Vue应用中使用它。
3、将路由实例挂载到Vue实例上
Vue CLI项目中的main.js示例 :
import Vue from 'vue';
import App from './App.vue';
import router from './router';
Vue.config.productionTip = false;
new Vue({
router, // 将路由实例传递给Vue实例
render: h => h(App) // 渲染App组件
// $mount('#app') 这一行在Vue CLI项目中是省略的
});
4、路由链接和路由视图的使用
路由链接(通常使用<router-link>
组件)和路由视图(<router-view>
组件)是Vue Router中两个非常核心的组件,它们分别用于导航和渲染页面内容。
4.1路由链接(<router-link>
)
<router-link>
是Vue Router提供的一个组件,用于创建导航链接。当用户点击这些链接时,它们会触发Vue Router的导航逻辑,而不是重新加载页面。<router-link>
组件会渲染成标准的<a>
标签,但是你可以通过tag
属性来改变它渲染成的标签类型(比如<li>
、<span>
等)。
<router-link to="/">Home</router-link>
<router-link :to="{ name: 'about' }">About</router-link>
在上面的例子中,第一个<router-link>
使用了字符串来指定路径(/
),而第二个则使用了对象语法,其中name
属性指定了路由的名称(这要求你在路由配置中为每个路由指定一个唯一的name
)。
注意:tag属性的使用:
<router-link to="/foo" tag="li">Foo</router-link>
4.2路由视图(<router-view>
)
<router-view>
是Vue Router的另一个组件,它用于渲染匹配到的路由组件。你可以把它想象成一个占位符,Vue Router会根据当前的路由路径来决定渲染哪个组件到这个占位符的位置,也就是你需要让目标组件在哪里展示,就将这个路由视图添加到哪里。
<template>
<div id="app">
<header>
<router-link to="/">Home</router-link>
<router-link to="/about">About</router-link>
</header>
<main>
<!-- 路由视图,用于渲染匹配到的组件 -->
<router-view></router-view>
</main>
</div>
</template>
在上面的例子中,当用户点击<router-link>
导航链接时,Vue Router会更新URL并查找匹配的路由。一旦找到匹配的路由,它就会将对应的组件渲染到<router-view>
所在的位置。
4.3小结
<router-link>
用于创建导航链接,用户点击后会触发Vue Router的导航逻辑。<router-view>
是路由组件的占位符,Vue Router会根据当前路由渲染相应的组件到这个位置。
四、路由参数和动态路由
1、路由参数
Vue路由参数是Vue Router中用于在路由跳转时传递数据的一种方式。这些参数可以是查询参数(query)或动态路由参数(params),它们允许在路由的URL中携带额外的信息,并在目标组件中访问这些信息。
1.1 查询参数(Query Parameters)
查询参数通过URL的查询字符串(即URL中?
后面的部分)传递。它们类似于HTTP GET请求中的查询参数,可以在URL中直接看到。
1.1.1传递查询参数
在<router-link>
组件中,可以通过to
属性的对象形式传递查询参数。
<router-link :to="{ path: '/user', query: { id: 123, name: 'John' }}">User</router-link>
1.1.2接收查询参数
可以使用this.$router.query来接收查询参数
export default {
mounted() {
console.log(this.$route.query.id); // 输出: 123
console.log(this.$route.query.name); // 输出: John
}
}
1.2. 动态路由参数(Dynamic Route Parameters)
动态路由参数通过URL中的动态片段(即路径中的:参数名
部分)传递。它们通常用于构建具有不同参数的URL,而不是将所有信息都放在查询字符串中。
1.2.1定义动态路由
const routes = [
{ path: '/user/:id', component: User }
];
1.2.2传递动态路由参数
在<router-link>
组件中,可以直接在to
属性的路径中指定动态路由参数的值。
<router-link :to="'/user/' + userId">User</router-link>
1.2.3接收动态路由参数
在目标组件中,可以通过$route.params
对象访问这些动态路由参数.但在大多数情况下,对于直接定义的动态路由参数,我们直接使用$route.params
即可。然而,对于命名路由和子路由中的params
参数,它们实际上是通过props
属性传递给子组件的,而不是直接通过$route.params
访问。
2、动态路由
把匹配到的所有路由,全部映射到同一个组件
2.1、动态路由
使用路由表配置传递参数
使用动态路由,首先需要在index.js中定义配置动态路由参数
path字段中配置动态路径参数,以冒号开头
{
path: '/detail/:id',
component: () => import('@/components/listchild.vue')
},
这里的“ component: () => import('@/components/listchild.vue')”采用按需引入的方式
在路由链接处使用:to的动态绑定形式在<router-link>中将参数绑定,当路由被激活使用时,将对应的参数传递到目标组件
<router-link :to='"/detail/"+item.id'>路由链接</router-link>
在目标组件中可以使用"console.log(this.$route.params.id)"打印出对应传递的参数
2.2动态路由的传参方式
动态路由的传参有两种,一种是params传参,一种是query传参,接下来我们用一个例子来仔细探讨以下这两种方式
首先我们先创建一个商品展示的组件命名为list.vue,我们使用这个组件展示商品,再创建一个组件命名为listchild.vue,这个组件我们用来展示商品详细信息,之后的操作则是将所有的商品路由映射到listchild组件上实现动态路由传参
2.2.1params传参
list.vue结构:
<template>
<div class="list-content">
<ul class="list">
<li class="item" v-for="item in proList" :key="item.id">
<!-- 通过params传递参数 -->
<router-link :to='{name:"detail" , params:{id:item.id}}'>
<img :src="item.img">
<span>{{ item.title }}---{{ item.price }}</span>
</router-link>
</li>
</ul>
</div>
</template>
在list.vue中使用:to以对象方式动态链接路由
index.js结构
//通过params传递参数
{
path: '/detail/:id',
name: 'detail',//命名路由
component: () => import('@/components/listchild.vue')
},
使用命名路由识别定义的路由,传递参数
注意:
在路由表中的目标路由的path路径中如果没有配置id,当我们刷新详情页面的时候,传递的参数会丢失,因此我们需要在使用的时候在路由表的目标路径中的path字段添加:id
具体参数是否传递,我们可以在目标组件中使用console.log(this.$route.params.id)来接收打印查看,具体代码实现:
export default{
created(){
console.log(this.$route.params.id)
}
}
</script>
2.2.2query传参
index.js
// query传参
{
path: '/detail',
name: 'detail',//命名路由
component: () => import('@/components/listchild.vue')
},
list.vue
<!-- query传递参数 -->
<router-link :to='{path:"/detail" , query:{id:item.id}}'>
<img :src="item.img">
<span>{{ item.title }}---{{ item.price }}</span>
</router-link>
同样的,参数是否传递需要使用console.log(this.$route.query.id)
<script >
export default{
created(){
console.log(this.$route.query.id)
}
}
</script>
2.3小结【params和query的区别】
1)params只能配合name使用,否则参数会丢失,解决参数丢失的方法:在路由表中的path中配置动态id即可,query配合path和name都可以使用
2)params在地址栏中不显示参数信息,当然不显示的前提是没有在path中配置动态id,query显示传递的参数信息
3)接收参数的方式不同:params使用this.$route.params接收,query使用this.$route.query接收
2.4$route和$router的区别
$route:每个组件的$route是不同的,包含的是当前路由的相关配置信息
$router是整个应用的路由配置信息的集合,整个应用是由一个
五、props解耦
在Vue中,
props
是父组件向子组件传递数据的一种方式。有时候,直接在子组件中使用this.$props.someProp
来访问这些属性可能会让模板或计算属性变得冗长且难以阅读。为了简化这个过程,Vue提供了一种称为“props解耦”(props destructuring)的技术,它允许你将props
解构到组件的局部作用域中。
使用props解耦,你可以直接在组件的方法、计算属性或模板中使用props的值,而不需要每次都通过this.$props
来访问它们。
接下来我们来看三种模式【布尔模式 / 对象模式 / 函数模式】
1、布尔模式
在路由配置表中设置props属性为true,此时将会默认将$route.params数据传给组件,组件需要通过自身的props属性取出params中的属性,以props的形式传递给目标组件
路由表配置:
{
path: '/detail/:id',
name: 'detail',//命名路由
props: true,
component: () => import('@/components/listchild.vue')
},
路由链接:
<router-link :to='{name:"detail" , params:{id:item.id}}'>
<img :src="item.img">
<span>{{ item.title }}---{{ item.price }}</span>
</router-link>
目标组件:
props:['id'],
使用props接收,可以使用插值表达式释放参数的值
注意:props如果是true时只能和params配合使用,query无法完成传递
2、对象模式
如果props是一个对象,其下所有属性均会被传入组件,需要注意的是当前props必须是静态的【固定的信息】
路由表配置:
{
path: '/detail/:id',
name: 'detail',//命名路由
props: {
id: 1,
username: '张三'
},
component: () => import('@/components/listchild.vue')
},
路由链接:
<router-link :to='{name:"detail" , params:{id:item.id}}'>
<img :src="item.img">
<span>{{ item.title }}---{{ item.price }}</span>
</router-link>
目标组件接收:
props:['id','username'],
注意,只能传递静态数据
3、函数模式
props也可以是一个函数的返回值,
路由配置
//函数模式
{
path: '/detail/:id?/:title?',
name: 'detail',//命名路由
props(route) {
return {
id: route.params.id,
title: route.params.title
}
},
component: () => import('@/components/listchild.vue')
},
路由链接
<router-link :to='{name:"detail" , params:{id:item.id,title:item.title}}'>
<img :src="item.img">
<span>{{ item.title }}---{{ item.price }}</span>
</router-link>
目标组件
props:['id','title'],
六、结语
今天的分享就到这里了,如果您觉得这篇文章还不错,请点赞、分享给更多的朋友吧!同时,也欢迎关注我的博客,获取更多精彩内容。