mirror of
https://github.com/nuxt/nuxt.git
synced 2024-11-27 16:12:12 +00:00
Merge branch 'master' into feature-layout
This commit is contained in:
commit
6b9af524aa
@ -198,15 +198,23 @@ function createRoutes (files, srcDir) {
|
|||||||
let route = { name: '', path: '', component: r(srcDir, file), _name: null }
|
let route = { name: '', path: '', component: r(srcDir, file), _name: null }
|
||||||
let parent = routes
|
let parent = routes
|
||||||
keys.forEach((key, i) => {
|
keys.forEach((key, i) => {
|
||||||
route.name = route.name ? route.name + (key === 'index' ? '' : '-' + key.replace('_', '')) : key.replace('_', '')
|
route.name = route.name ? route.name + '-' + key.replace('_', '') : key.replace('_', '')
|
||||||
let child = _.find(parent, { name: route.name })
|
let child = _.find(parent, { name: route.name })
|
||||||
if (child) {
|
if (child) {
|
||||||
if (!child.children) {
|
if (!child.children) {
|
||||||
child.children = []
|
child.children = []
|
||||||
}
|
}
|
||||||
parent = child.children
|
parent = child.children
|
||||||
|
route.path = ''
|
||||||
} else {
|
} else {
|
||||||
route.path = route.path + (key === 'index' ? (i > 0 ? '' : '/') : '/' + key.replace('_', ':'))
|
if (key === 'index' && (i + 1) === keys.length) {
|
||||||
|
route.path += (i > 0 ? '' : '/')
|
||||||
|
} else {
|
||||||
|
route.path += '/' + key.replace('_', ':')
|
||||||
|
if (key.includes('_')) {
|
||||||
|
route.path += '?'
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
route._name = '_' + hash(route.component)
|
route._name = '_' + hash(route.component)
|
||||||
@ -222,15 +230,22 @@ function createRoutes (files, srcDir) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function cleanChildrenRoutes (routes, isChild = false) {
|
function cleanChildrenRoutes (routes, isChild = false) {
|
||||||
let isOptional = true
|
let hasIndex = false
|
||||||
|
let parents = []
|
||||||
routes.forEach((route) => {
|
routes.forEach((route) => {
|
||||||
route.path = (isChild) ? route.path.replace('/', '') : route.path
|
route.path = (isChild) ? route.path.replace('/', '') : route.path
|
||||||
if (route.path === '' || route.path === '/') {
|
if ((isChild && /-index$/.test(route.name)) || (!isChild && route.name === 'index')) {
|
||||||
isOptional = false
|
hasIndex = true
|
||||||
}
|
}
|
||||||
if (isOptional && route.path.includes(':')) {
|
route.path = (hasIndex) ? route.path.replace('?', '') : route.path
|
||||||
route.path += '?'
|
if (/-index$/.test(route.name)) {
|
||||||
|
parents.push(route.name)
|
||||||
|
} else {
|
||||||
|
if (parents.indexOf(route.name.split('-').slice(0, -1).join('-') + '-index') > -1) {
|
||||||
|
route.path = route.path.replace('?', '')
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
route.name = route.name.replace(/-index$/, '')
|
||||||
if (route.children) {
|
if (route.children) {
|
||||||
delete route.name
|
delete route.name
|
||||||
route.children = cleanChildrenRoutes(route.children, true)
|
route.children = cleanChildrenRoutes(route.children, true)
|
||||||
|
185
test/fixtures/dynamic-routes/README.md
vendored
Normal file
185
test/fixtures/dynamic-routes/README.md
vendored
Normal file
@ -0,0 +1,185 @@
|
|||||||
|
# Defining custom routes with Nuxt.js
|
||||||
|
|
||||||
|
> Nuxt.js is based on `vue-router` and let you to defined custom routes easily :rocket:
|
||||||
|
|
||||||
|
## Concept
|
||||||
|
|
||||||
|
Nuxt.js generates automatically the `vue-router` configuration according to your file tree of `.vue` files inside the `pages/` directory.
|
||||||
|
|
||||||
|
## Basic routes
|
||||||
|
|
||||||
|
This file tree:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
pages/
|
||||||
|
--| team/
|
||||||
|
-----| index.vue
|
||||||
|
-----| about.vue
|
||||||
|
--| index.vue
|
||||||
|
```
|
||||||
|
|
||||||
|
will automatically generate:
|
||||||
|
|
||||||
|
```js
|
||||||
|
router: {
|
||||||
|
routes: [
|
||||||
|
{
|
||||||
|
name: 'index',
|
||||||
|
path: '/',
|
||||||
|
component: 'pages/index.vue'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'team',
|
||||||
|
path: '/team',
|
||||||
|
component: 'pages/team/index.vue'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'team-about',
|
||||||
|
path: '/team/about',
|
||||||
|
component: 'pages/team/about.vue'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Dynamic routes
|
||||||
|
|
||||||
|
To define a dynamic route with a param, you need to define a `.vue` file **prefixed by an underscore**.
|
||||||
|
|
||||||
|
This file tree:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
pages/
|
||||||
|
--| users/
|
||||||
|
-----| _id.vue
|
||||||
|
-----| index.vue
|
||||||
|
```
|
||||||
|
|
||||||
|
will automatically generate:
|
||||||
|
|
||||||
|
```js
|
||||||
|
router: {
|
||||||
|
routes: [
|
||||||
|
{
|
||||||
|
name: 'users',
|
||||||
|
path: '/users',
|
||||||
|
component: 'pages/users/index.vue'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'users-id',
|
||||||
|
path: '/users/:id',
|
||||||
|
component: 'pages/users/_id.vue'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Additional feature: validate (optional)
|
||||||
|
|
||||||
|
Nuxt.js lets you define a validator function inside your dynamic route component (In this example: `pages/users/_id.vue`).
|
||||||
|
|
||||||
|
If the validate method does not return `true`, Nuxt.js will automatically load the 404 error page.
|
||||||
|
|
||||||
|
```js
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
validate ({ params }) {
|
||||||
|
return /^\d+$/.test(params.id)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
```
|
||||||
|
|
||||||
|
## Nested Routes (children)
|
||||||
|
|
||||||
|
To define a nested route, you need to create a `.vue` file with the **same name as the directory** which contain your children views.
|
||||||
|
> Don't forget to put `<nuxt-child></nuxt-child>` inside your parent `.vue` file.
|
||||||
|
|
||||||
|
This file tree:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
pages/
|
||||||
|
--| users/
|
||||||
|
-----| _id.vue
|
||||||
|
--| users.vue
|
||||||
|
```
|
||||||
|
|
||||||
|
will automatically generate:
|
||||||
|
|
||||||
|
```js
|
||||||
|
router: {
|
||||||
|
routes: [
|
||||||
|
{
|
||||||
|
path: '/users',
|
||||||
|
component: 'pages/users.vue',
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
path: ':id',
|
||||||
|
component: 'pages/users/_id.vue',
|
||||||
|
name: 'users-id'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Dynamic Nested Routes
|
||||||
|
|
||||||
|
This file tree:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
pages/
|
||||||
|
--| posts/
|
||||||
|
-----| _slug/
|
||||||
|
--------| _name.vue
|
||||||
|
--------| comments.vue
|
||||||
|
-----| _slug.vue
|
||||||
|
-----| index.vue
|
||||||
|
--| posts.vue
|
||||||
|
```
|
||||||
|
|
||||||
|
will automatically generate:
|
||||||
|
|
||||||
|
```js
|
||||||
|
router: {
|
||||||
|
routes: [
|
||||||
|
{
|
||||||
|
path: '/posts',
|
||||||
|
component: 'pages/posts.vue',
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
path '',
|
||||||
|
component: 'pages/posts/index.vue',
|
||||||
|
name: 'posts'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: ':slug',
|
||||||
|
component: 'pages/posts/_slug.vue',
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
path: 'comments',
|
||||||
|
component: 'pages/posts/_slug/comments.vue',
|
||||||
|
name: 'posts-slug-comments'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: ':name',
|
||||||
|
component: 'pages/posts/_slug/_name.vue',
|
||||||
|
name: 'posts-slug-name'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Demo
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npm install
|
||||||
|
npm start
|
||||||
|
```
|
||||||
|
|
||||||
|
Go to [http://localhost:3000](http://localhost:3000) and navigate through the pages.
|
5
test/fixtures/dynamic-routes/nuxt.config.js
vendored
Normal file
5
test/fixtures/dynamic-routes/nuxt.config.js
vendored
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
module.exports = {
|
||||||
|
build: {
|
||||||
|
vendor: ['axios']
|
||||||
|
}
|
||||||
|
}
|
13
test/fixtures/dynamic-routes/package.json
vendored
Normal file
13
test/fixtures/dynamic-routes/package.json
vendored
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
{
|
||||||
|
"name": "nuxt-custom-routes",
|
||||||
|
"description": "",
|
||||||
|
"dependencies": {
|
||||||
|
"axios": "^0.15.2",
|
||||||
|
"nuxt": "latest"
|
||||||
|
},
|
||||||
|
"scripts": {
|
||||||
|
"dev": "nuxt",
|
||||||
|
"build": "nuxt build",
|
||||||
|
"start": "nuxt start"
|
||||||
|
}
|
||||||
|
}
|
0
test/fixtures/dynamic-routes/pages/_key/_id.vue
vendored
Normal file
0
test/fixtures/dynamic-routes/pages/_key/_id.vue
vendored
Normal file
0
test/fixtures/dynamic-routes/pages/_slug.vue
vendored
Normal file
0
test/fixtures/dynamic-routes/pages/_slug.vue
vendored
Normal file
0
test/fixtures/dynamic-routes/pages/parent.vue
vendored
Normal file
0
test/fixtures/dynamic-routes/pages/parent.vue
vendored
Normal file
0
test/fixtures/dynamic-routes/pages/parent/child.vue
vendored
Normal file
0
test/fixtures/dynamic-routes/pages/parent/child.vue
vendored
Normal file
0
test/fixtures/dynamic-routes/pages/parent/index.vue
vendored
Normal file
0
test/fixtures/dynamic-routes/pages/parent/index.vue
vendored
Normal file
0
test/fixtures/dynamic-routes/pages/parent/teub.vue
vendored
Normal file
0
test/fixtures/dynamic-routes/pages/parent/teub.vue
vendored
Normal file
46
test/fixtures/dynamic-routes/pages/test/index.vue
vendored
Normal file
46
test/fixtures/dynamic-routes/pages/test/index.vue
vendored
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
<template>
|
||||||
|
<div class="container">
|
||||||
|
<h2>Users</h2>
|
||||||
|
<ul class="users">
|
||||||
|
<li v-for="user in users">
|
||||||
|
<nuxt-link :to="'/users/'+user.id">{{ user.name }}</nuxt-link>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import axios from 'axios'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
data () {
|
||||||
|
return axios.get('https://jsonplaceholder.typicode.com/users')
|
||||||
|
.then((res) => {
|
||||||
|
return { users: res.data }
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.container {
|
||||||
|
text-align: center;
|
||||||
|
margin-top: 100px;
|
||||||
|
font-family: sans-serif;
|
||||||
|
}
|
||||||
|
.users {
|
||||||
|
list-style-type: none;
|
||||||
|
}
|
||||||
|
.users li a {
|
||||||
|
display: inline-block;
|
||||||
|
width: 200px;
|
||||||
|
border: 1px #ddd solid;
|
||||||
|
padding: 10px;
|
||||||
|
text-align: left;
|
||||||
|
color: #222;
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
.users li a:hover {
|
||||||
|
color: orange;
|
||||||
|
}
|
||||||
|
</style>
|
0
test/fixtures/dynamic-routes/pages/test/users.vue
vendored
Normal file
0
test/fixtures/dynamic-routes/pages/test/users.vue
vendored
Normal file
33
test/fixtures/dynamic-routes/pages/test/users/_id.vue
vendored
Normal file
33
test/fixtures/dynamic-routes/pages/test/users/_id.vue
vendored
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
<template>
|
||||||
|
<div class="user">
|
||||||
|
<h3>{{ name }}</h3>
|
||||||
|
<h4>@{{ username }}</h4>
|
||||||
|
<p>Email : {{ email }}</p>
|
||||||
|
<p><nuxt-link to="/">List of users</nuxt-link></p>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import axios from 'axios'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
validate ({ params }) {
|
||||||
|
return !isNaN(+params.id)
|
||||||
|
},
|
||||||
|
data ({ params, error }) {
|
||||||
|
return axios.get(`https://jsonplaceholder.typicode.com/users/${+params.id}`)
|
||||||
|
.then((res) => res.data)
|
||||||
|
.catch(() => {
|
||||||
|
error({ message: 'User not found', statusCode: 404 })
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.user {
|
||||||
|
text-align: center;
|
||||||
|
margin-top: 100px;
|
||||||
|
font-family: sans-serif;
|
||||||
|
}
|
||||||
|
</style>
|
0
test/fixtures/dynamic-routes/pages/test/users/_index/teub.vue
vendored
Normal file
0
test/fixtures/dynamic-routes/pages/test/users/_index/teub.vue
vendored
Normal file
0
test/fixtures/dynamic-routes/pages/test/users/index.vue
vendored
Normal file
0
test/fixtures/dynamic-routes/pages/test/users/index.vue
vendored
Normal file
Loading…
Reference in New Issue
Block a user