路由安装和简单使用
安装路由组件 npm i vue-router
scr/pages
下创建三个基础组件(路由组件:通过路由渲染的组件)
Home.vue News.vue About.vue
vue
<template>
<div>this is about</div>
</template>
创建文件 src/router/index.ts
,创建路由规则
typescript
import {createRouter, createWebHistory} from 'vue-router'
import Home from '@/pages/Home.vue'
// 创建路由规则
const router = createRouter({
history: createWebHistory(),
routes: [{
path: '/home',
component: Home
},{
path: '/news',
component: () => import('@/pages/News.vue')
},{
path: '/about',
component: () => import('@/pages/About.vue')
},
]
})
// 导出路由规则
export default router;
main.js
引入路由规则
js
import { createApp } from 'vue'
import App from './App.vue'
import router from 'vue-router'
const app = createApp(App)
app.mount('#app')
app.use(router)
App.vue 使用路由组件
vue
<template>
<div class="app">
<h2>vue路由示例</h2>
<!-- 导航区 -->
<div class="nav">
<router-link to="/home">首页</router-link>
<router-link to="/news">新闻</router-link>
<router-link :to="{path: '/about'}">关于</router-link>
</div>
<!-- 展示区 -->
<div class="content">
<router-view></router-view>
</div>
</div>
</template>
以上是基本用法示例,注意点:1,路由组件通常放大pages或views文件夹下,一般组件放components文件夹下。2,通过点击导航切换路由页面,消失的页面会被卸载,使用时会重新挂载
路由器工作模式
history模式(推荐)
优点:URL中不带
#
,更加美观 缺点:项目上线时服务端需要配置路径问题(try_files),否则刷新会有404问题
hash模式
优点:兼容性更好,不需要处理路径问题 缺点:URL 中带
#
,SEO优化也不好
命名路由
创建路由规则是新增name配置
typescript
// 创建路由规则
const router = createRouter({
history: createWebHistory(),
routes: [{
path: '/home',
name: 'jia',
component: Home
}
]
})
使用时可以用对象写法的to
vue
<router-link :to="{name:'jia'}">首页</router-link>
嵌套路由
修改news.vue
内容如下
vue
<template>
<div>
<!-- 导航区 -->
<ul><li v-for="n in news" :key="n.id">
<!-- to里面要从第一级开始,并且别忘了开头要有/ -->
<router-link to="/news/detail">{{n.title}}</router-link>
</li></ul>
<!-- 展示区 -->
<router-view></router-view>
</div>
</template>
<script setup lang="ts">
import { reactive } from 'vue';
const news = reactive([
{id: 1, title: 'news1', content: 'news1 content'},
{id: 2, title: 'news2', content: 'news2 content'},
{id: 3, title: 'news3', content: 'news3 content'},
{id: 4, title: 'news4', content: 'news4 content'},
{id: 5, title: 'news5', content: 'news5 content'}
])
</script>
<style scoped>
div {
display: flex;
}
</style>
创建子路由页面pages/Detail.vue
vue
<template>
<ul>
<li>编号:xxx</li>
<li>标题:xxx</li>
<li>内容:xxx</li>
</ul>
</template>
修改news的路由规则如下:
typescript
{
path: '/news',
name: 'news',
component: () => import('@/pages/News.vue'),
children: [{
path: 'detail',
component: () => import('@/pages/Detail.vue')
}]
}
以上是嵌套路由基本内容,detail页面都是写死的,如果需要不同新闻展示不同内容,就需要学习如何传参
query参数
最简示例
vue
// News.vue 修改如下:使用query传参a、b
<router-link to="/news/detail?a=1&b=2">{{n.title}}</router-link>
// Detail.vue修改如下,引入useRoute,从route中的query种读取传过来的值
<template>
<ul>
<li>编号:{{route.query.a}}</li>
<li>标题:{{route.query.b}}</li>
<li>内容:xxx</li>
</ul>
</template>
<script setup>
import {useRoute} from 'vue-router'
const route = useRoute()
</script>
模板字符串方式
vue
// News.vue 修改如下:使用query传参,模板字符串方式
<router-link :to="`/news/detail?id=${n.id}&title=${n.title}&content=${n.content}`">{{n.title}}</router-link>
// Detail.vue修改如下
<ul>
<li>编号:{{route.query.id}}</li>
<li>标题:{{route.query.title}}</li>
<li>内容:{{ route.query.content }}</li>
</ul>
// 优化Detail.vue
<template>
<ul>
<li>编号:{{query.id}}</li>
<li>标题:{{query.title}}</li>
<li>内容:{{ query.content }}</li>
</ul>
</template>
<script setup>
import { toRefs } from 'vue';
import {useRoute} from 'vue-router'
const route = useRoute()
const {query} = toRefs(route)
</script>
// 误区:query方式传不了对象类型,如下:
<router-link :to="`/news/detail?new=${n}`">{{n.title}}</router-link>
优化,to的对象类型传参
vue
// 优化News.vue,使用对象to传参方式
<ul><li v-for="n in news" :key="n.id">
<router-link :to="{
path: '/news/detail',
query: {
id: n.id,
title: n.title,
content: n.content
}
}">{{n.title}}</router-link>
</li></ul>
// 也可以使用命名路由方式,修改router/index.ts下的路由规则,detail命名为d
{
path: '/news',
name: 'news',
component: () => import('@/pages/News.vue'),
children: [{
name: 'd',
path: 'detail',
component: () => import('@/pages/Detail.vue')
}]
}
// 优化News.vue,使用对象to传参方式,通过命名路由跳转
<router-link :to="{
name: 'd',
query: {
id: n.id,
title: n.title,
content: n.content
}
}">{{n.title}}</router-link>
params参数
首先修改路由规则:必须是命名路由,path里面定义入参:xxx
,后面跟?
代表可选参数
typescript
{
path: '/news',
name: 'news',
component: () => import('@/pages/News.vue'),
children: [{
name: 'd',
path: 'detail/:id/:title/:content?',
component: () => import('@/pages/Detail.vue')
}]
}
News.vue改为如下params传参
vue
<router-link :to="{
name: 'd',
params: {
id: n.id,
title: n.title,
}
}">{{n.title}}</router-link>
Detail.vue使用
vue
<template>
<ul>
<li>编号:{{params.id}}</li>
<li>标题:{{params.title}}</li>
<li>内容:{{ params.content }}</li>
</ul>
</template>
<script setup>
import { toRefs } from 'vue';
import {useRoute} from 'vue-router'
const route = useRoute()
const {params} = toRefs(route)
</script>
路由的props参数
给新闻的路由规则添加props:true
配置,将路由收到的所有params参数作为props传给路由组件
typescript
children: [{
name: 'd',
path: 'detail/:id/:title/:content?',
component: () => import('@/pages/Detail.vue'),
props: true // 将路由收到的所有params参数作为props传给路由组件
}]
然后在Detail.vue中就可以直接使用defineProps接收使用了
vue
<template>
<ul>
<li>编号:{{id}}</li>
<li>标题:{{title}}</li>
<li>内容:{{ content }}</li>
</ul>
</template>
<script setup>
defineProps(['id', 'title', 'content'])
</script>
第二种写法,从query中读取
typescript
children: [{
name: 'd',
path: 'detail',
component: () => import('@/pages/Detail.vue'),
props(route) { // 函数写法,可以自己决定将什么作为props给路由组件
return route.query
}
}]
// 注意News.vue需要改为query传参路由跳转
<router-link :to="{
name: 'd',
query: {
id: n.id,
title: n.title,
content: n.content
}
}">{{n.title}}</router-link>
第三种写法,对象写法,可以自己决定将什么作为props给路由组件(使用极少,不能动态内容)
typescript
props: {
id: 123,
title: '新闻详情',
content: '新闻内容'
}
replace属性
页面跳转默认是push模式,页面记录可以前进后退,router-link
添加replace属性即可实现替换当前记录,例如:
vue
<router-link replace :to="{name:'jia'}">首页</router-link>
编程式路由导航
不通过点击router-link
进行路由页面跳转,比如我们打开页面3s之后自动跳转到新闻页面
在App.vue页面加载时执行3s延迟执行事件,使用router.push
跳转,入参和to一样,可以是字符串也可以是对象
vue
<script setup lang="ts">
import { onMounted } from 'vue';
import { useRouter } from 'vue-router';
const router = useRouter();
onMounted(() => {
setTimeout(() => {
router.push({
name: 'news'
});
}, 3000);
});
</script>
新闻列表项都加一个按钮,点击按钮去看新闻详情
vue
<ul><li v-for="n in news" :key="n.id">
<button @click="showNewsDetail(n)">点我看详情</button>
<router-link :to="{
name: 'd',
query: {
id: n.id,
title: n.title,
content: n.content
}
}">{{n.title}}</router-link>
</li></ul>
<script setup lang="ts">
import { reactive } from 'vue';
import { useRouter } from 'vue-router';
const router = useRouter();
function showNewsDetail(n) {
router.push({
name: 'd',
query: n
})
}
...
</script>
使用params实现同样的功能
typescript
// 路由规则修改path和props为params方式传参
children: [{
name: 'd',
path: 'detail/:id/:title/:content',
component: () => import('@/pages/Detail.vue'),
props(route) {
return route.params
}
}]
// News.vue 修改点击事件的时候params作为push参数
function showNewsDetail(n) {
router.push({
name: 'd',
params: n
})
}
路由重定向
给路由规则添加如下内容即可,指定重定向到那个首页路由
json
{
path: '/',
redirect: '/home'
}