5
5
title="Learn how to use Vue Router with the composition API"
6
6
/>
7
7
8
- 引入 ` setup ` 和 Vue 的[ 组合式 API] ( https://cn.vuejs.org/guide/extras/composition-api-faq.html ) ,开辟了新的可能性 ,但要想充分发挥 Vue Router 的潜力,我们需要使用一些新的函数来代替访问 ` this ` 和组件内导航守卫。
8
+ Vue 的[ 组合式 API] ( https://cn.vuejs.org/guide/extras/composition-api-faq.html ) 的引入开辟了新的可能性 ,但要想充分发挥 Vue Router 的潜力,我们需要使用一些新的函数来代替访问 ` this ` 和组件内导航守卫。
9
9
10
10
## 在 ` setup ` 中访问路由和当前路由
11
11
12
- 因为我们在 ` setup ` 里面没有访问 ` this ` ,所以我们不能再直接访问 ` this.$router ` 或 ` this.$route ` 。作为替代,我们使用 ` useRouter ` 和 ` useRoute ` 函数:
12
+ 因为我们在 ` setup ` 里面没有访问 ` this ` ,所以我们不能直接访问 ` this.$router ` 或 ` this.$route ` 。作为替代,我们使用 ` useRouter ` 和 ` useRoute ` 函数:
13
13
14
- ``` js
14
+ ``` vue
15
+ <script setup>
15
16
import { useRouter, useRoute } from 'vue-router'
16
17
17
- export default {
18
- setup () {
19
- const router = useRouter ()
20
- const route = useRoute ()
21
-
22
- function pushWithQuery (query ) {
23
- router .push ({
24
- name: ' search' ,
25
- query: {
26
- ... route .query ,
27
- ... query,
28
- },
29
- })
30
- }
31
- },
18
+ const router = useRouter()
19
+ const route = useRoute()
20
+
21
+ function pushWithQuery(query) {
22
+ router.push({
23
+ name: 'search',
24
+ query: {
25
+ ...route.query,
26
+ ...query,
27
+ },
28
+ })
32
29
}
30
+ </script>
33
31
```
34
32
35
- ` route ` 对象是一个响应式对象,所以它的任何属性都可以被监听,但你应该 ** 避免监听整个 ` route ` ** 对象。在大多数情况下,你应该直接监听你期望改变的参数 。
33
+ ` route ` 对象是一个响应式对象。在多数情况下,你应该 ** 避免监听整个 ` route ` ** 对象,同时直接监听你期望改变的参数 。
36
34
37
- ``` js
35
+ ``` vue
36
+ <script setup>
38
37
import { useRoute } from 'vue-router'
39
38
import { ref, watch } from 'vue'
40
39
41
- export default {
42
- setup () {
43
- const route = useRoute ()
44
- const userData = ref ()
45
-
46
- // 当参数更改时获取用户信息
47
- watch (
48
- () => route .params .id ,
49
- async newId => {
50
- userData .value = await fetchUser (newId)
51
- }
52
- )
53
- },
54
- }
40
+ const route = useRoute()
41
+ const userData = ref()
42
+
43
+ // 当参数更改时获取用户信息
44
+ watch(
45
+ () => route.params.id,
46
+ async newId => {
47
+ userData.value = await fetchUser(newId)
48
+ }
49
+ )
50
+ </script>
55
51
```
56
52
57
- 请注意,在模板中我们仍然可以访问 ` $router ` 和 ` $route ` ,所以不需要在 ` setup ` 中返回 ` router ` 或 ` route ` 。
53
+ 请注意,在模板中我们仍然可以访问 ` $router ` 和 ` $route ` ,所以如果你只在模板中使用这些对象的话,是不需要 ` useRouter ` 或 ` useRoute ` 的 。
58
54
59
55
## 导航守卫
60
56
61
- 虽然你仍然可以通过 ` setup ` 函数来使用组件内的导航守卫,但 Vue Router 将更新和离开守卫作为 组合式 API 函数公开:
57
+ Vue Router 将更新和离开守卫作为组合式 API 函数公开:
62
58
63
- ``` js
59
+ ``` vue
60
+ <script setup>
64
61
import { onBeforeRouteLeave, onBeforeRouteUpdate } from 'vue-router'
65
62
import { ref } from 'vue'
66
63
67
- export default {
68
- setup () {
69
- // 与 beforeRouteLeave 相同,无法访问 `this`
70
- onBeforeRouteLeave ((to , from ) => {
71
- const answer = window .confirm (
72
- ' Do you really want to leave? you have unsaved changes!'
73
- )
74
- // 取消导航并停留在同一页面上
75
- if (! answer) return false
76
- })
77
-
78
- const userData = ref ()
79
-
80
- // 与 beforeRouteUpdate 相同,无法访问 `this`
81
- onBeforeRouteUpdate (async (to , from ) => {
82
- // 仅当 id 更改时才获取用户,例如仅 query 或 hash 值已更改
83
- if (to .params .id !== from .params .id ) {
84
- userData .value = await fetchUser (to .params .id )
85
- }
86
- })
87
- },
88
- }
64
+ // 与 beforeRouteLeave 相同,无法访问 `this`
65
+ onBeforeRouteLeave((to, from) => {
66
+ const answer = window.confirm(
67
+ 'Do you really want to leave? you have unsaved changes!'
68
+ )
69
+ // 取消导航并停留在同一页面上
70
+ if (!answer) return false
71
+ })
72
+
73
+ const userData = ref()
74
+
75
+ // 与 beforeRouteUpdate 相同,无法访问 `this`
76
+ onBeforeRouteUpdate(async (to, from) => {
77
+ //仅当 id 更改时才获取用户,例如仅 query 或 hash 值已更改
78
+ if (to.params.id !== from.params.id) {
79
+ userData.value = await fetchUser(to.params.id)
80
+ }
81
+ })
82
+ </script>
89
83
```
90
84
91
85
组合式 API 守卫也可以用在任何由 ` <router-view> ` 渲染的组件中,它们不必像组件内守卫那样直接用在路由组件上。
@@ -94,40 +88,34 @@ export default {
94
88
95
89
Vue Router 将 RouterLink 的内部行为作为一个组合式函数 (composable) 公开。它接收一个类似 ` RouterLink ` 所有 prop 的响应式对象,并暴露底层属性来构建你自己的 ` RouterLink ` 组件或生成自定义链接:
96
90
97
- ``` js
91
+ ``` vue
92
+ <script setup>
98
93
import { RouterLink, useLink } from 'vue-router'
99
94
import { computed } from 'vue'
100
95
101
- export default {
102
- name: ' AppLink' ,
103
-
104
- props: {
105
- // 如果使用 TypeScript,请添加 @ts-ignore
106
- ... RouterLink .props ,
107
- inactiveClass: String ,
108
- },
109
-
110
- setup (props ) {
111
- const {
112
- // 解析出来的路由对象
113
- route,
114
- // 用在链接里的 href
115
- href,
116
- // 布尔类型的 ref 标识链接是否匹配当前路由
117
- isActive,
118
- // 布尔类型的 ref 标识链接是否严格匹配当前路由
119
- isExactActive,
120
- // 导航至该链接的函数
121
- navigate
122
- } = useLink (props)
123
-
124
- const isExternalLink = computed (
125
- () => typeof props .to === ' string' && props .to .startsWith (' http' )
126
- )
127
-
128
- return { isExternalLink, href, navigate, isActive }
129
- },
130
- }
96
+ const props = defineProps({
97
+ // 如果使用 TypeScript,请添加 @ts-ignore
98
+ ...RouterLink.props,
99
+ inactiveClass: String,
100
+ })
101
+
102
+ const {
103
+ // 解析出来的路由对象
104
+ route,
105
+ // 用在链接里的 href
106
+ href,
107
+ // 布尔类型的 ref 标识链接是否匹配当前路由
108
+ isActive,
109
+ // 布尔类型的 ref 标识链接是否严格匹配当前路由
110
+ isExactActive,
111
+ // 导航至该链接的函数
112
+ navigate
113
+ } = useLink(props)
114
+
115
+ const isExternalLink = computed(
116
+ () => typeof props.to === 'string' && props.to.startsWith('http')
117
+ )
118
+ </script>
131
119
```
132
120
133
121
注意在 RouterLink 的 ` v-slot ` 中可以访问与 ` useLink ` 组合式函数相同的属性。
0 commit comments