路由
路由
Vue实质上是一个 SPA(单Web应用程序) 应用,也就是实质上其实只有一张页面。所以我们使用route进行切换。
基本构成:
1、导航区、展示区
2、路由器
3、制定路由的具体规则(什么路径,对应着什么组件)
4、形成 一个一个的 xxx.vue 文件
5、告诉路由把命中的组件放在哪里:RouterView
6、不要通过直接在浏览器输入路由,通过:RouterLink
基本的切换效果
1、安装路由
npm install vue-router
2、创建路由器并暴露
对应位置:src/router/index.ts
//### 创建一个路由器,并暴露出去 ### import { createRouter, createWebHashHistory } from "vue-router"; //引入createRouter //以下是需要呈现的组件 import Home from "@/components/Home.vue"; import About from "@/components/About.vue"; import News from "@/components/News.vue"; //创建路由器 const router = createRouter({ history: createWebHashHistory(), //路由器的工作模式 routes: [ //一个一个的路由规则 { path: '/home', component: Home }, { path: '/about', component: About }, { path: '/news', component: News } ] }) export default router; //暴露出去router
3、创建对应的路由组件
4、创建了路由器实例,并将其注册为插件
位于:/src/main.ts
// 引入createApp用于创建应用 import { createApp } from "vue"; // 引入App根组件 import App from "./App.vue"; // 引入路由器 import router from "./router"; const app = createApp(App); app.use(router); app.mount("#app");
5、设置对应显示的位置
<div class="main-content"> <!-- 呈现对应组件 --> <RouterView></RouterView> </div>
6、点击后进行路由切换
这样就不用手动输入路由路径了,当然这里还通过属性设置了选中后的样式。
<!-- 导航区 --> <div class="navigate"> <RouterLink to="/home" active-class="active">首页</RouterLink> <RouterLink to="/news" active-class="active">新闻</RouterLink> <RouterLink to="/about" active-class="active">关于</RouterLink> </div>
路由组件放置位置与切换后卸载组件
为了区分路由组件和一般组件,路由组件通常存放在pages
或 views
文件夹,一般组件通常存放在components
文件夹。
通过点击导航,视觉效果上“消失” 了的路由组件,默认是被卸载掉的,需要的时候再去挂载。编写对应生命周期即可查看。
to的两种写法
<!-- 第一种:to的字符串写法 --> <RouterLink to="/home" active-class="active">首页</RouterLink> <!-- 第二种:to的对象写法 --> <RouterLink :to="{path: '/about'}" active-class="active">关于</RouterLink>> <!-- 通过路由 --> <RouterLink :to="{name: 'news'}" active-class="active">新闻</RouterLink> <!-- 通过命名 -->
路由的工作模式
history模式
写法:
Vue2:mode:'hsitory'
Vue3: history:createWebHistory()
React: BrowserRouter
优点:URL
更加美观,不带有#
,更接近传统的网站URL
。
缺点:后期项目上线,需要服务端配合处理路径问题,否则刷新会有404
错误。
参考代码:
const router = createRouter({ history:createWebHistory(), //history模式 /******/ })
补充(因为hash模式不会把#后面的路径给到对应服务端所以用特殊处理,因为SPA):
# 参考nginx简单处理方案 location / { try_files $uri $uri/ /index.html; }
hash模式
优点:兼容性更好,因为不需要服务器端处理路径。
缺点:URL
带有#
不太美观,且在SEO
(搜索引擎优化)优化方面相对较差。
参考代码:
const router = createRouter({ history:createWebHashHistory(), //hash模式 /******/ })
命名路由
作用:可以简化路由跳转及传参(后面就讲)。
给路由规则命名:
routes: [ //一个一个的路由规则 { name:'home', path: '/home', component: Home }, { name:'about', path: '/about', component: About }, { name:'news', path: '/news', component: News } ]
<!-- 命名后,对象写法就可以通过命名来,如/news/xxx路由也可以简化命名书写 --> <RouterLink :to="{name: 'news'}" active-class="active">新闻</RouterLink> <!-- 通过命名 -->
嵌套路由
这里步骤中不再包含一些必要的如安装路由,use到App的操作了。
编写嵌套路由
routes: [ //一个一个的路由规则 { name:'home', path: '/home', component: Home }, { name:'about', path: '/about', component: About }, { name:'news', path: '/news', component: News, children: [ { path: 'detail', //子级前面不用加/ component: Detail } ] } ]
编写对应路由组件
<template> <ul class="news-list"> <li>编号:xxx</li> <li>标题:xxx</li> <li>内容:xxx</li> </ul> </template> <script setup lang="ts" name="Detail"> </script> <style scoped> .news-list { list-style: none; padding-left: 20px; } .news-list>li { line-height: 30px; } </style>
使用
<template> <div class="news"> <!-- 导航区 --> <ul> <li v-for="news in newsList" :key="news.id"> <RouterLink to="/news/detail"> {{ news.content }} </RouterLink> <!-- <RouterLink :to="{path: '/news/detail'}"> {{ news.content }} </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:'asfdtrfay01',title:'很好的抗癌食物',content:'西蓝花'}, {id:'asfdtrfay02',title:'如何一夜暴富',content:'学IT'}, {id:'asfdtrfay03',title:'震惊,万万没想到',content:'明天是周一'}, {id:'asfdtrfay04',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; */ padding-left: 10px; } .news li::marker { 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>
路由传参(重点)
query参数
1、在导航区点击时通过query传递参数:
<!-- 导航区 --> <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', query: { id: news.id, title: news.title, content: news.content } }" > {{ news.title }} </RouterLink> </li> </ul>
2、对应的路由组件接收参数
<script setup lang="ts" name="Detail"> import { useRoute } from 'vue-router'; // 从命名中可以看出 这是已给hooks import { toRefs } from 'vue'; let router = useRoute(); // console.log('查看', router); let { query } = toRefs(router); //从响应式中解构属性会失去响应式 console.log('查看是否为响应式:', query); </script>
params参数
1、先配置路由
routes: [ //一个一个的路由规则 { name:'home', path: '/home', component: Home }, { name:'about', path: '/about', component: About }, { name:'news', path: '/news', component: News, children: [ { name: 'detail', path: 'detail/:id/:title/:content?', //子级前面不用加 ? 表示可传可不传 component: Detail } ] } ]
2、在导航区点击时通过params传递参数:
<ul> <li v-for="news in newsList" :key="news.id"> <!-- 第一种写法: --> <!-- <RouterLink :to="`/news/detail/${news.id}/${news.title}/${news.content}`"> {{ news.title }} </RouterLink> --> <!-- 第二种写法 --> <RouterLink :to="{ name: 'detail', //必须使用name params: { //参数不能是对象和数组 id:news.id, title:news.title, content:news.content, } }" > {{ news.title }} </RouterLink> </li> </ul>
3、接收参数
<script setup lang="ts" name="Detail"> import { useRoute } from 'vue-router'; import { toRefs } from 'vue'; const route = useRoute(); // console.log(route); let { params } = toRefs(route); console.log(params); </script>
注意事项
备注1:传递params
参数时,若使用to
的对象写法,必须使用name
配置项,不能用path
。
备注2:传递params
参数时,需要提前在规则中占位。
备注3:传递params
参数时,不能传递对象或数组参数。
路由_props配置
作用:让路由组件更方便的收到参数(可以将路由参数作为props
传给组件),这样可以简化接收位置的书写,只是需要注意三种写法,第一种适用于写了params的方式,第二种query和params都可以,第三种写的较死。
参考代码:
children: [ { name: 'detail', path: 'detail/:id/:title/:content?', //子级前面不用加 ? 表示可传可不传 component: Detail, //### 第一种写法:将路由收到的所有params参数作为props传给路由组件 // props: true //从<Detail> --> <Detail id = ?? title = ?? content = ??> //### 第二种写法:函数写法,可以自己决定将什么作为props给路由组件 // props(arg) { //这个参数就是路由参数,可以获取params或者query,一般用于处理query,毕竟params有上面的写法 // return arg.params; // } //### 第三种写法:对象写法,可以自己决定将什么作为props给路由组件 props: { //有点写死了 a: 100, b: 200, c: 300 } } ]
推荐
1、使用query参数的时候用第二种写法
props(arg) { return arg.query; }
2、使用params参数的时候用第一种写法
{ name: 'detail', path: 'detail/:id/:title/:content?', //子级前面不用加 ? 表示可传可不传 component: Detail, props: true }
3、第三种写法可以用于一些较为固定的地方
{ name: 'detail', path: 'detail/:id/:title/:content?', //子级前面不用加 ? 表示可传可不传 component: Detail, props: { //有点写死了 a: 100, b: 200, c: 300 } }
replace属性
作用:控制路由跳转时操作浏览器历史记录的模式。
浏览器的历史记录有两种写入方式:分别为push
和replace
:
push
是追加历史记录(默认值)。
replace
是替换当前记录。
开启replace
模式(在对应的 RouterLink 中加上属性后就可以设置,然后点击这个后就无法使用浏览器回退):
<RouterLink replace .......>...</RouterLink>
路由_编程式路由导航(脱离 RouterLink 实现路由跳转)
使用编程式路由导航,我们可以脱离 RouterLink进行路由跳转,无论是点击按钮、鼠标滑过、定时跳转如跳到秒杀页面等场景都可以使用。关键在于:学了to,我们通过获取路由器进行跳转中如使用 push 的方式也可以接受字符串或者对象,所以可以直接用to写法的格式
参考代码:
function showNewsDetail(news:NewsInter) { //可以写 :any 跳过检查 //### 这里push可以接收的对象是字符串 或者 对象,所以可以直接使用to的写法 router.push({ //这里也可以使用一个 replace 就不能使用浏览器回退了 name: 'detail', //必须使用name params: { //参数不能是对象和数组 id:news.id, title:news.title, content:news.content, } }); }
路由_重定向
如做初始跳转:
{ path:'/', redirect: '/home' }
本文作者:如此而已~~~
本文链接:https://www.cnblogs.com/fragmentary/p/18626706
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步