diff --git a/examples/index.html b/examples/index.html
index 9fcb249da..c0ee5bc16 100644
--- a/examples/index.html
+++ b/examples/index.html
@@ -17,6 +17,7 @@
Vue Router Examples
Redirect
Route Props
Route Alias
+ Route Params
Transitions
Data Fetching
Navigation Guards
diff --git a/examples/route-params/app.js b/examples/route-params/app.js
new file mode 100644
index 000000000..c9f4699e7
--- /dev/null
+++ b/examples/route-params/app.js
@@ -0,0 +1,58 @@
+import Vue from 'vue'
+import VueRouter from 'vue-router'
+
+Vue.use(VueRouter)
+
+const Log = {
+ template: `id: {{ $route.params.id }}, type: {{ $route.params.type }}
`
+}
+
+const Logs = {
+ template: `
+
+
{{ to.params }}
+
{{ to.params.type }}
+
+
+ `,
+ data () {
+ return {
+ to: {
+ name: 'items.logs.type',
+ params: { type: 'info' }
+ }
+ }
+ }
+}
+
+const router = new VueRouter({
+ mode: 'history',
+ base: __dirname,
+ routes: [
+ {
+ path: '/items/:id/logs',
+ component: Logs,
+ children: [
+ {
+ path: ':type',
+ name: 'items.logs.type',
+ component: Log
+ }
+ ]
+ }
+ ]
+})
+
+new Vue({
+ router,
+ template: `
+
+ `
+}).$mount('#app')
diff --git a/examples/route-params/index.html b/examples/route-params/index.html
new file mode 100644
index 000000000..939b0e9ff
--- /dev/null
+++ b/examples/route-params/index.html
@@ -0,0 +1,6 @@
+
+
+← Examples index
+
+
+
diff --git a/src/util/location.js b/src/util/location.js
index 176b50141..fb98d4537 100644
--- a/src/util/location.js
+++ b/src/util/location.js
@@ -18,7 +18,12 @@ export function normalizeLocation (
if (next._normalized) {
return next
} else if (next.name) {
- return extend({}, raw)
+ next = extend({}, raw)
+ const params = next.params
+ if (params && typeof params === 'object') {
+ next.params = extend({}, params)
+ }
+ return next
}
// relative params
diff --git a/test/e2e/specs/route-params.js b/test/e2e/specs/route-params.js
new file mode 100644
index 000000000..f5c6dc970
--- /dev/null
+++ b/test/e2e/specs/route-params.js
@@ -0,0 +1,26 @@
+module.exports = {
+ 'route-params': function (browser) {
+ browser
+ .url('http://localhost:8080/route-params/')
+ .waitForElementVisible('#app', 1000)
+ .assert.count('li a', 2)
+
+ // https://github.com/vuejs/vue-router/issues/2800
+ .click('li:nth-child(1) a')
+ .assert.urlEquals('http://localhost:8080/route-params/items/1/logs')
+ .assert.containsText('#params', JSON.stringify({ type: 'info' }, null, 2))
+ .click('.child-link')
+ .assert.urlEquals('http://localhost:8080/route-params/items/1/logs/info')
+ .assert.containsText('.log', 'id: 1, type: info')
+ // https://github.com/vuejs/vue-router/issues/2938
+ .assert.containsText('#params', JSON.stringify({ type: 'info' }, null, 2))
+
+ .click('li:nth-child(2) a')
+ .assert.urlEquals('http://localhost:8080/route-params/items/2/logs')
+ .click('.child-link')
+ .assert.urlEquals('http://localhost:8080/route-params/items/2/logs/info')
+ .assert.containsText('.log', 'id: 2, type: info')
+
+ .end()
+ }
+}