声明式 编程式 Declarative Programmatic
编程式的导航 | Vue Router https://router.vuejs.org/zh/guide/essentials/navigation.html
Programmatic Navigation
Aside from using <router-link>
to create anchor tags for declarative navigation, we can do this programmatically using the router's instance methods.
#router.push(location, onComplete?, onAbort?)
Note: Inside of a Vue instance, you have access to the router instance as $router
. You can therefore call this.$router.push
.
To navigate to a different URL, use router.push
. This method pushes a new entry into the history stack, so when the user clicks the browser back button they will be taken to the previous URL.
This is the method called internally when you click a <router-link>
, so clicking <router-link :to="...">
is the equivalent of calling router.push(...)
.
Declarative | Programmatic |
---|---|
<router-link :to="..."> |
router.push(...) |
The argument can be a string path, or a location descriptor object. Examples:
// literal string path
router.push('home')
// object
router.push({ path: 'home' })
// named route
router.push({ name: 'user', params: { userId: '123' } })
// with query, resulting in /register?plan=private
router.push({ path: 'register', query: { plan: 'private' } })
Note: params
are ignored if a path
is provided, which is not the case for query
, as shown in the example above. Instead, you need to provide the name
of the route or manually specify the whole path
with any parameter:
const userId = '123'
router.push({ name: 'user', params: { userId } }) // -> /user/123
router.push({ path: `/user/${userId}` }) // -> /user/123
// This will NOT work
router.push({ path: '/user', params: { userId } }) // -> /user
The same rules apply for the to
property of the router-link
component.
In 2.2.0+, optionally provide onComplete
and onAbort
callbacks to router.push
or router.replace
as the 2nd and 3rd arguments. These callbacks will be called when the navigation either successfully completed (after all async hooks are resolved), or aborted (navigated to the same route, or to a different route before current navigation has finished), respectively. In 3.1.0+, you can omit the 2nd and 3rd parameter and router.push
/router.replace
will return a promise instead if Promises are supported.
Note: If the destination is the same as the current route and only params are changing (e.g. going from one profile to another /users/1
-> /users/2
), you will have to use beforeRouteUpdate
to react to changes (e.g. fetching the user information).
#router.replace(location, onComplete?, onAbort?)
It acts like router.push
, the only difference is that it navigates without pushing a new history entry, as its name suggests - it replaces the current entry.
Declarative | Programmatic |
---|---|
<router-link :to="..." replace> |
router.replace(...) |
#router.go(n)
This method takes a single integer as parameter that indicates by how many steps to go forwards or go backwards in the history stack, similar to window.history.go(n)
.
Examples
// go forward by one record, the same as history.forward()
router.go(1)
// go back by one record, the same as history.back()
router.go(-1)
// go forward by 3 records
router.go(3)
// fails silently if there aren't that many records.
router.go(-100)
router.go(100)
#History Manipulation
You may have noticed that router.push
, router.replace
and router.go
are counterparts of window.history.pushState
, window.history.replaceState
and window.history.go
(opens new window), and they do imitate the window.history
APIs.
Therefore, if you are already familiar with Browser History APIs (opens new window), manipulating history will be super easy with Vue Router.
It is worth mentioning that Vue Router navigation methods (push
, replace
, go
) work consistently in all router modes (history
, hash
and abstract
).
Programmatic Navigation | Vue Router https://router.vuejs.org/guide/essentials/navigation.html
编程式的导航
除了使用 <router-link>
创建 a 标签来定义导航链接,我们还可以借助 router 的实例方法,通过编写代码来实现。
#router.push(location, onComplete?, onAbort?)
注意:在 Vue 实例内部,你可以通过 $router
访问路由实例。因此你可以调用 this.$router.push
。
想要导航到不同的 URL,则使用 router.push
方法。这个方法会向 history 栈添加一个新的记录,所以,当用户点击浏览器后退按钮时,则回到之前的 URL。
当你点击 <router-link>
时,这个方法会在内部调用,所以说,点击 <router-link :to="...">
等同于调用 router.push(...)
。
声明式 | 编程式 |
---|---|
<router-link :to="..."> |
router.push(...) |
该方法的参数可以是一个字符串路径,或者一个描述地址的对象。例如:
// 字符串
router.push('home')
// 对象
router.push({ path: 'home' })
// 命名的路由
router.push({ name: 'user', params: { userId: '123' }})
// 带查询参数,变成 /register?plan=private
router.push({ path: 'register', query: { plan: 'private' }})
注意:如果提供了 path
,params
会被忽略,上述例子中的 query
并不属于这种情况。取而代之的是下面例子的做法,你需要提供路由的 name
或手写完整的带有参数的 path
:
const userId = '123'
router.push({ name: 'user', params: { userId }}) // -> /user/123
router.push({ path: `/user/${userId}` }) // -> /user/123
// 这里的 params 不生效
router.push({ path: '/user', params: { userId }}) // -> /user
同样的规则也适用于 router-link
组件的 to
属性。
在 2.2.0+,可选的在 router.push
或 router.replace
中提供 onComplete
和 onAbort
回调作为第二个和第三个参数。这些回调将会在导航成功完成 (在所有的异步钩子被解析之后) 或终止 (导航到相同的路由、或在当前导航完成之前导航到另一个不同的路由) 的时候进行相应的调用。在 3.1.0+,可以省略第二个和第三个参数,此时如果支持 Promise,router.push
或 router.replace
将返回一个 Promise。
注意: 如果目的地和当前路由相同,只有参数发生了改变 (比如从一个用户资料到另一个 /users/1
-> /users/2
),你需要使用 beforeRouteUpdate
来响应这个变化 (比如抓取用户信息)。
#router.replace(location, onComplete?, onAbort?)
跟 router.push
很像,唯一的不同就是,它不会向 history 添加新记录,而是跟它的方法名一样 —— 替换掉当前的 history 记录。
声明式 | 编程式 |
---|---|
<router-link :to="..." replace> |
router.replace(...) |
#router.go(n)
这个方法的参数是一个整数,意思是在 history 记录中向前或者后退多少步,类似 window.history.go(n)
。
例子
// 在浏览器记录中前进一步,等同于 history.forward()
router.go(1)
// 后退一步记录,等同于 history.back()
router.go(-1)
// 前进 3 步记录
router.go(3)
// 如果 history 记录不够用,那就默默地失败呗
router.go(-100)
router.go(100)
#操作 History
你也许注意到 router.push
、 router.replace
和 router.go
跟 window.history.pushState
、 window.history.replaceState
和 window.history.go
(opens new window)好像, 实际上它们确实是效仿 window.history
API 的。
因此,如果你已经熟悉 Browser History APIs (opens new window),那么在 Vue Router 中操作 history 就是超级简单的。
还有值得提及的,Vue Router 的导航方法 (push
、 replace
、 go
) 在各类路由模式 (history
、 hash
和 abstract
) 下表现一致。