Vite + Vue3 + Ts + Router 路由
Vue Router 官网
1、安装
npm install vue-router - S
2、创建 router
- 在项目根目录中
str
文件夹中创建 router
目录,并目录中创建 index.ts
文件,文件示例代码如下:
import { createRouter, createWebHistory } from "vue-router";
const router = createRouter({
history: createWebHistory(),
routes: [
{
path: "/a",
component: () => import("@/views/A.vue"),
},
{
path: "/b",
component: () => import("@/views/B.vue"),
},
{
path: "/c",
component: () => import("@/views/C.vue"),
},
],
});
export default router;
3、注册路由
- 在
main.ts
文件中导入 router
,并注册,示例代码如下:
import { createApp } from "vue";
import App from "./App.vue";
import { router } from "./router/router";
const app = createApp(App);
app.use(router);
app.mount("#app");
4、使用方法
<template>
<h2 class="title">Vue3 路由测试</h2>
<div class="routers">
<RouterLink to="/a" active-class="active">首页</RouterLink>
<RouterLink to="/b" active-class="active">新闻</RouterLink>
<RouterLink to="/c" active-class="active">体育</RouterLink>
</div>
<div class="container">
<RouterView></RouterView>
</div>
</template>
<script setup lang="ts">
import { RouterView, RouterLink } from "vue-router";
</script>
<style>
.title {
border-radius: 40px;
line-height: 80px;
text-align: center;
border: 1px #999 solid;
background: linear-gradient(to bottom, green, #ff9999, green);
}
.routers {
display: flex;
justify-content: space-around;
}
.routers a {
border: 1px #cdcdcd solid;
padding: 10px 20px;
border-radius: 4px;
background: #999;
text-decoration: none;
}
.routers .active {
background: #c00000;
color: #fff;
}
.container {
border: 1px #333 solid;
height: 400px;
margin-top: 20px;
border-radius: 4px;
}
</style>
<template>
<h2>我是 A 页面</h2>
</template>
<script setup>
</script>
<style lang='scss' scoped>
</style>
<template>
<h2>我是 B 页面</h2>
</template>
<script setup></script>
<style lang="scss" scoped></style>
<template>
<h2>我是 C 页面</h2>
</template>
<script setup></script>
<style lang="scss" scoped></style>
5、两个注意点
- 1、路由组件通常存在
pages
或 views
文件夹,一般组件通常存放在 components
文件夹。 - 2、通过点击导航,视觉效果上“消失”了的路由组件,默认是被销毁掉的,需要的时候再去挂载。
6、路由器工作模式
1、History 模式
优点
:URL
更加美观。不带有 #
,更接近传统的网站 URL
。缺点
:后期项目上线,需要服务端配合处理路径问题,否则刷新会有404错误。
const router = createRouter({
history:createWebHistory()
})
2、Hash 模式
优点
:兼容性更好,因为不需要服务器处理路径。缺点
:URL
带有 #
不太美观,且在 SEO
优化方面相对较差。
const router = createRouter({
history:createWebHashHistory()
})
7、to 的两种写法
第一种:字符串写法
<RouterLink to="/a" active-class="active">首页</RouterLink>
第二种:对象写法
<RouterLink :to="{ path: '/c' }" active-class="active">体育</RouterLink>
<RouterLink :to="{ name: 'new' }" active-class="active">新闻</RouterLink>
8、嵌套路由
- 示例代码如下:
src
-> router
-> index.ts
文件内容如下:
import { createRouter, createWebHashHistory } from "vue-router";
const router = createRouter({
history: createWebHashHistory(),
routes: [
{
path: "/",
redirect: "/a",
},
{
path: "/a",
component: () => import("@/views/A.vue"),
},
{
name: "new",
path: "/b",
component: () => import("@/views/B.vue"),
children: [
{
path: "detail",
component: () => import("@/views/NewsDatails.vue"),
},
],
},
{
name: "about",
path: "/c",
component: () => import("@/views/C.vue"),
},
],
});
export default router;
<template>
<div class="p">
<div class="menu">
<h3>新闻列表</h3>
<ul>
<li v-for="item in news" :key="item.id">
<h4>
<RouterLink to="/b/detail">{{ item.title }}</RouterLink>
</h4>
</li>
</ul>
</div>
<div class="content">
<RouterView />
</div>
</div>
</template>
<script setup>
import { reactive } from "vue";
import { RouterView, RouterLink } from "vue-router";
const news = reactive([
{
id: 1,
title: "新闻标题01",
content: "新闻内容01",
},
{
id: 2,
title: "新闻标题02",
content: "新闻内容02",
},
{
id: 3,
title: "新闻标题03",
content: "新闻内容03",
},
]);
</script>
<style lang="scss" scoped>
.p {
display: flex;
height: 100%;
.menu {
width: 30%;
}
.content {
border: 4px #c00000 solid;
border-radius: 10px;
height: 90%;
width: 70%;
margin: 10px;
}
}
</style>
<template>
<h3>我是新闻详情页面</h3>
</template>
<script setup></script>
<style lang="scss" scoped></style>
9、传参数
<template>
<div class="p">
<div class="menu">
<h3>新闻列表</h3>
<ul>
<li v-for="item in news" :key="item.id">
<h4>
<RouterLink
:to="{
path: '/b/detail',
query: {
content: item.content,
},
}"
:query="item"
>{{ item.title }}</RouterLink
>
</h4>
</li>
</ul>
</div>
<div class="content">
<RouterView />
</div>
</div>
</template>
<script setup>
import { reactive } from "vue";
import { RouterView, RouterLink } from "vue-router";
const news = reactive([
{
id: 1,
title: "新闻标题01",
content: "新闻内容01",
},
{
id: 2,
title: "新闻标题02",
content: "新闻内容02",
},
{
id: 3,
title: "新闻标题03",
content: "新闻内容03",
},
]);
</script>
<style lang="scss" scoped>
.p {
display: flex;
height: 100%;
.menu {
width: 30%;
}
.content {
border: 4px #c00000 solid;
border-radius: 10px;
height: 90%;
width: 70%;
margin: 10px;
}
}
</style>
<template>
<h3>新闻详情</h3>
<h4>{{ route.query.content }}</h4>
</template>
<script setup>
import { useRoute } from "vue-router";
const route = useRoute();
</script>
<style lang="scss" scoped></style>
<template>
<h3>新闻详情</h3>
<h4>{{ query.content }}</h4>
</template>
<script setup>
import { useRoute } from "vue-router";
import { toRefs } from "vue";
const route = useRoute();
const { query } = toRefs(route);
</script>
<style lang="scss" scoped></style>
import { createRouter, createWebHashHistory } from "vue-router";
const router = createRouter({
history: createWebHashHistory(),
routes: [
{
path: "/",
redirect: "/a",
},
{
path: "/a",
component: () => import("@/views/A.vue"),
},
{
name: "new",
path: "/b",
component: () => import("@/views/B.vue"),
children: [
{
name: "xiangqing",
path: "detail/:content?",
component: () => import("@/views/NewsDatails.vue"),
},
],
},
{
name: "about",
path: "/c",
component: () => import("@/views/C.vue"),
},
],
});
export default router;
<template>
<div class="p">
<div class="menu">
<h3>新闻列表</h3>
<ul>
<li v-for="item in news" :key="item.id">
<h4>
<RouterLink
:to="{
name: 'xiangqing', // 必须使用路由的 name 属性
params: {
content: item.content,
},
}"
>{{ item.title }}</RouterLink
>
</h4>
</li>
</ul>
</div>
<div class="content">
<RouterView />
</div>
</div>
</template>
<script setup>
import { reactive } from "vue";
import { RouterView, RouterLink } from "vue-router";
const news = reactive([
{
id: 1,
title: "新闻标题01",
content: "新闻内容01",
},
{
id: 2,
title: "新闻标题02",
content: "新闻内容02",
},
{
id: 3,
title: "新闻标题03",
content: "新闻内容03",
},
]);
</script>
<style lang="scss" scoped>
.p {
display: flex;
height: 100%;
.menu {
width: 30%;
}
.content {
border: 4px #c00000 solid;
border-radius: 10px;
height: 90%;
width: 70%;
margin: 10px;
}
}
</style>
<template>
<h3>新闻详情</h3>
<h4>{{ route.params.content }}</h4>
</template>
<script setup>
import { useRoute } from "vue-router";
const route = useRoute();
</script>
<style lang="scss" scoped></style>
10、路由的 props 配置
- 作用:让路由组件更方便的收到参数(可以将路由参数作为
props
传给组件)
import { createRouter, createWebHashHistory } from "vue-router";
const router = createRouter({
history: createWebHashHistory(),
routes: [
{
path: "/",
redirect: "/a",
},
{
path: "/a",
component: () => import("@/views/A.vue"),
},
{
name: "new",
path: "/b",
component: () => import("@/views/B.vue"),
children: [
{
name: "xiangqing",
path: "detail/:content?",
component: () => import("@/views/NewsDatails.vue"),
props(route) {
return route.query;
},
},
],
},
{
name: "about",
path: "/c",
component: () => import("@/views/C.vue"),
},
],
});
export default router;
11、replace 属性
- 1、作用:控制路由跳转时操作浏览器历史记录的模式
- 2、浏览器的历史记录有两种写入方式:分别为
push
和 replace
:
push
是追加历史记录(默认值)replace
是替换当前记录
- 3、开启
replace
模式:
<RouterLink replace ......>News</RouterLink>
12、编程式导航
- 路由组件的两个重要的属性:
$route
和 $router
变成了两个 hooks
- 编程式路由导航就是脱离
<RouterLink>
实现路由跳转 - 简单例子,代码如下:
import { createRouter, createWebHashHistory } from "vue-router";
const router = createRouter({
history: createWebHashHistory(),
routes: [
{
path: "/",
redirect: "/a",
},
{
path: "/a",
component: () => import("@/views/A.vue"),
},
{
name: "new",
path: "/b",
component: () => import("@/views/B.vue"),
children: [
{
name: "xiangqing",
path: "detail",
component: () => import("@/views/NewsDatails.vue"),
props(route) {
return route.query;
},
},
],
},
{
name: "about",
path: "/c",
component: () => import("@/views/C.vue"),
},
],
});
export default router;
<template>
<div class="p">
<div class="menu">
<h3>新闻列表</h3>
<ul>
<li v-for="item in news" :key="item.id">
<h4>
<RouterLink
:to="{
name: 'xiangqing', // 必须使用路由的 name 属性
query: {
content: item.content,
},
}"
>{{ item.title }}</RouterLink
>
<button @click="detailHandle(item.content)">查看详情</button>
</h4>
</li>
</ul>
</div>
<div class="content">
<RouterView />
</div>
</div>
</template>
<script setup lang="ts">
import { reactive } from "vue";
import { RouterView, RouterLink, useRouter } from "vue-router";
const router = useRouter();
const news = reactive([
{
id: 1,
title: "新闻标题01",
content: "新闻内容01",
},
{
id: 2,
title: "新闻标题02",
content: "新闻内容02",
},
{
id: 3,
title: "新闻标题03",
content: "新闻内容03",
},
]);
interface NewsInder {
content: string;
}
const detailHandle = (content: NewsInder) => {
router.push({
name: "xiangqing",
query: {
content: content,
},
});
};
</script>
<style lang="scss" scoped>
.p {
display: flex;
height: 100%;
.menu {
width: 30%;
}
.content {
border: 4px #c00000 solid;
border-radius: 10px;
height: 90%;
width: 70%;
margin: 10px;
}
}
</style>
13、重定向
{
path: "/",
redirect: "/a",
}