宣告式 程式設計式 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 callthis.$router.push
.
To navigate to a different URL, userouter.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 callingrouter.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 apath
is provided, which is not the case forquery
, as shown in the example above. Instead, you need to provide thename
of the route or manually specify the wholepath
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 theto
property of therouter-link
component.
In 2.2.0+, optionally provideonComplete
andonAbort
callbacks torouter.push
orrouter.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 androuter.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 usebeforeRouteUpdate
to react to changes (e.g. fetching the user information).
#router.replace(location, onComplete?, onAbort?)
It acts likerouter.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 towindow.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 thatrouter.push
,router.replace
androuter.go
are counterparts ofwindow.history.pushState
,window.history.replaceState
andwindow.history.go
(opens new window), and they do imitate thewindow.history
APIs.
Therefore, if you are already familiar withBrowser 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
andabstract
).
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
) 下表現一致。