我创建了这个 Vue.js 路由器示例来让我了解路由的工作原理。我故意从 CDN 加载所有内容,以便任何人看到这个后,都可以立即开始学习,而不必学习如何导入依赖项等。
我的问题是,我应该在哪里放置根据该路由的路由参数从 JSON API 获取数据的方法?在应用程序中,还是在组件中?
如果我的问题看起来很幼稚,请原谅。我想我已经快到了。
运行代码片段,然后单击“整页”以更好地查看。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Simple Vue.js Router Example</title>
<!-- VUE JS v2.6.1 -->
<script src="https://unpkg.com/vue/dist/vue.js"></script>
<!-- VUE ROUTER JS v3.1.3 -->
<script src="https://unpkg.com/vue-router/dist/vue-router.js"></script>
<!-- BOOTSTRAP CSS v4.3.1 -->
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
<!-- GOOGLE FONT CSS - Roboto Mono -->
<link href="https://fonts.googleapis.com/css?family=Roboto+Mono:100,300,400,500,700&display=swap" rel="stylesheet">
<!-- GOOGLE FONT CSS - Material Icons -->
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
<style type="text/css">
body {
font-family: 'Roboto Mono', monospace;
font-weight: 400;
font-size: 1rem;
background-color: #e0e0e0;
}
.active {
color: #f44336;
}
</style>
</head>
<body>
<!-- VUE APP - PARENT CONTAINER -->
<div id="app" class="container">
<!-- HEADER CONTAINER -->
<header>
<hr>
<h1>Header</h1>
<p>Static header text</p>
<ul>
<li>
<router-link to="/">/ </router-link>
</li>
<li>
<router-link to="/users">/users</router-link>
</li>
<li>
<router-link to="/users/123">/users/123</router-link>
</li>
<li>
<router-link to="/posts">/posts</router-link>
</li>
<li>
<router-link to="/posts/456">/posts/456</router-link>
</li>
<li>
<router-link to="/unsaved-changes">/unsaved-changes</router-link>
</li>
<li>
<router-link to="/unknown-route/789">/unknown-route/789</router-link>
<br>
<small>*forwards to route /404</small>
</li>
</ul>
</header>
<!-- MAIN CONTAINER -->
<main>
<hr>
<h1>Main</h1>
<p>Static main text</p>
<router-view name="routerView0"></router-view>
<router-view name="routerView1"></router-view>
<router-view name="routerView2"></router-view>
<router-view name="routerView3"></router-view>
<router-view name="routerView4"></router-view>
<router-view name="routerView5"></router-view>
<router-view name="routerView6"></router-view>
</main>
<!-- FOOTER CONTAINER -->
<footer>
<hr>
<h1>Footer</h1>
<p>Static footer text</p>
</footer>
</div>
<!-- JAVA SCRIPT -->
<script type="text/javascript">
// DISABLE
Vue.config.productionTip = false;
// DISABLE
Vue.config.devtools = false;
// COMPONENT 0
const Component0 = {
template:
`
<div style="background-color: #bcaaa4;">
<strong>Component 0</strong>
<br>
success: route /
<br>
result: component rendered.
</div>
`
}
// COMPONENT 1
const Component1 = {
template:
`
<div style="background-color: #80deea;">
<strong>Component 1</strong>
<br>
success: route /users
<br>
result: component rendered.
</div>
`
}
// COMPONENT 2
const Component2 = {
template:
`
<div style="background-color: #80deea;">
<strong>Component 2</strong>
<br>
success: route /users/{{ $route.params.id }}
<br>
result: component rendered.
</div>
`
}
// COMPONENT 3
const Component3 = {
template:
`
<div style="background-color: #b39ddb;">
<strong>Component 3</strong>
<br>
success: route /posts
<br>
result: component rendered.
</div>
`
}
// COMPONENT 4
const Component4 = {
template:
`
<div style="background-color: #b39ddb;">
<strong>Component 4</strong>
<br>
success: route /posts/{{ $route.params.id }}
<br>
result: component rendered.
</div>
`
}
// COMPONENT 5
const Component5 = {
template:
`
<div style="background-color: #ffe082;">
<strong>Component 5</strong>
<br>
success: route /unsaved-changes
<br>
result: component rendered.
<br>
<small><strong>*If you leave this route,<br> all text typed in below will be lost.</strong></small>
<br>
<input type="text">
</div>
`,
// IN COMPOMENT ONLY...
beforeRouteLeave (to, from, next) {
const answer = window.confirm('Are you sure you want to leave this route? There are unsaved changes!')
if (answer) {
next()
} else {
next(false)
}
}
}
// COMPONENT 6
const Component6 = {
template:
`
<div style="background-color: #ef9a9a;">
<strong>Component 6</strong>
<br>
error: unknown route.
<br>
action: forwarded to route /404.
<br>
result: component rendered.
</div>
`
}
// IN THIS ROUTE I WILL RENDER THESE COMPONENTS..
const router = new VueRouter({
mode: 'hash',
linkExactActiveClass: "active",
routes: [
// ROUTE 0
{ path: '/',
// COMPONENT(S) TO RENDER IN ORDER
components: {
// ONE OR MORE...
routerView0: Component0,
}
}, // END ROUTE 0
// ROUTE 1
{ path: '/users',
// COMPONENT(S) TO RENDER
components: {
// ONE OR MORE...
routerView1: Component1,
}
}, // END ROUTE 1
// ROUTE 1.1
{ path: '/users/:id',
// COMPONENT(S) TO RENDER
components: {
// ONE OR MORE...
routerView2: Component2,
},
// REPORT WHEN THIS ROUTE IS VISITED
beforeEnter: (to, from, next) => {
// ...
console.warn('ROUTE CHANGE')
console.log('ROUTE', 'FROM:', from.path, 'TO:', to.path);
next();
}
}, // END ROUTE 1.1
// ROUTE 2
{
path: '/posts',
components: {
// ONE OR MORE...
routerView3: Component3,
}
}, // END ROUTE 2
// ROUTE 2.1
{
path: '/posts/:id',
components: {
// ONE OR MORE...
routerView4: Component4,
}, // END ROUTE 2.1
// REPORT WHEN THIS ROUTE IS VISITED
beforeEnter: (to, from, next) => {
// ...
console.warn('ROUTE CHANGE')
console.log('ROUTE', 'FROM:', from.path, 'TO:', to.path);
next();
}
},
// ROUTE UNSAVED CHANGES
{
path: '/unsaved-changes',
components: {
// ONE OR MORE...
routerView5: Component5,
}
}, // END ROUTE UNSAVED CHANGES
// REDIRECT!
{
path: '*', redirect: '/404',
// TRAP ANY UNDEFINED ROUTE AND...
// FORWARD IT TO /404 ROUTE
},
// ROUTE UNDEFINED - CUSTOM PAGE
{
path: '/404',
components: {
// ONE OR MORE...
routerView6: Component6,
}
}, // END ROUTE UNDEFINED
]
});
// WATCH EVERY ROUTE THAT IS VISITED
/*
router.beforeEach((to, from, next) => {
// ...
console.info('Global Route Watcher')
console.log('ROUTE', 'FROM:', from.path, 'TO:', to.path);
next();
});
*/
const App = new Vue({
el: '#app',
router,
data: {
},
})
</script>
</body>
</html>
最佳答案
我个人在组件内部进行获取,如果您希望组件在获取数据之前渲染并添加加载动画,您可以在created或beforeCreate钩子(Hook)上获取数据,或者您可以使用beforeRouteEnter或beforeRouteUpdate钩子(Hook)组件。
我背后的逻辑如下,如果您从组件中获取数据,只需向它们传递一个新的路由参数即可更容易测试,并且您可以避免在 App 组件上执行一些复杂的逻辑,因为它不必跟踪选择哪条路线并采取相应的行动。
关于javascript - Vue.js 路由器。将方法放在应用程序中还是组件中?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57759598/