key - value
的对应关系route
需要经过路由器 router
的管理pages
或 views
,一般组件一般存放在 components
后端路由:
value
是function
, 用来处理客户端提交的请求router.get(path, function(req, res))
前端路由:
value
是component
,用于展示页面内容<Route path="/test" component={Test}>
path
变为/test
时, 当前路由组件就会变为Test
组件history
模式优点:URL中不带有 #
,更加美观,更接近传统的网站URL
缺点:后期项目上线需要服务端配合处理路径问题,否则容易 404
Vue2:
mode: 'history'
Vue3:
history: createWebHistory()
React:
<BrowserRouter></BrowserRouter>
hash
模式优点:兼容性更好,不需要服务端处理路径
缺点:在SEO优化方面相对较差
@/router/index.ts
typescript// 创建一个路由器并暴露出去
import { createRouter, createWebHistory } from 'vue-router';
import Home from '@/views/Home.vue';
import News from '@/views/News.vue';
import About from '@/views/About.vue';
const router = createRouter({
history: createWebHistory(), // 路由器工作模式
routes: [ // 路由规则
{
path: '/home',
component: Home
},
{
name: 'xinwen',
path: '/news',
component: News
},
{
path: '/about',
component: About
}
]
});
export default router;
@/App.vue
vue<template> <div class="app"> <h2 class="title">Vue 路由</h2> <!-- 导航区 --> <div class="nav"> <RouterLink to="/home" active-class="active">首页</RouterLink> <RouterLink :to="{name: 'xinwen'}" active-class="active">新闻</RouterLink> <RouterLink :to="{path: '/about'}" active-class="active">关于</RouterLink> </div> <!-- 展示区 --> <div class="content"> <RouterView /> </div> </div> </template> <script setup lang="ts"> import { RouterView, RouterLink } from 'vue-router'; </script>
为每一个路由配置 children
属性,子级路由不需要写 /
,<RouterLink>
中 to
属性指向的 path 要写完整
typescriptconst router = createRouter({
history: createWebHistory(), // 路由器工作模式
routes: [ // 路由规则
{
path: '/home',
component: Home
},
{
name: 'xinwen',
path: '/news',
component: News,
children: [
{
path: 'detail', // 子级路由不需要写 /
component: Detail
}
]
},
{
path: '/about',
component: About
}
]
});
vue<RouterLink to="/news/detail">{{ news.title }}</RouterLink> <div class="content"> <RouterView></RouterView> </div>
传递参数
vue<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="{ path: '/news/detail', query: { id: news.id, title: news.title, content: news.content } }"> {{ news.title }} </RouterLink> </li> </ul>
接收参数
vue<template> <ul class="news-list"> <li>编号:{{ query.id }}</li> <li>标题:{{ query.title }}</li> <li>内容:{{ query.content }}</li> </ul> </template> <script setup lang="ts"> import { toRefs } from 'vue'; import { useRoute } from 'vue-router'; let route = useRoute(); let { query } = toRefs(route); </script>
path: 'detail/:id/:title/:content?'
?
表示<RouterLink>
中 to
采用对象写法时,要使用 name
而不是 path
传递参数
vue<!-- 写法一 --> <!-- <RouterLink :to="`/news/detail/${news.id}/${news.title}/${news.content}`">{{ news.title }}</RouterLink> --> <!-- 写法二 --> <RouterLink :to="{ name: 'xiangqing', params: { id: news.id, title: news.title, content: news.content } }">
接收参数
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"> import { toRefs } from 'vue'; import { useRoute } from 'vue-router'; let route = useRoute(); // let { query } = toRefs(route); </script>
在路由规则中配置
typescript{
path: 'detail/:id/:title/:content?', // 子级路由不需要写 /
name: 'xiangqing',
component: Detail,
// 写法一,将路由收到的所有 params 参数作为 props 传给路由组件
// props: true
// 写法二,自己决定将什么作为 props 传给路由组件
/* props(route) {
return route.query; // 可以传递 query 参数
} */
// 写法三,对象写法,数据是写死的
props: {
a: 100,
b: 200,
c: 300
}
}
接收时,直接在路由组件中使用 defineProps()
进行调用即可
vue<template> <ul class="news-list"> <li>编号:{{ id }}</li> <li>标题:{{ title }}</li> <li>内容:{{ content }}</li> </ul> </template> <script setup lang="ts"> defineProps(['id', 'title', 'content']) </script>
优雅!
路由的跳转默认是 push 模式,可以通过在 <RouterLink>
上添加 replace
属性切换为 replace 模式
使用 useRouter()
得到路由器,可进行 push 和 replace 操作
vue<template> <div class="news"> <!-- news 导航区 --> <ul> <li v-for="news in newsList" :key="news.id"> <button @click="showNewsDetail(news)">查看新闻</button> <RouterLink :to="{ name: 'xiangqing', params: { id: news.id, title: news.title, content: news.content } }"> {{ news.title }} </RouterLink> </li> </ul> <!-- news 展示区 --> <div class="content"> <RouterView></RouterView> </div> </div> </template> <script setup lang="ts"> import { reactive } from 'vue'; import { useRouter } from 'vue-router'; const newsList = reactive([ { id: 'abc01', title: '新闻001', content: '这是新闻001的内容abc' }, { id: 'abc02', title: '新闻002', content: '这是新闻002的内容def' }, { id: 'abc03', title: '新闻003', content: '这是新闻003的内容ghi' }, { id: 'abc04', title: '新闻004', content: '这是新闻004的内容jkl' } ]); const router = useRouter(); const showNewsDetail = (news: {id: string, title: string, content: string}) => { router.push({ name: 'xiangqing', params: { id: news.id, title: news.title, content: news.content } }) } </script>
typescript {
path: '/',
redirect: '/home'
}
redirect 也可以接收一个函数,动态返回重定向目标
typescript {
// /search/screens -> /search?q=screens
path: '/search/:searchText',
redirect: to => {
// 方法接收目标路由作为参数
// return 重定向的字符串路径/路径对象
return { path: '/search', query: { q: to.params.searchText } }
},
}
本文作者:Morales
本文链接:
版权声明:本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 License 许可协议。转载请注明出处!