Merge branch 'master' into feature-layout

This commit is contained in:
Sébastien Chopin 2016-12-23 17:32:45 +01:00
commit 6b9af524aa
15 changed files with 304 additions and 7 deletions

View File

@ -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
View 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.

View File

@ -0,0 +1,5 @@
module.exports = {
build: {
vendor: ['axios']
}
}

View 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"
}
}

View File

View File

View File

View File

View File

View File

View 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>

View File

View 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>