前言
路由就是通过不同的url地址展示不同的页面或者内容; vue 路由就是把所有内容的url地址统一管理中间站,然后根据不同的模块去跳转
1.router-link
- 类似a标签,可以在不重新加载页面的情况下更改 URL
<script src="https://unpkg.com/vue@3"></script>
<script src="https://unpkg.com/vue-router@4"></script>
<div id="app">
<h1>Hello world!</h1>
<p>
<!--使用 router-link 组件进行导航 -->
<!--通过传递 `to` 来指定链接 -->
<!--`<router-link>` 将呈现一个带有正确 `href` 属性的 `<a>` 标签-->
<router-link to="/">Go to Home</router-link>
<router-link to="/about">Go to About</router-link>
</p>
<!-- 路由出口 -->
<!-- 路由匹配到的组件将渲染在这里 -->
<router-view></router-view>
</div>
2.router-view
- router-view 将显示与 url 对应的组件
// 1.定义路由组件
const Home = { template: '<div>Home</div>' }
const About = { template: '<div>About</div>' }
// 2.定义多个路由
const routes = [
{ path: '/', component: Home },
{ path: '/about', component: About },
]
// 3.创建路由实例和routes配置
const router = VueRouter.createRouter({
// 4. 内部提供了 history 模式的实现。使用hash模式
history: VueRouter.createWebHashHistory(),
routes, // `routes: routes` 的缩写
})
// 5.创建挂载实例
const app = Vue.createApp({})
app.use(router); // 可以在任意组件中以 this.$router 的形式访问它,并且以 this.$route 的形式访问当前路由
app.mount('#app')
// Home.vue
export default {
computed: {
username() {
// 获取params的值
return this.$route.params.username
},
},
methods: {
goTest() {
if (isAuthenticated) {
this.$router.push('/dashboard')
} else {
this.$router.push('/login')
}
},
},
}
3.嵌套路由
- 以/ 开头的嵌套路径将被视为根路径。允许利用组件嵌套,而不必使用嵌套的 URL
const router = new VueRouter({
routes: [
{
path: '/user/:id', component: User,
children: [
// 当 /user/:id 匹配成功,
// UserHome 会被渲染在 User 的 <router-view> 中
{ path: '', component: UserHome },
// ...其他子路由
]
}
]
})
4.动态路由
- 动态路由应用场景就是封装好的一个组件复用,然后匹配多个路径
- 带参数的动态路由匹配
const User = {
template: '<div>User</div>',
}
// 这些都会传递给 `createRouter`
const routes = [
// 动态段以冒号开始
{ path: '/users/:id', component: User },
]
// 读取路由里:id
const User = {
template: '<div>User {{ $route.params.id }}</div>',
}
// 匹配模式 =〉匹配路径 =〉$route.params
/users/:username =〉 /users/eduardo => { username: 'eduardo' }
/users/:username/posts/:postId =〉/users/eduardo/posts/123 =>{ username: 'eduardo', postId: '123' }
- 响应路由参数的变化
const User = {
template: '...',
created() {
this.$watch(
() => this.$route.params,
(toParams, previousParams) => {
// 对路由变化做出响应...
}
)
},
}
// 或者使用 beforeRouteUpdate 导航守卫,它也可以取消导航:
const User = {
template: '...',
async beforeRouteUpdate(to, from) {
// 对路由变化做出响应...
this.userData = await fetchUser(to.params.id)
},
}
5.编程式导航
- 可以通过 router.push。
// 声明式
<router-link :to="...">
// 编程式
router.push(...)
// 字符串路径
router.push('/users/eduardo')
// 带有路径的对象
router.push({ path: '/users/eduardo' })
// 命名的路由,并加上参数,让路由建立 url
router.push({ name: 'user', params: { username: 'eduardo' } })
// 带查询参数,结果是 /register?plan=private
router.push({ path: '/register', query: { plan: 'private' } })
// 带 hash,结果是 /about#team
router.push({ path: '/about', hash: '#team' })
- 如果路由提供了path,这个params则会被忽略
const username = 'eduardo'
// 我们可以手动建立 url,但我们必须自己处理编码
router.push(`/user/${username}`) // -> /user/eduardo
// 同样
router.push({ path: `/user/${username}` }) // -> /user/eduardo
// 如果可能的话,使用 `name` 和 `params` 从自动 URL 编码中获益
router.push({ name: 'user', params: { username } }) // -> /user/eduardo
// `params` 不能与 `path` 一起使用
router.push({ path: '/user', params: { username } }) // -> /user
由于属性 to 与 router.push 接受的对象种类相同,所以两者的规则完全相同。
替换当前的位置
- 它的作用类似于 router.push,唯一不同的是,它在导航时不会向 history 添加新记录,正如它的名字所暗示的那样——它取代了当前的条目。
// 声明式
<router-link :to="..." replace>
// 编程式
router.replace(...)
// 也可以直接在传递给 router.push 的 routeLocation 中增加一个属性 replace: true :
router.push({ path: '/home', replace: true })
// 相当于
router.replace({ path: '/home' })
路由history模式 window.history.go(n)。
// 向前移动一条记录,与 router.forward() 相同
router.go(1)
// 返回一条记录,与router.back() 相同
router.go(-1)
// 前进 3 条记录
router.go(3)
// 如果没有那么多记录,静默失败
router.go(-100)
router.go(100)
6.命名路由
- 命名路由的优点: 1.没有硬编码的 URL
- params 的自动编码/解码。
- 防止你在 url 中出现打字错误。
- 绕过路径排序(如显示一个)
import Vue from 'vue'
import VueRouter from 'vue-router'
Vue.use(VueRouter)
const Home = { template: '<div>This is Home</div>' }
const Foo = { template: '<div>This is Foo</div>' }
const Bar = { template: '<div>This is Bar {{ $route.params.id }}</div>' }
const router = new VueRouter({
mode: 'history',
base: __dirname,
routes: [
{ path: '/', name: 'home', component: Home },
{ path: '/foo', name: 'foo', component: Foo },
{ path: '/bar/:id', name: 'bar', component: Bar }
]
})
new Vue({
router,
template: `
<div id="app">
<h1>Named Routes</h1>
<p>Current route name: {{ $route.name }}</p>
<ul>
<li><router-link :to="{ name: 'home' }">home</router-link></li>
<li><router-link :to="{ name: 'foo' }">foo</router-link></li>
<li><router-link :to="{ name: 'bar', params: { id: 123 }}">bar</router-link></li>
</ul>
<router-view class="view"></router-view>
</div>
`
}).$mount('#app')
1.命名视图
- 一个视图使用一个组件渲染,因此对于同个路由,多个视图就需要多个组件。确保正确使用 components 配置 (带上 s):
<router-view class="view left-sidebar" name="LeftSidebar"></router-view>
<router-view class="view main-content"></router-view>
<router-view class="view right-sidebar" name="RightSidebar"></router-view>
const router = createRouter({
history: createWebHashHistory(),
routes: [
{
path: '/',
components: {
default: Home,
// LeftSidebar: LeftSidebar 的缩写
LeftSidebar,
// 它们与 `<router-view>` 上的 `name` 属性匹配
RightSidebar,
},
},
],
})
2.嵌套命名视图
<!-- UserSettings.vue -->
<div>
<h1>User Settings</h1>
<NavBar />
<router-view />
<router-view name="helper" />
</div>
// 路由
{
path: '/settings',
// 你也可以在顶级路由就配置命名视图
component: UserSettings,
children: [{
path: 'emails',
component: UserEmailsSubscriptions
}, {
path: 'profile',
components: {
default: UserProfile,
helper: UserProfilePreview
}
}]
}
7.路由组件传参
-
布尔模式 当 props 设置为 true 时,route.params 将被设置为组件的 props。
-
命名视图
// 对于有命名视图的路由,必须为每个命名视图定义 props 配置:
const routes = [
{
path: '/user/:id',
components: { default: User, sidebar: Sidebar },
props: { default: true, sidebar: false }
}
]
- 对象模式 当 props 是一个对象时,它将原样设置为组件 props。当 props 是静态的时候很有用。
const routes = [
{
path: '/promotion/from-newsletter',
component: Promotion,
props: { newsletterPopup: false }
}
]
- 函数模式 可以创建一个返回 props 的函数。这允许你将参数转换为其他类型,将静态值与基于路由的值相结合等等。
const routes = [
{
path: '/search',
component: SearchUser,
props: route => ({ query: route.query.q })
}
]
// URL /search?q=vue 将传递 {query: 'vue'} 作为 props 传给 SearchUser 组件。
参考资料: