037_路由-query参数
笔记


蓝色的是News组件,红色的是Detail组件

导航区和展示区

在 vue 里面,路由传参有两种参数 query 和 params

query传参就是在 如下绿色的路由跳转的地方加?,绿色是路由的具体规则路径

我们在路由规则后面加?然后在传具体参数,如下所示

a为key,哈哈为value,多组之间用&分割


用query将 数据传给了 Detail 组件

Detail 开始接收数据了 以前讲路由的时候就说了 route 是路由,router是路由器。

route 是路由 你有什么路径,我给你看什么组件。
router 是路由器 路由器是管理一个一个路由的

useRoute 是一个 hooks 我们还写了 useDog useSum





模板字符串
<ul>
<li v-for="news in newsList" :key="news.id">
<RouterLink :to="`/news/detail?id=${news.id}&title=${news.title}&content=${news.content}`">
{{ news.title }}
</RouterLink>
</li>
</ul>
模板字符串:
:to="`/news/detail?id=${news.id}&title=${news.title}&content=${news.content}`"
绿色为起始标签,中间红色的[{{news.title}}]是标签体,粉色的[:to="{}"]为标签属性

v-for标签内news当然可以使用


query传参的第一种写法 src/pages/News.vue
<RouterLink :to="`/news/detail?id=${news.id}&title=${news.title}&content=${news.content}`">
{{ news.title }}
</RouterLink>
query传参的第二种写法 src/pages/News.vue
<RouterLink
:to="{
path:'/news/detail',
query:{
id: news.id,
title: news.title,
content: news.content
}
}">
{{ news.title }}
</RouterLink>


响应式对象参数直接解构,肯定出问题,会丢失响应式

你从一个响应式对象身上直接解构属性,属性就此失去响应式,如果你不响失去响应式,你就直接引入 toRes(),直接用toRefs()包裹一下属性,就不会失去原来数据的响应式属性了

此时的query也不对啊,还需要路由的 props 配置

有了 props,就可以轻松把query干掉

能让你干干净净的写 id,title,content等属性

_路由-query参数 实现代码如下
1, src/pages/Detail.vue
<template>
<ul class="news-list">
<li>编号: {{ query.id }}</li>
<li>标题: {{ query.title }}</li>
<li>内容: {{ query.content }}</li>
<!-- <li>编号: {{ $route.query.id }}</li>
<li>标题: {{ $route.query.title }}</li>
<li>内容: {{ $route.query.content }}</li> -->
</ul>
</template>
<script setup lang="ts" name="Detail">
// console.log('创建');
import { useRoute } from 'vue-router';
import { toRefs } from 'vue';
let route = useRoute();
// 解构query赋值给query对象
let {query} = toRefs(route);
// console.log('@', route);
</script>
<style scoped>
.news-list {
list-style: none;
padding-left: 20px;
}
.news-list>li {
line-height: 30px;
}
</style>
2, src/pages/News.vue
<script setup lang="ts" name="News">
/*! @file
*******************************************************
<PRE>
文件实现功能 : 新闻详情页面
作 者 : mary
版本 : 1.0
-------------------------------------------------------
备注 : -
-------------------------------------------------------
修改记录 :
日期 版本 修改人 修改内容
2025/6/18 1.0 mary 创建
</PRE>
******************************************************/
import { reactive } from 'vue'
import {RouterView,RouterLink} from 'vue-router'
// defineOptions({name: ''})
//====================================================
// == 类型定义
const newsList = reactive([
{id:'zg01',title:'很好的抗癌食物',content:'西兰花'},
{id:'zg02',title:'如何一夜暴富',content:'学IT'},
{id:'zg03',title:'震惊,万万没想到',content:'明天是周一'},
{id:'zg04',title:'好消息!好消息!',content:'快过年了'},
])
//====================================================
// == 初始化
//====================================================
//== 事件处理
</script>
<template>
<div class="news">
<!-- 导航区 -->
<ul>
<li v-for="news in newsList" :key="news.id">
<!-- 第一种写法: -->
<!-- <RouterLink :to="`/news/detail?id=${news.id}&title=${news.title}&content=${news.content}`">
{{ news.title }}
</RouterLink> -->
<!-- 第二种写法: -->
<RouterLink
:to="{
// name: 'detail', // 路由名称,可以不写,默认就是当前路由的name属性值
path:'/news/detail', // 路由路径,可以不写,默认就是当前路由的path属性值
query:{
id: news.id,
title: news.title,
content: news.content
}
}">
{{ news.title }}
</RouterLink>
</li>
</ul>
<!-- 展示区 -->
<div class="news-content">
<RouterView></RouterView>
</div>
</div>
</template>
<style scoped>
/*新闻*/
.news {
padding: 0 20px;
display: flex;
justify-content: space-between;
height: 100%;
}
.news ul {
margin-top: 30px;
/* list-style: none; 隐藏 ul 小圆点*/
padding-left: 10px;
}
.news li::marker {
/* ul 小圆点样式 */
color: #64967E;
}
.news li>a {
font-size: 18px;
line-height: 40px;
text-decoration: none;
color: #64967E;
text-shadow: 0 0 1px rgb(0, 84, 0);
}
.news-content {
width: 70%;
height: 90%;
border: 1px solid;
margin-top: 20px;
border-radius: 10px;
}
</style>
3, src/router/index.ts
// 创建一个路由器,并暴露出去
// 第一步: 引入vue-router模块的createRouter方法
import {createRouter,createWebHistory,createWebHashHistory} from 'vue-router'
// 第三步:引入一个一个可能要呈现的组件,也就是页面组件
import Home from '@/pages/Home.vue'
import News from '@/pages/News.vue'
import About from '@/pages/About.vue'
import Detail from '@/pages/Detail.vue'
// 第二步: 创建路由器
const router = createRouter({
history:createWebHistory(), // 路由器的工作模式
// history:createWebHashHistory(), // 路由器的工作模式
routes:[ // 一个一个路由规则 路由规则数组
{
path: "/",
redirect: "/home" // 重定向
},
{
name:'home',
path:'/home',
component:Home
},
{
name:'news',
path:'/news',
component:News,
// 添加一个子集属性children,在里面写子路由规则数组
children:[ // 子路由规则数组 子集路由前不需要写'/',否则会找不到路径
{
name:'detail',
path:'detail',
component:Detail
},
]
},
{
name:'about',
path:'/about',
component:About
},
]
})
// 第四步: 把创建的路由器暴露出去
export default router;


038_路由-params参数
备注1: 传递 params 参数时,若使用 to 的对象写法,必须使用 name 配置项,不能用path
备注2: 传递 params 参数时,需要提前在规则中占位。
params参数
1, 传递参数
<!--跳转并携带params参数(to的字符串写法)-->
<!-- params传参的第一种写法 -->
<RouterLink :to="`/news/detail/${news.id}/${news.title}/${news.content}`">
{{ news.title }}
</RouterLink>
<!--跳转并携带params参数(to的对象写法)-->
<!-- params传参的第二种写法 -->
<RouterLink
:to="{
name:'detail',
params:{
id: news.id,
title: news.title,
content: news.content
}
}">
{{ news.title }}
</RouterLink>
2, 接收参数
import { useRoute } from 'vue-router';
const route = useRoute();
console.log(route);
备注1: 传递 params 参数时,若使用 to 的对象写法,必须使用 name 配置项,不能用path
备注2: 传递 params 参数时,需要提前在规则中占位。
笔记






params传参 直接在路径'/news/detail/'后添加你要传的参数,如下图所示

在 params 里面红色的'/news/detail'为路径,绿色的 '/哈哈/您好/嘿嘿' 是params的传参。

params 返回没有这样的路由规则,找不到与之对应的,你心里明白'/哈哈/您好/嘿嘿' 是params的传参,但是路由的规则不明白


路由规则不明白,params的传参,继续找,就没有找到,就报警了,所以对于params你确实可以这样写传参,但是你必须提前到路由里面去占位,比如 "path:'detail/:id/:title/:content',"


params参数原理:拿到浏览器上的路径去路由中去找去匹配

'/哈哈/您好/嘿嘿' 是params的传参,去对应的路由寻找,'哈哈,您好,嘿嘿'他们都是参数

接收参数


query传参必须是 key=value还得通过&链接

query 传参路径里面能体现传参,Detail也能正常跳转

params传参的第一种方式:params传参,在router/index.js中配置路由时,使用动态路径参数 :id,:title,:content 代码如下
{
name:'news',
path:'/news',
component:News,
// 添加一个子集属性children,在里面写子路由规则数组
children:[ // 子路由规则数组 子集路由前不需要写'/',否则会找不到路径
{
name:'detail',
path:'detail/:id/:title/:content',
component:Detail
},
]
},
params传参的第一种写法 src/pages/News.vue
<ul>
<li v-for="news in newsList" :key="news.id">
<RouterLink :to="`/news/detail/${news.id}/${news.title}/${news.content}`">
{{ news.title }}
</RouterLink>
</li>
</ul>
params传参的第二种写法 src/pages/News.vue
params传参只能用name传参,不能用path传参 不能传对象和数组 路由(src/router/index.ts)里面传什么参数,接收(src/pages/Detail.vue)的时候就得写什么参数
params传参 必须做三件事情
1,路由传参:占位 src/router/index.ts
{
name:'news',
path:'/news',
component:News,
// 添加一个子集属性children,在里面写子路由规则数组
children:[ // 子路由规则数组 子集路由前不需要写'/',否则会找不到路径
{
name:'detail',
path:'detail/:id/:title/:content',
component:Detail
},
]
},
2, src/pages/News.vue 导航传参:
<!-- 导航区 -->
<ul>
<li v-for="news in newsList" :key="news.id">
<!-- params传参的第一种方式:params传参,在router/index.js中配置路由时,使用动态路径参数 :id -->
<!-- params传参的第二种方式:params传参,在router/index.js中配置路由时,使用占位符 -->
<!-- params传参的第一种写法 -->
<!-- <RouterLink :to="`/news/detail/${news.id}/${news.title}/${news.content}`">
{{ news.title }}
</RouterLink> -->
<!-- params传参的第二种写法 -->
<RouterLink
:to="{ // 只能用name传参,不能用path传参 不能传对象和数组
name:'detail',
params:{
id: news.id,
title: news.title,
content: news.content
}
}">
{{ news.title }}
</RouterLink>
</li>
</ul>
3, 接收参数: 去 src/pages/Detail
原则:路由(src/router/index.ts)里面传什么参数,接收(src/pages/Detail.vue)的时候就得写什么参数
<template>
<ul class="news-list">
<li>编号: {{ route.params.id }}</li>
<li>标题: {{ route.params.title }}</li>
<li>内容: {{ route.params.content }}</li>
</ul>
</template>
<script setup lang="ts" name="Detail">
import { useRoute } from 'vue-router';
const route = useRoute();
console.log(route);
</script>
动态路由参数 :id/:title/:content? 表示可选的动态路由参数,也就是可有可无的动态路由参数
可选的动态路由参数 在参数后面添加? 就可以实现
{
name:'news',
path:'/news',
component:News,
// 添加一个子集属性children,在里面写子路由规则数组
// 动态路由参数 :id/:title/:content? 问号表示可选的动态路由参数,也就是可有可无的动态路由参数
children:[ // 子路由规则数组 子集路由前不需要写'/',否则会找不到路径
{
name:'detail',
path:'detail/:id/:title/:content?',
component:Detail
},
]
},
params 接收参数的写法 src/pages/Detail.vue
<template>
<ul class="news-list">
<li>编号: {{ route.params.id }}</li>
<li>标题: {{ route.params.title }}</li>
<li>内容: {{ route.params.content }}</li>
</ul>
</template>
<script setup lang="ts" name="Detail">
import { useRoute } from 'vue-router';
const route = useRoute();
console.log(route);
</script>
query传参 必须做三件事情
1, 去 src/router/index.ts 配置路由项目
{
name:'news',
path:'/news',
component:News,
children:[ // 子路由规则数组 子集路由前不需要写'/',否则会找不到路径
{
name:'detail',
path:'detail', // query传参 动态路由参数
// path:'detail/:id/:title/:content?',//params传参 动态路由参数
component:Detail,
props(route) {
return route.query
}
},
]
},
2, 去 src/pages/News.vue
<RouterLink
:to="{
path:'/news/detail',
// name:'detail',
query:{
id: news.id,
title: news.title,
content: news.content
}
}">
{{ news.title }}
</RouterLink>
3, 去 src/pages/Detail.vue 添加如下代码
<script setup lang="ts" name="Detail">
defineProps(['id', 'title', 'content'])
</script>



如果是query参数,绿色箭头的地方既可以用name写法,也可以用path写法

如果是params参数,绿色箭头的地方只能用name写法



params占位的时候是什么名,到接收的地方就是什么名




_路由-params参数 实现代码如下
1, src/pages/News.vue
<template>
<div class="news">
<!-- 导航区 -->
<ul>
<li v-for="news in newsList" :key="news.id">
<!-- params传参的第一种方式:params传参,在router/index.js中配置路由时,使用动态路径参数 :id -->
<!-- params传参的第二种方式:params传参,在router/index.js中配置路由时,使用占位符 -->
<!-- params传参的第一种写法 -->
<!-- <RouterLink :to="`/news/detail/${news.id}/${news.title}/${news.content}`">
{{ news.title }}
</RouterLink> -->
<!-- params传参的第二种写法 -->
<RouterLink
:to="{
name:'detail',
params:{
id: news.id,
title: news.title,
content: news.content
}
}">
{{ news.title }}
</RouterLink>
</li>
</ul>
<!-- 展示区 -->
<div class="news-content">
<RouterView></RouterView>
</div>
</div>
</template>
<script setup lang="ts" name="News">
import { reactive } from 'vue'
import {RouterView,RouterLink} from 'vue-router'
const newsList = reactive([
{id:'zg01',title:'很好的抗癌食物',content:'西兰花'},
{id:'zg02',title:'如何一夜暴富',content:'学IT'},
{id:'zg03',title:'震惊,万万没想到',content:'明天是周一'},
{id:'zg04',title:'好消息!好消息!',content:'快过年了'},
])
</script>
<style scoped>
/*新闻*/
.news {
padding: 0 20px;
display: flex;
justify-content: space-between;
height: 100%;
}
.news ul {
margin-top: 30px;
/* list-style: none; 隐藏 ul 小圆点*/
padding-left: 10px;
}
.news li::marker {
/* ul 小圆点样式 */
color: #64967E;
}
.news li>a {
font-size: 18px;
line-height: 40px;
text-decoration: none;
color: #64967E;
text-shadow: 0 0 1px rgb(0, 84, 0);
}
.news-content {
width: 70%;
height: 90%;
border: 1px solid;
margin-top: 20px;
border-radius: 10px;
}
</style>
2, src/pages/Detail.vue
<template>
<ul class="news-list">
<li>编号: {{ route.params.id }}</li>
<li>标题: {{ route.params.title }}</li>
<li>内容: {{ route.params.content }}</li>
</ul>
</template>
<script setup lang="ts" name="Detail">
import { useRoute } from 'vue-router';
const route = useRoute();
console.log(route.params);
</script>
<style scoped>
.news-list {
list-style: none;
padding-left: 20px;
}
.news-list>li {
line-height: 30px;
}
</style>
3, src/router/index.ts
// 创建一个路由器,并暴露出去
// 第一步: 引入vue-router模块的createRouter方法
import {createRouter,createWebHistory,createWebHashHistory} from 'vue-router'
// 第三步:引入一个一个可能要呈现的组件,也就是页面组件
import Home from '@/pages/Home.vue'
import News from '@/pages/News.vue'
import About from '@/pages/About.vue'
import Detail from '@/pages/Detail.vue'
// 第二步: 创建路由器
const router = createRouter({
history:createWebHistory(), // 路由器的工作模式
// history:createWebHashHistory(), // 路由器的工作模式
routes:[ // 一个一个路由规则 路由规则数组
{
path: "/",
redirect: "/home" // 重定向
},
{
name:'home',
path:'/home',
component:Home
},
{
name:'news',
path:'/news',
component:News,
// 添加一个子集属性children,在里面写子路由规则数组
// 动态路由参数 :id/:title/:content? 表示可选的动态路由参数,也就是可有可无的动态路由参数
children:[ // 子路由规则数组 子集路由前不需要写'/',否则会找不到路径
{
name:'detail',
path:'detail/:id/:title/:content?', // 动态路由参数 :id/:title/:content
component:Detail
},
]
},
{
name:'about',
path:'/about',
component:About
},
]
})
// 第四步: 把创建的路由器暴露出去
export default router;

039_路由-props配置
4.9 [路由的 props 配置]
作用: 让路由组件更方便的收到参数(可以将路由参数作为 props 传给组件)
{
name: 'xiang',
path: 'detail/:id/:title/:content',
component: Detail,
// props 的对象写法,作用:把对象中的每一组key-value作为 props 传给Detail组件
// props: {a:1,b:2,c:3}
// props的布尔值写法,作用:把收到了每一组params参数,作为 props 传给Detail组件
// props:true
// props的函数写法,作用:把返回的对象中每一组key-value作为props传给Detail组件
props(route) {
return route.query
}
}
笔记




当你点击'新闻'(src/pages/News.vue),他就会去寻找名字为'xiang'的路由,同时带着三个参数 id,title,content去(src/router/index.ts)

到(src/router/index.ts)找到了名字为 'xiang'的路由需要传(id,title,content)红色框里面的三个参数

接下来找到是Detail组件,相当于<Detail />组件

相当于你自己写了一个Detail组件

接下来 props相当于Detail组件传入 id=?? title=?? content=??

只要我们加上 props:true这一行,就是路由收到的所有参数


路由收到的所有参数全部都传给了 props 组件了

黄色是占位收到的 props 参数

绿色的是props:true这行代码底层帮你传给组件的参数

你收到了哪些参数,defineProps就给你传哪些传数

如何实现props传参
1, 去 src/router/index.ts 文件去添加 props:true 这一行
{
name:'news',
path:'/news',
component:News,
// 添加一个子集属性children,在里面写子路由规则数组
// 动态路由参数 :id/:title/:content? 表示可选的动态路由参数,也就是可有可无的动态路由参数
children:[ // 子路由规则数组 子集路由前不需要写'/',否则会找不到路径
{
name:'detail',
path:'detail/:id/:title/:content?', // 动态路由参数 :id/:title/:content
component:Detail,
props:true // 开启props传参,这样就可以在Detail组件中使用this.$route.params来获取动态路由参数了
},
]
},
2, 去 src/pages/Detail.vue 通过 defineProps() 接收参数 你收到 props 哪些参数,他就给你传哪些参数
<script setup lang="ts" name="Detail">
defineProps(['id', 'title', 'content'])
</script>
使用 props 传参最优雅

首先去路由设置开启 props:true 传参

如果未开启 props:true 下面就真是[<Detail />]组件传参,数据就收不到。可以测试一下。


没有设置组件路由 props:true,就收不到数据


props参数的三种写法
// 第一种写法: 将路由收到的所有parans参数作为props传递给Detail路由组件
props:true




qwe就是 route



如果你传的是params,就直接使用props:true就OK
1, 去 src/pages/Detail.vue 添加 params 传参
<RouterLink
:to="{
name:'detail',
params:{
id: news.id,
title: news.title,
content: news.content
}
}">
{{ news.title }}
</RouterLink>
2, 去 src/router/index.ts 添加
props:true
3, 去 src/pages/Detail.vue 添加如下代码
<script setup lang="ts" name="Detail">
defineProps(['id', 'title', 'content'])
</script>
如果你传的是query,你写如下函数
1, 去 src/pages/Detail.vue 添加 query 传参
<RouterLink
:to="{
name:'detail',
query:{
id: news.id,
title: news.title,
content: news.content
}
}">
{{ news.title }}
</RouterLink>
2, 去 src/router/index.ts
props(route) {
return route.query//将路由收到的所有query参数作为props传递给Detail路由组件
//return route.params // 将路由收到的所有parans参数作为props传递给Detail路由组件
}
3, 去 src/pages/Detail.vue 添加如下代码
<script setup lang="ts" name="Detail">
defineProps(['id', 'title', 'content'])
</script>
只要以后你走这个绿色规则,底层逻辑一定是
<Detail a=100,b=200,c=300 />




_路由-props配置 实现代码如下
1, src/pages/News.vue
<template>
<div class="news">
<!-- 导航区 -->
<ul>
<li v-for="news in newsList" :key="news.id">
<!-- params传参的第一种方式:params传参,在router/index.js中配置路由时,使用动态路径参数 :id -->
<!-- params传参的第二种方式:params传参,在router/index.js中配置路由时,使用占位符 -->
<!-- params传参的第一种写法 -->
<!-- <RouterLink :to="`/news/detail/${news.id}/${news.title}/${news.content}`">
{{ news.title }}
</RouterLink> -->
<!-- params传参的第二种写法 -->
<!-- <RouterLink
:to="{
name:'detail',
params:{
id: news.id,
title: news.title,
content: news.content
}
}">
{{ news.title }}
</RouterLink> -->
<!-- query传参的第三种写法 -->
<RouterLink
:to="{
path:'/news/detail',
// name:'detail',
query:{
id: news.id,
title: news.title,
content: news.content
}
}">
{{ news.title }}
</RouterLink>
</li>
</ul>
<!-- 展示区 -->
<div class="news-content">
<RouterView></RouterView>
</div>
</div>
</template>
<script setup lang="ts" name="News">
import { reactive } from 'vue'
import {RouterView,RouterLink} from 'vue-router'
const newsList = reactive([
{id:'zg01',title:'很好的抗癌食物',content:'西兰花'},
{id:'zg02',title:'如何一夜暴富',content:'学IT'},
{id:'zg03',title:'震惊,万万没想到',content:'明天是周一'},
{id:'zg04',title:'好消息!好消息!',content:'快过年了'},
])
</script>
<style scoped>
/*新闻*/
.news {
padding: 0 20px;
display: flex;
justify-content: space-between;
height: 100%;
}
.news ul {
margin-top: 30px;
/* list-style: none; 隐藏 ul 小圆点*/
padding-left: 10px;
}
.news li::marker {
/* ul 小圆点样式 */
color: #64967E;
}
.news li>a {
font-size: 18px;
line-height: 40px;
text-decoration: none;
color: #64967E;
text-shadow: 0 0 1px rgb(0, 84, 0);
}
.news-content {
width: 70%;
height: 90%;
border: 1px solid;
margin-top: 20px;
border-radius: 10px;
}
</style>
2, src/pages/Detail.vue
<template>
<ul class="news-list">
<li>编号: {{ id }}</li>
<li>标题: {{ title }}</li>
<li>内容: {{ content }}</li>
</ul>
</template>
<script setup lang="ts" name="Detail">
defineProps(['id', 'title', 'content'])
</script>
<style scoped>
.news-list {
list-style: none;
padding-left: 20px;
}
.news-list>li {
line-height: 30px;
}
</style>
3, src/router/index.ts
// 创建一个路由器,并暴露出去
// 第一步: 引入vue-router模块的createRouter方法
import {createRouter,createWebHistory,createWebHashHistory} from 'vue-router'
// 第三步:引入一个一个可能要呈现的组件,也就是页面组件
import Home from '@/pages/Home.vue'
import News from '@/pages/News.vue'
import About from '@/pages/About.vue'
import Detail from '@/pages/Detail.vue'
// 第二步: 创建路由器
const router = createRouter({
history:createWebHistory(), // 路由器的工作模式
// history:createWebHashHistory(), // 路由器的工作模式
routes:[ // 一个一个路由规则 路由规则数组
{
path: "/",
redirect: "/home" // 重定向
},
{
name:'home',
path:'/home',
component:Home
},
{
name:'news',
path:'/news',
component:News,
// 添加一个子集属性children,在里面写子路由规则数组
// 动态路由参数 :id/:title/:content? 表示可选的动态路由参数,也就是可有可无的动态路由参数
children:[ // 子路由规则数组 子集路由前不需要写'/',否则会找不到路径
{
name:'detail',
path:'detail', // query传参 动态路由参数
// path:'detail/:id/:title/:content?', // params传参 动态路由参数 :id/:title/:content
component:Detail,
// 第一种写法: 将路由收到的所有parans参数作为props传递给Detail路由组件
// props:true // 开启props传参,这样就可以在Detail组件中使用this.$route.params来获取动态路由参数了
// 第二种写法: 函数写法 可以自己决定将什么参数作为props传递给Detail路由组件
props(route) {
return route.query // 将路由收到的所有query参数作为props传递给Detail路由组件
// return route.params // 将路由收到的所有parans参数作为props传递给Detail路由组件
}
// props: (route) => ({id: route.params.id, title: route.params.title})
// props: (route) => ({...route.params}) // 展开运算符,将对象中的所有属性都展开到新的对象中
// 第三种写法: 对象写法n基本不用 将路由收到的所有parans参数作为props传递给Detail路由组件,但是会多一些额外的属性,比如params,query等
// props:(route)=>({...route.params,...route.query})
// props: {
// a:100,
// b:200,
// c:300
// }
},
]
},
{
name:'about',
path:'/about',
component:About
},
]
})
// 第四步: 把创建的路由器暴露出去
export default router;

040_路由-replace属性
4.10 [replace属性]
1, 作用: 控制路由跳转时操作浏览器历史记录的模式。
2, 浏览器的历史记录有两种写入方式: 分别为 push 和 replace
a, push 是追加历史记录(默认值)。
b, replace 是替换当前记录。
3, 开启 replace 模式:
<RouterLink replace ...>News</RouterLink>

笔记

路由器跳转时会操作浏览器历史记录,路由器操作浏览器的历史记录有两个动作,一个是push,一个是replace,push相当于有指针,一直指着栈顶,就是你最后看的一个东西,可以借助浏览器的前进后退,就可以调整小指针。

可以借助浏览器的前进,后退就可以调整小指针。

点击后退箭头,小指针就调整到下面位置,这就是push模式。push就是推入栈内。

replace你现在看的是唯品会,过一会儿看的是今日头条,今日头条就把唯品会覆盖掉。这就是replace模式。replace就是替换的意思。


在导航区添加 replace 此时路由器就变成了replace模式


你希望他看完路由回不去,就用replace模式,一般情况下我们都用push模式。

_路由-replace属性 实现代码如下
1, src/App.vue
<template>
<div class="app">
<!-- 标题 -->
<Header></Header>
<!-- 导航区 -->
<div class="navigate">
<!--第一种: to的字符串写法-->
<!-- <RouterLink to="/home" active-class="active">首页</RouterLink>
<RouterLink to="/news" active-class="active">新闻</RouterLink>
<RouterLink to="/about" active-class="active">关于</RouterLink> -->
<!--第二种: to的对象写法 path跳转-->
<!-- <RouterLink :to="{path:'/home'}" active-class="active">首页</RouterLink>
<RouterLink :to="{path:'/news'}" active-class="active">新闻</RouterLink>
<RouterLink :to="{path:'/about'}" active-class="active">关于</RouterLink> -->
<!--第三种: to的对象写法 名字跳转-->
<RouterLink replace :to="{name:'home'}" active-class="active">首页</RouterLink>
<RouterLink replace :to="{name:'news'}" active-class="active">新闻</RouterLink>
<RouterLink replace :to="{name:'about'}" active-class="active">关于</RouterLink>
</div>
<!-- 展示区 -->
<div class="main-content">
<!-- 占位符,此处将来要展示不同的组件内容 -->
<RouterView></RouterView>
<!-- 此处以后可能要展示各种组件内容,到底展示哪个组件,取决于路由的匹配结果 -->
</div>
</div>
</template>
<script setup lang="ts" name="App">
import { RouterView,RouterLink } from 'vue-router';
import Header from '@/components/Header.vue';
</script>
<style scoped>
/*App*/
.navigate {
display: flex;
justify-content: space-around;
margin: 0 100px;
}
.navigate a {
display: block;
text-align: center;
width: 90px;
height: 40px;
line-height: 40px;
border-radius: 10px;
background-color: gray;
text-decoration: none;
color: white;
font-size: 18px;
letter-spacing: 5px;
}
.navigate a.active {
background-color: #64967E;
color: #ffc268;
font-weight: 900;
text-shadow: 0 0 1px black;
font-family: 微软雅黑;
}
.main-content {
margin: 0 auto;
margin-top: 30px;
border-radius: 10px;
width: 90%;
height: 400px;
border: 1px solid;
}
</style>

041_路由-编程式路由导航
4.11 [编程式导航]
路由组件的两个重要的属性: route和router变成了两个hooks
import {useRoute,useRouter} from 'vue-router'
const route = useRoute()
const router = useRouter()
console.log(route.query)
console.log(route.params)
console.log(router.push)
console.log(router.replace)

笔记


到目前为止,所有的导航区都是用RouterLink写的

下面三个 首页 新闻 关于 都是导航区 效果-代码


这些新闻也是导航,也是用RouterLink写的 效果-代码


RouterLink他是一个组件,浏览器他认识h1,h2,h3,但是他不认识RouterLink标签。

RouterLink标签最终会转成html标签===>是a标签





从以上图片可以看出 RouterLink ==> a,此时我想写一个button按钮,一点就能跳转路由,RouterLink出来的是a标签,我现在路由跳转是button按钮标签,该如何处理?

如果你只会RouterLink去跳转路由,意味着你所有的导航只能是a元素。

使用RouterLink标签根本就无法实现====>需求: 首页看3秒钟自动跳转到新闻。我们该如何处理?

3秒钟打印@ 代码-效果


绿色这里使用RouterLink实现跳转,这是根本就不可能的事情,因为RouterLink是结构标签。把结构标签放在脚本里面,没有这样的用法。你会发现你是无法进行下去的。


我们的需求是: 在这里编写一段代码让路由实现跳转到/news页面,此时不再是RouterLink==>a标签了。此时就涉及到编程式路由导航。

脱离RouterLink实现路由跳转,就是编程式路由导航。

一旦调用 router 路由器,你想去哪里就去哪里

一下代码实现需求: 进入首页,3秒钟以后跳转到新闻页面

路由跳转的时候有两个动作 :
push(跳转时留下历史记录) 和
replace(跳转时直接替换,没有留下历史记录)

这才是开发时常用的编程式路由导航

只有你输入正确的用户名和密码才能跳转到个人中心,都需要使用如下编程式路由导航。


在开发中,编程式路由导航是使用频率要远远大于RouterLink导航

在绿色的部分有四个小按钮,只要一点击就可以查看新闻.

绿色的RouterLink是页面中的一个一个红色导航 代码-效果



点击就能看详情 代码-详情



展示新闻详情

push() 里面写什么,to能写什么,push()括号就能写什么。

to 的属性写法,to能写的,push()也能写。

to有两种写法: 1,字符串写法,2, 对象写法。

写to 你写RouterlLink 你想跳转路由

你摸到了路由器router,你调 push() 你也想跳转路由,上面 to 可以实现跳转路由

既然to是跳转路由,push()也是跳转路由,他俩语法是统一的,所以push()里面传字符串和对象都可以。

news的使用范围

news 传参


RouterLink 掌握好,就是把to掌握好

编程式跳转push(?) 跟 to里面的写法一模一样


总结: 编程式导航的场景
1, 只有符合某些条件,我们才跳转,不是说用户一点击,我们就跳转,我们不让你一点击就跳转,到十点整自动跳转到秒杀路由,只有用户登录成功才跳转到个人中心,这种场景只能用编程式导航。
2, 鼠标滑过一个东西,我们就跳转,我们就得用编程式导航,总之我们不想用RouterLink的时候,也想实现路由跳转,就得用编程式路由导航。
_路由-编程式路由导航 实现代码如下
1, src/pages/Home.vue
<template>
<div class="home">
<img src="http://www.atguigu.com/images/index_new/logo.png" alt="">
</div>
</template>
<script setup lang="ts" name="Home">
import {onMounted} from 'vue'
import {useRouter} from 'vue-router'
const router = useRouter()
onMounted(() => {
setTimeout(() => {
// 在这里编写一段代码让路由实现跳转到/news页面
router.push('/news')
}, 3000)
})
</script>
<style scoped>
.home {
display: flex;
justify-content: center;
align-items: center;
height: 100%;
}
</style>
2, src/pages/News.vue
<template>
<div class="news">
<!-- 导航区 -->
<ul>
<li v-for="news in newsList" :key="news.id">
<!-- params传参的第一种方式:params传参,在router/index.js中配置路由时,使用动态路径参数 :id -->
<!-- params传参的第二种方式:params传参,在router/index.js中配置路由时,使用占位符 -->
<!-- params传参的第一种写法 -->
<!-- <RouterLink :to="`/news/detail/${news.id}/${news.title}/${news.content}`">
{{ news.title }}
</RouterLink> -->
<!-- params传参的第二种写法 -->
<!-- <RouterLink
:to="{
name:'detail',
params:{
id: news.id,
title: news.title,
content: news.content
}
}">
{{ news.title }}
</RouterLink> -->
<!-- query传参的第三种写法 -->
<button @click="showNewsDetail(news)">查看新闻</button>
<RouterLink
:to="{
//path:'/news/detail',
name:'detail',
query:{
id: news.id,
title: news.title,
content: news.content
}
}">
{{ news.title }}
</RouterLink>
</li>
</ul>
<!-- 展示区 -->
<div class="news-content">
<RouterView></RouterView>
</div>
</div>
</template>
<script setup lang="ts" name="News">
import { reactive } from 'vue'
import {RouterView,RouterLink,useRouter} from 'vue-router'
const newsList = reactive([
{id:'zg01',title:'很好的抗癌食物',content:'西兰花'},
{id:'zg02',title:'如何一夜暴富',content:'学IT'},
{id:'zg03',title:'震惊,万万没想到',content:'明天是周一'},
{id:'zg04',title:'好消息!好消息!',content:'快过年了'},
])
const router = useRouter()
interface NewsInter {
id: string,
title: string,
content: string,
}
function showNewsDetail(news:NewsInter) {
router.push({
//path:'/news/detail',
name:'detail',
query:{
id: news.id,
title: news.title,
content: news.content
}
})
}
</script>
<style scoped>
/*新闻*/
.news {
padding: 0 20px;
display: flex;
justify-content: space-between;
height: 100%;
}
.news ul {
margin-top: 30px;
/* list-style: none; 隐藏 ul 小圆点*/
padding-left: 10px;
}
.news li::marker {
/* ul 小圆点样式 */
color: #64967E;
}
.news li>a {
font-size: 18px;
line-height: 40px;
text-decoration: none;
color: #64967E;
text-shadow: 0 0 1px rgb(0, 84, 0);
}
.news-content {
width: 70%;
height: 90%;
border: 1px solid;
margin-top: 20px;
border-radius: 10px;
}
</style>
3, src/router/index.ts
// 创建一个路由器,并暴露出去
// 第一步: 引入vue-router模块的createRouter方法
import {createRouter,createWebHistory,createWebHashHistory} from 'vue-router'
// 第三步:引入一个一个可能要呈现的组件,也就是页面组件
import Home from '@/pages/Home.vue'
import News from '@/pages/News.vue'
import About from '@/pages/About.vue'
import Detail from '@/pages/Detail.vue'
// 第二步: 创建路由器
const router = createRouter({
history:createWebHistory(), // 路由器的工作模式
// history:createWebHashHistory(), // 路由器的工作模式
routes:[ // 一个一个路由规则 路由规则数组
{
path: "/",
redirect: "/home" // 重定向
},
{
name:'home',
path:'/home',
component:Home
},
{
name:'news',
path:'/news',
component:News,
// 添加一个子集属性children,在里面写子路由规则数组
// 动态路由参数 :id/:title/:content? 表示可选的动态路由参数,也就是可有可无的动态路由参数
children:[ // 子路由规则数组 子集路由前不需要写'/',否则会找不到路径
{
name:'detail',
path:'detail', // query传参 动态路由参数
// path:'detail/:id/:title/:content?', // params传参 动态路由参数 :id/:title/:content
component:Detail,
// 第一种写法: 将路由收到的所有parans参数作为props传递给Detail路由组件
// props:true // 开启props传参,这样就可以在Detail组件中使用this.$route.params来获取动态路由参数了
// 第二种写法: 函数写法 可以自己决定将什么参数作为props传递给Detail路由组件
props(route) {
return route.query // 将路由收到的所有query参数作为props传递给Detail路由组件
// return route.params // 将路由收到的所有parans参数作为props传递给Detail路由组件
}
// props: (route) => ({id: route.params.id, title: route.params.title})
// props: (route) => ({...route.params}) // 展开运算符,将对象中的所有属性都展开到新的对象中
// 第三种写法: 对象写法n基本不用 将路由收到的所有parans参数作为props传递给Detail路由组件,但是会多一些额外的属性,比如params,query等
// props:(route)=>({...route.params,...route.query})
// props: {
// a:100,
// b:200,
// c:300
// }
},
]
},
{
name:'about',
path:'/about',
component:About
},
]
})
// 第四步: 把创建的路由器暴露出去
export default router;

042_路由-重定向
_路由-重定向 实现代码
1, src/router/index.ts
// 创建一个路由器,并暴露出去
// 第一步: 引入vue-router模块的createRouter方法
import {createRouter,createWebHistory,createWebHashHistory} from 'vue-router'
// 第三步:引入一个一个可能要呈现的组件,也就是页面组件
import Home from '@/pages/Home.vue'
import News from '@/pages/News.vue'
import About from '@/pages/About.vue'
import Detail from '@/pages/Detail.vue'
// 第二步: 创建路由器
const router = createRouter({
history:createWebHistory(), // 路由器的工作模式
// history:createWebHashHistory(), // 路由器的工作模式
routes:[ // 一个一个路由规则 路由规则数组
{
path: "/",
redirect: "/home" // 重定向
},
{
name:'home',
path:'/home',
component:Home
},
{
name:'news',
path:'/news',
component:News,
// 添加一个子集属性children,在里面写子路由规则数组
// 动态路由参数 :id/:title/:content? 表示可选的动态路由参数,也就是可有可无的动态路由参数
children:[ // 子路由规则数组 子集路由前不需要写'/',否则会找不到路径
{
name:'detail',
path:'detail', // query传参 动态路由参数
// path:'detail/:id/:title/:content?', // params传参 动态路由参数 :id/:title/:content
component:Detail,
// 第一种写法: 将路由收到的所有parans参数作为props传递给Detail路由组件
// props:true // 开启props传参,这样就可以在Detail组件中使用this.$route.params来获取动态路由参数了
// 第二种写法: 函数写法 可以自己决定将什么参数作为props传递给Detail路由组件
props(route) {
return route.query // 将路由收到的所有query参数作为props传递给Detail路由组件
// return route.params // 将路由收到的所有parans参数作为props传递给Detail路由组件
}
// props: (route) => ({id: route.params.id, title: route.params.title})
// props: (route) => ({...route.params}) // 展开运算符,将对象中的所有属性都展开到新的对象中
// 第三种写法: 对象写法n基本不用 将路由收到的所有parans参数作为props传递给Detail路由组件,但是会多一些额外的属性,比如params,query等
// props:(route)=>({...route.params,...route.query})
// props: {
// a:100,
// b:200,
// c:300
// }
},
]
},
{
name:'about',
path:'/about',
component:About
},
]
})
// 第四步: 把创建的路由器暴露出去
export default router;
重定向一般在一级路由实现
{
path: "/",
redirect: "/home" // 重定向
},

