Skip to content

Commit ebdfc65

Browse files
committed
simple router
1 parent 65bd1cb commit ebdfc65

File tree

2 files changed

+78
-30
lines changed

2 files changed

+78
-30
lines changed

src/.vitepress/config.ts

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -205,20 +205,20 @@ export const sidebar = {
205205
text: 'Best Practices',
206206
items: [
207207
{
208-
text: 'Accessibility',
209-
link: '/guide/best-practices/accessibility'
210-
},
211-
{
212-
text: 'Security',
213-
link: '/guide/best-practices/security'
208+
text: 'Production Deployment',
209+
link: '/guide/best-practices/production-deployment'
214210
},
215211
{
216212
text: 'Performance',
217213
link: '/guide/best-practices/performance'
218214
},
219215
{
220-
text: 'Production Deployment',
221-
link: '/guide/best-practices/production-deployment'
216+
text: 'Accessibility',
217+
link: '/guide/best-practices/accessibility'
218+
},
219+
{
220+
text: 'Security',
221+
link: '/guide/best-practices/security'
222222
}
223223
]
224224
},

src/guide/scaling-up/routing.md

Lines changed: 70 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -2,45 +2,93 @@
22

33
## Official Router
44

5+
<!-- TODO update links -->
6+
57
For most Single Page Applications, it's recommended to use the officially-supported [vue-router library](https://github.com/vuejs/vue-router-next). For more details, see vue-router's [documentation](https://next.router.vuejs.org/).
68

79
## Simple Routing from Scratch
810

9-
If you only need very simple routing and do not wish to involve a full-featured router library, you can do so by dynamically rendering a page-level component like this:
11+
If you only need very simple routing and do not wish to involve a full-featured router library, you can do so with [Dynamic Components](/guide/essentials/component-basics.html#dynamic-components) and update the current component state by listening to browser [`hashchange` events](https://developer.mozilla.org/en-US/docs/Web/API/Window/hashchange_event) or using the [History API](https://developer.mozilla.org/en-US/docs/Web/API/History).
12+
13+
Here's a bare-bone example:
1014

11-
```js
12-
const { createApp, h } = Vue
15+
<div class="composition-api">
1316

14-
const NotFoundComponent = { template: '<p>Page not found</p>' }
15-
const HomeComponent = { template: '<p>Home page</p>' }
16-
const AboutComponent = { template: '<p>About page</p>' }
17+
```vue
18+
<script setup>
19+
import { ref, computed } from 'vue'
20+
import Home from './Home.vue'
21+
import About from './About.vue'
22+
import NotFound from './NotFound.vue'
1723
1824
const routes = {
19-
'/': HomeComponent,
20-
'/about': AboutComponent
25+
'/': Home,
26+
'/about': About
2127
}
2228
23-
const SimpleRouter = {
24-
data: () => ({
25-
currentRoute: window.___location.pathname
26-
}),
29+
const currentPath = ref(window.___location.hash)
30+
31+
window.addEventListener('hashchange', () => {
32+
currentPath.value = window.___location.hash
33+
})
34+
35+
const currentView = computed(() => {
36+
return routes[currentPath.value.slice(1) || '/'] || NotFound
37+
})
38+
</script>
39+
40+
<template>
41+
<a href="#/">Home</a> |
42+
<a href="#/about">About</a> |
43+
<a href="#/non-existent-path">Broken Link</a>
44+
<component :is="currentView" />
45+
</template>
46+
```
47+
48+
[Try it in the Playground](https://sfc.vuejs.org/#eyJBcHAudnVlIjoiPHNjcmlwdCBzZXR1cD5cbmltcG9ydCB7IHJlZiwgY29tcHV0ZWQgfSBmcm9tICd2dWUnXG5pbXBvcnQgSG9tZSBmcm9tICcuL0hvbWUudnVlJ1xuaW1wb3J0IEFib3V0IGZyb20gJy4vQWJvdXQudnVlJ1xuaW1wb3J0IE5vdEZvdW5kIGZyb20gJy4vTm90Rm91bmQudnVlJ1xuXG5jb25zdCByb3V0ZXMgPSB7XG4gICcvJzogSG9tZSxcbiAgJy9hYm91dCc6IEFib3V0XG59XG5cbmNvbnN0IGN1cnJlbnRQYXRoID0gcmVmKHdpbmRvdy5sb2NhdGlvbi5oYXNoKVxuXG53aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcignaGFzaGNoYW5nZScsICgpID0+IHtcbiAgY3VycmVudFBhdGgudmFsdWUgPSB3aW5kb3cubG9jYXRpb24uaGFzaFxufSlcblxuY29uc3QgY3VycmVudFZpZXcgPSBjb21wdXRlZCgoKSA9PiB7XG4gIHJldHVybiByb3V0ZXNbY3VycmVudFBhdGgudmFsdWUuc2xpY2UoMSkgfHwgJy8nXSB8fCBOb3RGb3VuZFxufSlcbjwvc2NyaXB0PlxuXG48dGVtcGxhdGU+XG4gIDxhIGhyZWY9XCIjL1wiPkhvbWU8L2E+IHxcbiAgPGEgaHJlZj1cIiMvYWJvdXRcIj5BYm91dDwvYT4gfFxuICA8YSBocmVmPVwiIy9ub24tZXhpc3RlbnQtcGF0aFwiPkJyb2tlbiBMaW5rPC9hPlxuICA8Y29tcG9uZW50IDppcz1cImN1cnJlbnRWaWV3XCIgLz5cbjwvdGVtcGxhdGU+IiwiaW1wb3J0LW1hcC5qc29uIjoie1xuICBcImltcG9ydHNcIjoge1xuICAgIFwidnVlXCI6IFwiaHR0cHM6Ly9zZmMudnVlanMub3JnL3Z1ZS5ydW50aW1lLmVzbS1icm93c2VyLmpzXCJcbiAgfVxufSIsIkhvbWUudnVlIjoiPHRlbXBsYXRlPlxuICA8aDE+SG9tZTwvaDE+XG48L3RlbXBsYXRlPiIsIkFib3V0LnZ1ZSI6Ijx0ZW1wbGF0ZT5cbiAgPGgxPkFib3V0PC9oMT5cbjwvdGVtcGxhdGU+IiwiTm90Rm91bmQudnVlIjoiPHRlbXBsYXRlPlxuICA8aDE+NDA0PC9oMT5cbjwvdGVtcGxhdGU+In0=)
49+
50+
</div>
51+
52+
<div class="options-api">
2753

54+
```vue
55+
<script>
56+
import Home from './Home.vue'
57+
import About from './About.vue'
58+
import NotFound from './NotFound.vue'
59+
60+
const routes = {
61+
'/': Home,
62+
'/about': About
63+
}
64+
65+
export default {
66+
data() {
67+
return {
68+
currentPath: window.___location.hash
69+
}
70+
},
2871
computed: {
29-
CurrentComponent() {
30-
return routes[this.currentRoute] || NotFoundComponent
72+
currentView() {
73+
return routes[this.currentPath.slice(1) || '/'] || NotFound
3174
}
3275
},
33-
34-
render() {
35-
return h(this.CurrentComponent)
76+
mounted() {
77+
window.addEventListener('hashchange', () => {
78+
this.currentPath = window.___location.hash
79+
})
3680
}
3781
}
82+
</script>
3883
39-
createApp(SimpleRouter).mount('#app')
84+
<template>
85+
<a href="#/">Home</a> |
86+
<a href="#/about">About</a> |
87+
<a href="#/non-existent-path">Broken Link</a>
88+
<component :is="currentView" />
89+
</template>
4090
```
4191

42-
Combined with the [History API](https://developer.mozilla.org/en-US/docs/Web/API/History_API/Working_with_the_History_API), you can build a very basic but fully-functional client-side router. To see that in practice, check out [this example app](https://github.com/phanan/vue-3.0-simple-routing-example).
43-
44-
## Integrating 3rd-Party Routers
92+
[Try it in the Playground](https://sfc.vuejs.org/#eyJBcHAudnVlIjoiPHNjcmlwdD5cbmltcG9ydCBIb21lIGZyb20gJy4vSG9tZS52dWUnXG5pbXBvcnQgQWJvdXQgZnJvbSAnLi9BYm91dC52dWUnXG5pbXBvcnQgTm90Rm91bmQgZnJvbSAnLi9Ob3RGb3VuZC52dWUnXG5cbmNvbnN0IHJvdXRlcyA9IHtcbiAgJy8nOiBIb21lLFxuICAnL2Fib3V0JzogQWJvdXRcbn1cblxuZXhwb3J0IGRlZmF1bHQge1xuICBkYXRhKCkge1xuICAgIHJldHVybiB7XG4gICAgICBjdXJyZW50UGF0aDogd2luZG93LmxvY2F0aW9uLmhhc2hcbiAgICB9XG4gIH0sXG4gIGNvbXB1dGVkOiB7XG4gICAgY3VycmVudFZpZXcoKSB7XG4gICAgICByZXR1cm4gcm91dGVzW3RoaXMuY3VycmVudFBhdGguc2xpY2UoMSkgfHwgJy8nXSB8fCBOb3RGb3VuZFxuICAgIH1cbiAgfSxcbiAgbW91bnRlZCgpIHtcbiAgICB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcignaGFzaGNoYW5nZScsICgpID0+IHtcblx0XHQgIHRoaXMuY3VycmVudFBhdGggPSB3aW5kb3cubG9jYXRpb24uaGFzaFxuXHRcdH0pXG4gIH1cbn1cbjwvc2NyaXB0PlxuXG48dGVtcGxhdGU+XG4gIDxhIGhyZWY9XCIjL1wiPkhvbWU8L2E+IHxcbiAgPGEgaHJlZj1cIiMvYWJvdXRcIj5BYm91dDwvYT4gfFxuICA8YSBocmVmPVwiIy9ub24tZXhpc3RlbnQtcGF0aFwiPkJyb2tlbiBMaW5rPC9hPlxuICA8Y29tcG9uZW50IDppcz1cImN1cnJlbnRWaWV3XCIgLz5cbjwvdGVtcGxhdGU+IiwiaW1wb3J0LW1hcC5qc29uIjoie1xuICBcImltcG9ydHNcIjoge1xuICAgIFwidnVlXCI6IFwiaHR0cHM6Ly9zZmMudnVlanMub3JnL3Z1ZS5ydW50aW1lLmVzbS1icm93c2VyLmpzXCJcbiAgfVxufSIsIkhvbWUudnVlIjoiPHRlbXBsYXRlPlxuICA8aDE+SG9tZTwvaDE+XG48L3RlbXBsYXRlPiIsIkFib3V0LnZ1ZSI6Ijx0ZW1wbGF0ZT5cbiAgPGgxPkFib3V0PC9oMT5cbjwvdGVtcGxhdGU+IiwiTm90Rm91bmQudnVlIjoiPHRlbXBsYXRlPlxuICA8aDE+NDA0PC9oMT5cbjwvdGVtcGxhdGU+In0=)
4593

46-
If there's a 3rd-party router you prefer to use, such as [Page.js](https://github.com/visionmedia/page.js) or [Director](https://github.com/flatiron/director), integration is [similarly straightforward](https://github.com/phanan/vue-3.0-simple-routing-example/compare/master...pagejs). Here's a [complete example](https://github.com/phanan/vue-3.0-simple-routing-example/tree/pagejs) using Page.js.
94+
</div>

0 commit comments

Comments
 (0)