diff --git a/lib/build/index.js b/lib/build/index.js index 8e5f488527..8d47588799 100644 --- a/lib/build/index.js +++ b/lib/build/index.js @@ -198,15 +198,23 @@ function createRoutes (files, srcDir) { let route = { name: '', path: '', component: r(srcDir, file), _name: null } let parent = routes 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 }) if (child) { if (!child.children) { child.children = [] } parent = child.children + route.path = '' } 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) @@ -222,15 +230,22 @@ function createRoutes (files, srcDir) { } function cleanChildrenRoutes (routes, isChild = false) { - let isOptional = true + let hasIndex = false + let parents = [] routes.forEach((route) => { route.path = (isChild) ? route.path.replace('/', '') : route.path - if (route.path === '' || route.path === '/') { - isOptional = false + if ((isChild && /-index$/.test(route.name)) || (!isChild && route.name === 'index')) { + hasIndex = true } - if (isOptional && route.path.includes(':')) { - route.path += '?' + route.path = (hasIndex) ? route.path.replace('?', '') : 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) { delete route.name route.children = cleanChildrenRoutes(route.children, true) diff --git a/test/fixtures/dynamic-routes/README.md b/test/fixtures/dynamic-routes/README.md new file mode 100644 index 0000000000..a6a85d97ad --- /dev/null +++ b/test/fixtures/dynamic-routes/README.md @@ -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 + +``` + +## 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 `` 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. diff --git a/test/fixtures/dynamic-routes/nuxt.config.js b/test/fixtures/dynamic-routes/nuxt.config.js new file mode 100644 index 0000000000..bb0765f744 --- /dev/null +++ b/test/fixtures/dynamic-routes/nuxt.config.js @@ -0,0 +1,5 @@ +module.exports = { + build: { + vendor: ['axios'] + } +} diff --git a/test/fixtures/dynamic-routes/package.json b/test/fixtures/dynamic-routes/package.json new file mode 100644 index 0000000000..31c9724fdb --- /dev/null +++ b/test/fixtures/dynamic-routes/package.json @@ -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" + } +} diff --git a/test/fixtures/dynamic-routes/pages/_key/_id.vue b/test/fixtures/dynamic-routes/pages/_key/_id.vue new file mode 100644 index 0000000000..e69de29bb2 diff --git a/test/fixtures/dynamic-routes/pages/_slug.vue b/test/fixtures/dynamic-routes/pages/_slug.vue new file mode 100644 index 0000000000..e69de29bb2 diff --git a/test/fixtures/dynamic-routes/pages/parent.vue b/test/fixtures/dynamic-routes/pages/parent.vue new file mode 100644 index 0000000000..e69de29bb2 diff --git a/test/fixtures/dynamic-routes/pages/parent/child.vue b/test/fixtures/dynamic-routes/pages/parent/child.vue new file mode 100644 index 0000000000..e69de29bb2 diff --git a/test/fixtures/dynamic-routes/pages/parent/index.vue b/test/fixtures/dynamic-routes/pages/parent/index.vue new file mode 100644 index 0000000000..e69de29bb2 diff --git a/test/fixtures/dynamic-routes/pages/parent/teub.vue b/test/fixtures/dynamic-routes/pages/parent/teub.vue new file mode 100644 index 0000000000..e69de29bb2 diff --git a/test/fixtures/dynamic-routes/pages/test/index.vue b/test/fixtures/dynamic-routes/pages/test/index.vue new file mode 100644 index 0000000000..94414546d1 --- /dev/null +++ b/test/fixtures/dynamic-routes/pages/test/index.vue @@ -0,0 +1,46 @@ + + + + + diff --git a/test/fixtures/dynamic-routes/pages/test/users.vue b/test/fixtures/dynamic-routes/pages/test/users.vue new file mode 100644 index 0000000000..e69de29bb2 diff --git a/test/fixtures/dynamic-routes/pages/test/users/_id.vue b/test/fixtures/dynamic-routes/pages/test/users/_id.vue new file mode 100644 index 0000000000..ccd6594097 --- /dev/null +++ b/test/fixtures/dynamic-routes/pages/test/users/_id.vue @@ -0,0 +1,33 @@ + + + + + diff --git a/test/fixtures/dynamic-routes/pages/test/users/_index/teub.vue b/test/fixtures/dynamic-routes/pages/test/users/_index/teub.vue new file mode 100644 index 0000000000..e69de29bb2 diff --git a/test/fixtures/dynamic-routes/pages/test/users/index.vue b/test/fixtures/dynamic-routes/pages/test/users/index.vue new file mode 100644 index 0000000000..e69de29bb2