最近小哆啦在学习之余,发现自己在vue-router中有好多不了解的知识点,小哆啦决定梳理一遍vue-router3.x
说起前端路由有些朋友可能会问什么是路由?何为前端路由?
小哆啦查阅资料之后发现其实最开始提出路由这个概念的是后端,是来跟后端服务器进行交互的一种方式,通过不同的路径,来请求不同的资源,请求不同的页面是路由的其中一种功能。
前端随着 ajax 的流行,数据请求可以在不刷新浏览器的情况下进行。异步交互体验中最盛行的就是 SPA ------ 单页应用。单页应用不仅仅是在页面交互时无刷新的,连页面跳转都是无刷新的,为了实现单页应用,所以就有了前端路由。
前端路由是指在单页面应用(SPA)中,通过JavaScript来管理应用的不同视图之间的导航。
vue-router是什么
这里的路由并不是指我们平时所说的硬件路由器,这里的路由就是SPA(单页应用)的路径管理器 。再通俗的说,vue-router就是WebApp的链接路径管理系统。 vue-router是Vue.js官方的路由插件,它和vue.js是深度集成的,适合用于构建单页面应用。vue的单页面应用是基于路由和组件的,路由用于设定访问路径,并将路径和组件映射起来。传统的页面应用,是用一些超链接来实现页面切换和跳转的。在vue-router单页面应用中,则是路径之间的切换,也就是组件的切换。路由模块的本质 就是建立起url和页面之间的映射关系 。 至于我们为啥不能用a标签,这是因为用Vue做的都是单页应用,就相当于只有一个主的index.html页面,所以你写的标签是不起作用的,你必须使用vue-router来进行管理。
介绍
Vue Router是Vue.js官方的路由管理器。它和 Vue.js 的核⼼深度集成,让构建单⻚⾯应⽤变得易如反掌。包含的功能有:
- 动态路由匹配
- 嵌套的路由/视图表
- 模块化的、基于组件的路由配置
- 路由参数、查询、通配符
- 基于 Vue.js 过渡系统的视图过渡效果
- 细粒度的导航控制
- 带有⾃动激活的 CSS class 的链接
- HTML5 历史模式或 hash 模式,在 IE9 中⾃动降级
- ⾃定义的滚动条⾏为
使用
先说一下安装吧。
安装
js
npm install vue-router
如果在一个模块化工程中使用它,必须要通过 Vue.use()
明确地安装路由功能:
js
Vue.use(VueRouter)
创建和挂载根实例。
JS
// 记得要通过 router 配置参数注入路由,
// 从而让整个应用都有路由功能
const app = new Vue({
router
}).$mount('#app')
动态路由匹配
动态路由匹配是 Vue Router 中非常强大且灵活的功能,它允许你在路由配置中定义带有动态部分的路径,并根据这些动态部分动态渲染组件或执行逻辑。
-
路由配置 在路由配置中使用冒号
:
来表示动态的部分,这部分会被当作参数添加到$route.params
对象中。javascriptconst routes = [ { path: '/user/:id', component: User, props: true, // 将$route.params作为组件的props传递 children: [ { path: 'profile', component: UserProfile, }, { path: 'posts', component: UserPosts, }, ], }, ];
上述例子中,
/user/:id
定义了一个动态路由,:id
是动态的部分,例如/user/123
。路由还包含了两个子路由:/user/:id/profile
和/user/:id/posts
。 -
组件中的使用 在匹配到动态路由时,路由参数会自动添加到
$route.params
对象中,可以在组件中通过$route.params
来获取这些参数。vue<!-- User.vue --> <template> <div> <h2>User Page</h2> <p>User ID: {{ $route.params.id }}</p> <!-- 匹配子路由时,子组件会渲染到这里 --> <router-view></router-view> </div> </template> <script> export default { // 组件逻辑 }; </script>
在这个例子中,
$route.params.id
就是动态路由中的参数,例如当访问/user/123
时,$route.params.id
就是123
。 -
嵌套路由 动态路由和嵌套路由可以结合使用,形成更复杂的路由结构。在上述的路由配置中,
/user/:id
下包含了两个子路由:/user/:id/profile
和/user/:id/posts
。这种嵌套结构可以更好地组织和管理不同层次的页面。 -
编程式导航 在组件中,你可以使用
$router.push
进行编程式导航,传递不同的动态参数来匹配不同的路径。javascript// 编程式导航 this.$router.push('/user/123');
这样的导航会触发动态路由的匹配,并在组件中更新相应的参数。
5.响应路由参数的变化
当使用路由参数时,例如从 /user/foo
导航到 /user/bar
,原来的组件实例会被复用 。因为两个路由都渲染同个组件,比起销毁再 创建,复用则显得更加高效。不过,这也意味着组件的生命周期钩子不会再被调用。
复用组件时,想对路由参数的变化作出响应的话,你可以简单地 watch (监测变化) $route
对象:
js
const User = {
template: '...',
watch: {
$route(to, from) {
// 对路由变化作出响应...
}
}
}
或者使用 beforeRouteUpdate
导航守卫:
js
const User = {
template: '...',
beforeRouteUpdate(to, from, next) {
// react to route changes...
// don't forget to call next()
}
}
有时候,同一个路径可以匹配多个路由,此时,匹配的优先级就按照路由的定义顺序:路由定义得越早,优先级就越高。
嵌套路由
嵌套路由是指在 Vue Router 中,一个路由可以包含另一个路由,形成一个嵌套的关系。这种嵌套的结构使得你可以更好地组织和管理复杂的页面布局,其中某些部分的渲染是由子路由处理的。例如:
text
/user/foo/profile /user/foo/posts
+------------------+ +-----------------+
| User | | User |
| +--------------+ | | +-------------+ |
| | Profile | | +------------> | | Posts | |
| | | | | | | |
| +--------------+ | | +-------------+ |
+------------------+ +-----------------+
借助 vue-router
,使用嵌套路由配置,就可以很简单地表达这种关系。
-
路由配置:
在路由配置中,通过
children
属性定义子路由。javascriptconst routes = [ { path: '/dashboard', component: Dashboard, children: [ { path: 'profile', component: UserProfile, }, { path: 'posts', component: UserPosts, }, ], }, ];
在上述配置中,
/dashboard
路由下包含了两个子路由:/dashboard/profile
和/dashboard/posts
。 -
组件中的使用:
在父组件中通过
<router-view>
标签来指定子路由的渲染位置。vue<!-- Dashboard.vue --> <template> <div> <h2>Dashboard</h2> <router-view></router-view> </div> </template> <script> export default { // 父组件逻辑 }; </script>
当访问
/dashboard
时,Dashboard
组件会渲染,并在<router-view>
处渲染当前活动的子路由。 -
编程式导航:
在父组件中使用
$router.push
进行导航到子路由。javascript// 编程式导航到子路由 this.$router.push('/dashboard/profile');
-
嵌套子路由的组件:
在子路由对应的组件中,可以通过
$route
对象来访问路由参数。vue<!-- UserProfile.vue --> <template> <div> <h3>User Profile</h3> <p>User ID: {{ $route.params.id }}</p> </div> </template> <script> export default { // 子路由组件逻辑 }; </script>
-
命名视图(Named Views):
对于复杂的布局,你可以使用命名视图来同时渲染多个视图。
vue<!-- Dashboard.vue --> <template> <div> <h2>Dashboard</h2> <router-view name="profile"></router-view> <router-view name="posts"></router-view> </div> </template> <script> export default { // 父组件逻辑 }; </script>
在路由配置中,使用
components
属性定义多个组件。javascriptconst routes = [ { path: '/dashboard', components: { default: Dashboard, profile: UserProfile, posts: UserPosts, }, }, ];
每个命名视图对应于一个具体的子路由。
通过这些方式,嵌套路由使得你可以更好地组织和管理复杂的页面结构,使得代码结构清晰,可维护性更强。
编程式的导航
编程式导航是指通过代码来实现路由的切换,而不是通过用户的导航行为(如点击链接)触发路由的变化。Vue Router 提供了一些方法用于编程式导航,常用的方法包括 $router.push
、$router.replace
、$router.go
等。
编程式导航方法 | 声明式导航对应方式 |
---|---|
$router.push 方法: |
<router-link to="/user/123">User Profile</router-link> |
$router.replace 方法: |
<router-link :to="..." replace> |
$router.go 方法: |
通常不直接有对应的声明式导航方式,用于在导航历史中前进或后退 |
$router.push
方法
$router.push
方法用于导航到一个新的 URL。它接受一个包含 path
、query
、params
等选项的对象。
javascript
this.$router.push({ path: '/user/123', query: { name: '张三' } });
在组件内部,你可以这样使用:
javascript
// 在组件中使用 $router.push
methods: {
navigateToUserPage() {
this.$router.push({ name: 'user', params: { id: 123 } });
}
}
$router.replace
方法
$router.replace
方法与 $router.push
类似,但是它不会在导航历史中留下新的记录,而是替换当前的历史记录。
javascript
this.$router.replace({ path: '/user/123', query: { name: '张三' } });
$router.go
方法
$router.go
方法用于在导航历史中前进或后退指定步数。
javascript
// 后退一步
this.$router.go(-1);
// 前进一步
this.$router.go(1);
- 使用命名路由
在路由配置中定义了命名路由,可以通过名称进行导航。
javascript
// 在路由配置中定义命名路由
const routes = [
{ path: '/user/:id', name: 'user', component: User },
];
// 在组件中使用命名路由
this.$router.push({ name: 'user', params: { id: 123 } });
- 使用路由路径
直接指定路径进行导航。
javascript
this.$router.push('/user/123');
注意事项
- 在组件内部可以通过
this.$router
访问路由实例。 - 在使用编程式导航时,确保目标路径是有效的,并且对应的组件已经在路由配置中定义。
- 使用编程式导航时,可以携带路由参数、查询参数等信息,具体取决于路由配置的定义。
编程式导航通常在用户进行某些操作后触发,例如提交表单、点击按钮等。在这些情况下,你可以使用编程式导航来实现页面的切换。
命名路由
命名路由是在 Vue Router 中给路由配置指定一个名称的方式。通过给路由对象添加 name
属性,你可以为路由起一个简短、有意义的名字。命名路由在编程式导航和声明式导航中都很有用。
在路由配置中使用命名路由
javascript
const routes = [
{
path: '/user/:id',
name: 'user',
component: User,
},
{
path: '/dashboard',
name: 'dashboard',
component: Dashboard,
},
];
在上述路由配置中,user
和 dashboard
就是命名路由的名称。
声明式导航中使用命名路由
在模板中使用 <router-link>
时,可以通过 to
属性指定命名路由:
html
<router-link :to="{ name: 'user', params: { id: 123 }}">User Profile</router-link>
编程式导航中使用命名路由
在组件内部,你可以使用 $router.push
、$router.replace
、$router.go
等方法中的 name
属性进行编程式导航:
javascript
// 编程式导航到命名路由
this.$router.push({ name: 'user', params: { id: 123 } });
获取当前路由的名称
在组件内部,可以通过 $route.name
获取当前路由的名称:
javascript
// 获取当前路由的名称
const currentRouteName = this.$route.name;
为何使用命名路由
-
可读性和维护性: 使用命名路由可以使代码更具可读性和维护性,尤其在大型应用中,通过名称而不是路径来标识路由更容易理解。
-
灵活性: 使用命名路由可以在不改变路由路径的情况下修改路由配置,而不会影响到使用该路由的地方。
-
动态路径参数: 命名路由可以更方便地处理动态路径参数,如
:id
。
重定向和别名
重定向(Redirects)
重定向是指在路由匹配时将用户重定向到另一个路径。在 Vue Router 中,可以通过 redirect
属性实现重定向。
在路由配置中使用重定向
javascript
const routes = [
{
path: '/',
redirect: '/home', // 将根路径重定向到 /home
},
{
path: '/home',
component: Home,
},
{
path: '/dashboard',
redirect: '/home', // 将 /dashboard 重定向到 /home
},
];
在上述示例中,如果用户访问根路径 /
,将被重定向到 /home
;如果用户访问 /dashboard
,同样会被重定向到 /home
。
重定向函数
你还可以使用一个函数来动态计算重定向目标。函数接收 to
路由对象作为参数,你可以基于当前的路由状态动态地决定重定向目标。
javascript
const routes = [
{
path: '/admin',
redirect: to => {
// 动态计算重定向目标
if (isAdminUser()) {
return '/admin/dashboard';
} else {
return '/login';
}
},
},
// ...
];
重定向的使用场景:
- 默认首页: 重定向常用于将用户导航到默认首页。例如,将根路径
/
重定向到/home
。 - 路由重构: 在进行路由结构调整或优化时,可以使用重定向确保用户访问旧路径时被正确导向到新路径,而不会导致404错误。
- 动态条件重定向: 可以使用函数来动态计算重定向目标,根据用户的状态或权限进行条件性的重定向。
别名(Alias)
别名是指为路由创建额外的路径,而不改变该路由的实际路径。这在需要提供多个路径访问同一组件的情况下很有用。在 Vue Router 中,可以通过 alias
属性实现别名。
在路由配置中使用别名:****
javascript
const routes = [
{
path: '/about',
component: About,
alias: '/about-us', // 创建别名,/about-us 也会访问 About 组件
},
{
path: '/contact',
component: Contact,
},
];
在上述示例中,当用户访问 /about
或 /about-us
时,都会渲染 About
组件。
别名函数:
别名也可以是一个函数,允许你动态计算别名路径。
javascript
const routes = [
{
path: '/admin',
component: Admin,
alias: to => {
// 动态计算别名路径
return `/dashboard${to.path}`;
},
},
// ...
];
通过使用别名和重定向,你可以更灵活地配置路由,适应不同的导航需求和场景。这些功能允许你以一种更动态和可扩展的方式管理路由。
重定向的使用场景:
- 默认首页: 重定向常用于将用户导航到默认首页。例如,将根路径
/
重定向到/home
。 - 路由重构: 在进行路由结构调整或优化时,可以使用重定向确保用户访问旧路径时被正确导向到新路径,而不会导致404错误。
- 动态条件重定向: 可以使用函数来动态计算重定向目标,根据用户的状态或权限进行条件性的重定向。
结合使用场景
- 权限控制: 通过结合使用重定向和别名,可以实现基于用户权限的导航控制。例如,用户未登录时重定向到登录页面,同时提供别名以确保旧路径的兼容性。
- 路由模块化: 当应用结构较为庞大,路由配置较为复杂时,可以使用别名和重定向来模块化路由配置,提高可维护性。
- A/B 测试: 在进行 A/B 测试时,可以使用别名为不同版本提供不同路径,而不改变实际路由逻辑。
路由组件传参
在 Vue Router 中,路由组件传参有多种方式,主要包括动态路径参数、查询参数、状态管理(如 Vuex)、props 和路由元信息等。下
1. 动态路径参数
动态路径参数是指在路由路径中使用冒号 :
定义的参数,这些参数会被 Vue Router 解析并作为 $route.params
对象传递给路由组件。
在路由配置中定义动态路径参数
javascript
const routes = [
{
path: '/user/:id',
component: User,
},
];
在路由组件中接收动态路径参数
javascript
// User.vue
export default {
mounted() {
// 获取动态路径参数
const userId = this.$route.params.id;
console.log('User ID:', userId);
},
};
2. 查询参数
查询参数是指在 URL 中使用 ?
后跟的键值对,通过 $route.query
对象传递给路由组件。
在路由组件中接收查询参数
javascript
// User.vue
export default {
mounted() {
// 获取查询参数
const queryParam = this.$route.query.param;
console.log('Query Parameter:', queryParam);
},
};
3. 状态管理(Vuex)
Vuex 是 Vue.js 的状态管理库,通过 Vuex 可以实现全局状态的管理,从而在不同的组件中传递数据。
在路由组件中使用 Vuex 状态
javascript
// 在路由组件中使用 Vuex 状态
export default {
computed: {
// 从 Vuex 获取状态
userName() {
return this.$store.state.user.name;
},
},
};
4. Props
可以通过 props
将路由参数传递给组件。在路由配置中使用 props: true
,然后在组件中通过 props
接收参数。
在路由配置中启用 props
javascript
const routes = [
{
path: '/user/:id',
component: User,
props: true, // 启用 props
},
];
在路由组件中接收 props
javascript
// User.vue
export default {
props: ['id'],
mounted() {
// 在组件中使用 props
console.log('User ID:', this.id);
},
};
5. 路由元信息(Meta)
可以通过路由元信息传递额外的信息给路由组件。
在路由配置中定义元信息
javascript
const routes = [
{
path: '/user/:id',
component: User,
meta: { requiresAuth: true },
},
];
在路由组件中接收元信息
javascript
// User.vue
export default {
beforeRouteEnter(to, from, next) {
// 获取元信息
const requiresAuth = to.meta.requiresAuth;
console.log('Requires Auth:', requiresAuth);
// 使用 next 函数接收参数,可在组件实例创建前访问组件实例
next(vm => {
// 在组件实例内部使用元信息
console.log('Inside Component - Requires Auth:', vm.$route.meta.requiresAuth);
});
},
};
注意
- 动态路径参数: 动态路径参数会在 URL 中展示,例如
/user/123
中的123
。 - 查询参数: 查询参数会在 URL 中展示,例如
/user?id=123
中的id=123
。 - 状态管理(Vuex): Vuex 状态不会直接在 URL 中展示。 Vuex 是用于在整个应用中共享状态的,不会影响当前路由的 URL。
- Props: Props 通过组件的属性传递,不会在 URL 中展示,如果
props
是一个对象,它会被按原样设置为组件属性。当props
是静态的时候有用。 - 路由元信息(Meta): 路由元信息不会直接在 URL 中展示。它是附加在路由配置中的元信息,用于在路由组件内部访问附加信息,而不会影响 URL。
路由守卫
导航守卫(Navigation Guards)是 Vue Router 提供的一组用于在路由导航过程中进行控制的钩子函数。这些钩子函数允许你在导航到某个路由之前或之后执行一些逻辑,例如进行权限验证、取消导航、修改路由参数等。
Vue Router 提供了三种导航守卫:
- 全局导航守卫: 这些守卫影响所有路由,包括全局
beforeEach
、beforeResolve
、afterEach
。 - 路由独享的守卫: 这些守卫只会影响单个路由,可以在路由配置中使用
beforeEnter
。 - 组件内的守卫: 这些守卫只会影响某个组件,包括
beforeRouteEnter
、beforeRouteUpdate
、beforeRouteLeave
。
1. 全局导航守卫
beforeEach(to, from, next)
- 注意事项:
- 必须调用
next()
才能继续导航,否则路由会被中断。 - 如果多次调用
next()
,导航会按照调用的顺序执行。
- 必须调用
- 使用场景:
- 权限验证:在每个路由导航前检查用户是否有权限访问。
- 页面切换动画:在导航前执行一些动画效果。
beforeResolve(to, from, next)
挺讨厌66用由于用咿咿呀呀咿咿呀呀一样一样咿呀咿呀呦也有一家他v'b'b'v'c'b'n'n'b'v'c't'yvbbvcbnnbvcty
- 注意事项:
- 通常用于异步路由组件的解析,一般情况下不需要特别关注。
- 使用场景:
- 在确认导航前解析异步组件,确保组件在导航完成时已经加载完毕。
afterEach(to, from)
- 注意事项:
- 无法中断导航,因为它在导航完成后触发。
- 不能修改导航的结果。
- 使用场景:
- 页面埋点:在每个导航完成后执行埋点逻辑。
- 日志记录:记录用户的访问记录。
javascript
const router = new VueRouter({
routes: [...],
});
router.beforeEach((to, from, next) => {
// 在路由导航前执行逻辑,例如权限验证
if (to.meta.requiresAuth && !userLoggedIn()) {
next('/login');
} else {
next();
}
});
router.beforeResolve((to, from, next) => {
// 在导航被确认之前执行逻辑,例如解析异步路由组件
resolveAsyncComponent(to, next);
});
router.afterEach((to, from) => {
// 在每个导航完成后执行逻辑,例如埋点
trackPageView(to.path);
});
2. 路由独享的守卫
beforeEnter(to, from, next)
- 注意事项:
- 必须调用
next()
才能继续导航,否则路由会被中断。 - 在这个守卫中无法访问组件实例
this
。
- 必须调用
- 使用场景:
- 特定路由的权限验证:对某个路由独立进行权限验证
javascript
const routes = [
{
path: '/dashboard',
component: Dashboard,
beforeEnter: (to, from, next) => {
// 在进入路由前执行逻辑
if (isAdmin()) {
next();
} else {
next('/login');
}
},
},
];
3. 组件内的守卫
-
beforeRouteEnter(to, from, next)
- 注意事项:
- 由于在导航前触发,因此无法直接访问组件实例
this
。 - 必须通过
next
回调函数中的参数访问组件实例。
- 由于在导航前触发,因此无法直接访问组件实例
- 使用场景:
- 需要在组件进入前执行逻辑,例如在进入前弹出确认框。
beforeRouteUpdate(to, from, next)
- 注意事项:
- 在组件复用时触发。
- 适用于需要在路由更新时执行逻辑,如重新请求数据。
- 使用场景:
- 在路由更新时,例如从
/user/1
切换到/user/2
,需要重新加载用户数据。
- 在路由更新时,例如从
beforeRouteLeave(to, from, next)
- 注意事项:
- 在离开当前路由时触发。
- 适用于需要在离开组件前执行清理操作的场景。
- 使用场景:
- 在用户离开编辑页面时,弹出确认框询问是否保存未提交的数据。
- 注意事项:
javascript
export default {
beforeRouteEnter(to, from, next) {
// 在进入该组件前执行逻辑,不能访问组件实例
if (userNeedsConfirmation()) {
next(vm => {
// 可以访问组件实例
vm.showConfirmationDialog();
});
} else {
next();
}
},
beforeRouteUpdate(to, from, next) {
// 在路由更新但是复用该组件时触发
// 例如,可以在这里重新请求组件数据
fetchData();
next();
},
beforeRouteLeave(to, from, next) {
// 在离开当前路由时触发
// 可以执行一些清理操作
cleanup();
next();
},
};
next总结
next()
用于继续导航。next(false)
用于中断导航。next('/path')
用于重定向到指定路径。next(error)
用于中断导航并处理错误。next(vm => {})
用于在组件实例创建后执行逻辑。
完整的导航解析流程
- 导航被触发: 当用户点击页面中的链接或通过编程式导航(
router.push
、router.replace
等)时,导航被触发。 - 触发全局前置守卫: 所有注册的全局
beforeEach
导航守卫被调用。这是在任何路由改变之前执行的全局守卫,用于执行一些全局的任务,例如权限验证。 - 触发路由独享的守卫: 对于目标匹配到的路由,执行它们独享的
beforeEnter
导航守卫。这是在全局守卫之后、路由独享守卫之前执行的守卫。 - 触发解析异步组件: 如果目标路由包含异步加载的组件,会触发
beforeResolve
导航守卫,用于解析异步组件。 - 触发全局解析守卫: 所有注册的全局
beforeResolve
导航守卫被调用。这是在路由解析完成之前执行的守卫。 - 导航被确认: 调用
next()
表示导航被确认,可以继续。如果在上述步骤中没有中断导航的情况下,导航将被确认。 - 更新视图: 导航被确认后,Vue Router 会更新视图,将新的组件渲染到页面中。
- 触发全局后置守卫: 所有注册的全局
afterEach
导航守卫被调用。这是在视图更新之后执行的全局守卫,用于执行一些全局的任务,例如页面埋点。
路由元信息
路由元信息是 Vue Router 提供的一种机制,用于在路由配置中附加一些额外的信息。这些信息可以在导航守卫和组件内部使用,为路由的管理和控制提供了更多的灵活性。
在路由配置中添加路由元信息
在每个路由对象中,可以通过 meta
字段添加路由元信息。例如:
javascript
const routes = [
{
path: '/dashboard',
component: Dashboard,
meta: {
requiresAuth: true, // 用于权限验证
title: 'Dashboard Page', // 用于设置页面标题
},
},
// 其他路由配置...
];
在导航守卫中使用路由元信息
在导航守卫中,可以通过路由对象的 meta
字段访问路由元信息。例如:
javascript
router.beforeEach((to, from, next) => {
// 获取路由元信息
const requiresAuth = to.meta.requiresAuth;
// 在导航前进行权限验证
if (requiresAuth && !userLoggedIn()) {
next('/login');
} else {
next();
}
});
在组件中使用路由元信息
在组件内部,可以通过访问路由对象的 meta
字段来获取路由元信息。例如:
javascript
export default {
created() {
// 获取路由元信息
const pageTitle = this.$route.meta.title;
document.title = pageTitle || 'Default Page Title';
},
};
常见的路由元信息用途
-
权限验证: 使用
requiresAuth
之类的标志来表示该路由需要登录权限。 -
页面标题: 使用
title
字段来表示页面的标题,方便在导航守卫和组件中设置页面标题。 -
面包屑导航: 在路由元信息中添加用于生成面包屑导航的信息。
-
布局控制: 在路由元信息中添加布局相关的信息,例如是否显示侧边栏、顶部栏等。
过渡动效
过渡动效在Vue.js中是通过<transition>
组件实现的,它基于CSS过渡和一些JavaScript钩子函数。:
过渡动效的原理
-
过渡类名的生成: 过渡类名是由
<transition>
组件的name
属性生成的,这个属性定义了过渡类名的前缀。例如,如果name
设置为"fade",则相关的过渡类名将是"fade-enter"、"fade-enter-active"、"fade-enter-to"等。 -
触发时机: 过渡动效分为进入(enter)和离开(leave)两个阶段。这些阶段是在元素插入或从DOM中移除时触发的,通常通过
v-if
、v-show
或动态组件进行切换。 -
CSS过渡类名: Vue会自动根据状态为元素添加或移除相应的CSS类名,这些类名可以用于定义过渡效果。常见的类名有
.enter-active-class
、.leave-active-class
、.enter-class
、.leave-class
等。
过渡动效的使用
- 基本结构: 使用
<transition>
包裹需要过渡的元素。
vue
<transition name="fade">
<!-- 这里是需要过渡的元素 -->
<div v-if="show" class="box">
Content to be transitioned
</div>
</transition>
- 定义过渡效果样式: 在样式表中定义过渡效果的相关样式。
css
/* 定义过渡效果的样式 */
.fade-enter-active, .fade-leave-active {
transition: opacity 1s;
}
.fade-enter, .fade-leave-to {
opacity: 0;
}
- JavaScript钩子函数: 使用
<transition>
组件提供的JavaScript钩子函数来处理过渡的不同阶段。
vue
<script>
export default {
data() {
return {
show: true,
};
},
methods: {
toggleShow() {
this.show = !this.show;
},
},
};
</script>
在上述代码中,toggleShow
方法用于切换show
的值,触发元素的进入或离开过渡。
这样,当你改变show
的值时,Vue会自动添加或移除相应的CSS类名,并根据定义的样式产生过渡效果。通过结合CSS和JavaScript钩子函数,你可以灵活地实现各种过渡动效。
在Vue Router中,可以通过使用滚动行为(Scroll Behavior)来定义页面切换时的滚动效果。滚动行为可以控制路由切换时页面的滚动位置,使用户在导航之间保持流畅的滚动体验。
滚动行为
在Vue Router中配置滚动行为需要在创建VueRouter
实例时传递scrollBehavior
选项。这个选项是一个函数,接收to
和from
两个路由对象,以及savedPosition
参数,用于控制滚动行为。
javascript
const router = new VueRouter({
routes: [
// 定义你的路由
],
scrollBehavior(to, from, savedPosition) {
// 返回期望滚动到的位置
if (savedPosition) {
return savedPosition;
} else {
return { x: 0, y: 0 };
}
},
});
Scroll Behavior 函数参数
滚动行为的函数接收三个参数:
to
:表示即将进入的路由对象。from
:表示即将离开的路由对象。savedPosition
:只有在通过浏览器的前进/后退按钮触发导航时才可用。保存了在浏览器历史记录中当前导航前的滚动位置。
Scroll Behavior 函数返回值
滚动行为函数应该返回一个对象,表示期望滚动到的位置。这个对象可以包含x
和y
属性,分别表示水平和垂直方向的滚动位置。
javascript
scrollBehavior(to, from, savedPosition) {
// 通过 to.path 来判断是否进入了指定的路由
if (to.path === '/about' && from.path === '/home') {
return { x: 0, y: 0 }; // 滚动到顶部
} else {
return savedPosition || { x: 0, y: 0 }; // 使用保存的位置,或者滚动到顶部
}
}
示例
javascript
const router = new VueRouter({
routes: [
// 定义你的路由
],
scrollBehavior(to, from, savedPosition) {
if (to.hash) {
// 如果路由带有 hash 值,滚动到目标元素
return { selector: to.hash };
} else if (savedPosition) {
// 如果有 savedPosition,从保存的位置滚动
return savedPosition;
} else {
// 默认滚动到页面顶部
return { x: 0, y: 0 };
}
},
});
在这个例子中,如果路由带有哈希值(例如#section1
),则滚动到相应的元素。如果有保存的位置,使用保存的位置进行滚动。如果没有保存的位置,滚动到页面顶部。