diff --git a/examples/redirect/app.js b/examples/redirect/app.js
index d81664c85..32beeb885 100644
--- a/examples/redirect/app.js
+++ b/examples/redirect/app.js
@@ -9,6 +9,8 @@ const Foo = { template: '
foo
' }
const Bar = { template: 'bar
' }
const Baz = { template: 'baz
' }
const WithParams = { template: '{{ $route.params.id }}
' }
+const Foobar = { template: 'foobar
' }
+const FooBar = { template: 'FooBar
' }
const router = new VueRouter({
mode: 'history',
@@ -50,6 +52,12 @@ const router = new VueRouter({
// redirect with params
{ path: '/redirect-with-params/:id', redirect: '/with-params/:id' },
+ // redirect with caseSensitive
+ { path: '/foobar', component: Foobar, caseSensitive: true },
+
+ // redirect with pathToRegexpOptions
+ { path: '/FooBar', component: FooBar, pathToRegexpOptions: { sensitive: true }},
+
// catch all redirect
{ path: '*', redirect: '/' }
]
@@ -97,6 +105,14 @@ new Vue({
/redirect-with-params/123 (redirects to /with-params/123)
+
+ /foobar
+
+
+
+ /FooBar
+
+
/not-found (redirects to /)
diff --git a/flow/declarations.js b/flow/declarations.js
index 91ed03ef8..e62aeb9f9 100644
--- a/flow/declarations.js
+++ b/flow/declarations.js
@@ -4,9 +4,15 @@ declare class RouteRegExp extends RegExp {
keys: Array<{ name: string, optional: boolean }>;
}
+declare type PathToRegexpOptions = {
+ sensitive?: boolean,
+ strict?: boolean,
+ end?: boolean
+}
+
declare module 'path-to-regexp' {
declare var exports: {
- (path: string, keys?: Array{ name: string }>): RouteRegExp;
+ (path: string, keys?: Array{ name: string }>, options?: PathToRegexpOptions): RouteRegExp;
compile: (path: string) => (params: Object) => string;
}
}
@@ -48,6 +54,8 @@ declare type RouteConfig = {
beforeEnter?: NavigationGuard;
meta?: any;
props?: boolean | Object | Function;
+ caseSensitive?: boolean;
+ pathToRegexpOptions?: PathToRegexpOptions;
}
declare type RouteRecord = {
diff --git a/src/create-route-map.js b/src/create-route-map.js
index c68d211b7..bd865a27c 100644
--- a/src/create-route-map.js
+++ b/src/create-route-map.js
@@ -58,9 +58,15 @@ function addRouteRecord (
}
const normalizedPath = normalizePath(path, parent)
+ const pathToRegexpOptions: PathToRegexpOptions = route.pathToRegexpOptions || {}
+
+ if (typeof route.caseSensitive === 'boolean') {
+ pathToRegexpOptions.sensitive = route.caseSensitive
+ }
+
const record: RouteRecord = {
path: normalizedPath,
- regex: compileRouteRegex(normalizedPath),
+ regex: compileRouteRegex(normalizedPath, pathToRegexpOptions),
components: route.components || { default: route.component },
instances: {},
name,
@@ -136,8 +142,8 @@ function addRouteRecord (
}
}
-function compileRouteRegex (path: string): RouteRegExp {
- const regex = Regexp(path)
+function compileRouteRegex (path: string, pathToRegexpOptions: PathToRegexpOptions): RouteRegExp {
+ const regex = Regexp(path, [], pathToRegexpOptions)
if (process.env.NODE_ENV !== 'production') {
const keys: any = {}
regex.keys.forEach(key => {
diff --git a/test/e2e/specs/redirect.js b/test/e2e/specs/redirect.js
index f91e66342..ba39d3b7a 100644
--- a/test/e2e/specs/redirect.js
+++ b/test/e2e/specs/redirect.js
@@ -3,7 +3,7 @@ module.exports = {
browser
.url('http://localhost:8080/redirect/')
.waitForElementVisible('#app', 1000)
- .assert.count('li a', 10)
+ .assert.count('li a', 12)
// assert correct href with base
.assert.attributeContains('li:nth-child(1) a', 'href', '/redirect/relative-redirect')
.assert.attributeContains('li:nth-child(2) a', 'href', '/redirect/relative-redirect?foo=bar')
@@ -14,7 +14,9 @@ module.exports = {
.assert.attributeContains('li:nth-child(7) a', 'href', '/redirect/dynamic-redirect#baz')
.assert.attributeContains('li:nth-child(8) a', 'href', '/redirect/named-redirect')
.assert.attributeContains('li:nth-child(9) a', 'href', '/redirect/redirect-with-params/123')
- .assert.attributeContains('li:nth-child(10) a', 'href', '/not-found')
+ .assert.attributeContains('li:nth-child(10) a', 'href', '/redirect/foobar')
+ .assert.attributeContains('li:nth-child(11) a', 'href', '/redirect/FooBar')
+ .assert.attributeContains('li:nth-child(12) a', 'href', '/not-found')
.assert.containsText('.view', 'default')
@@ -55,6 +57,14 @@ module.exports = {
.assert.containsText('.view', '123')
.click('li:nth-child(10) a')
+ .assert.urlEquals('http://localhost:8080/redirect/foobar')
+ .assert.containsText('.view', 'foobar')
+
+ .click('li:nth-child(11) a')
+ .assert.urlEquals('http://localhost:8080/redirect/FooBar')
+ .assert.containsText('.view', 'FooBar')
+
+ .click('li:nth-child(12) a')
.assert.urlEquals('http://localhost:8080/redirect/')
.assert.containsText('.view', 'default')
@@ -104,6 +114,16 @@ module.exports = {
.assert.urlEquals('http://localhost:8080/redirect/with-params/123')
.assert.containsText('.view', '123')
+ .url('http://localhost:8080/redirect/foobar')
+ .waitForElementVisible('#app', 1000)
+ .assert.urlEquals('http://localhost:8080/redirect/foobar')
+ .assert.containsText('.view', 'foobar')
+
+ .url('http://localhost:8080/redirect/FooBar')
+ .waitForElementVisible('#app', 1000)
+ .assert.urlEquals('http://localhost:8080/redirect/FooBar')
+ .assert.containsText('.view', 'FooBar')
+
.url('http://localhost:8080/redirect/not-found')
.waitForElementVisible('#app', 1000)
.assert.urlEquals('http://localhost:8080/redirect/')
diff --git a/test/e2e/specs/route-matching.js b/test/e2e/specs/route-matching.js
index 79e5b3745..ea1ef3a29 100644
--- a/test/e2e/specs/route-matching.js
+++ b/test/e2e/specs/route-matching.js
@@ -124,7 +124,6 @@ module.exports = {
})
)
}, null, '/optional-group/foo/bar')
-
.end()
}
}
diff --git a/test/unit/specs/create-map.spec.js b/test/unit/specs/create-map.spec.js
index ff1ccf46d..ad5803d1c 100644
--- a/test/unit/specs/create-map.spec.js
+++ b/test/unit/specs/create-map.spec.js
@@ -3,6 +3,8 @@ import { createRouteMap } from '../../../src/create-route-map'
const Home = { template: 'This is Home
' }
const Foo = { template: 'This is Foo
' }
+const FooBar = { template: 'This is FooBar
' }
+const Foobar = { template: 'This is foobar
' }
const Bar = { template: 'This is Bar
' }
const Baz = { template: 'This is Baz
' }
@@ -74,4 +76,61 @@ describe('Creating Route Map', function () {
expect(console.warn).toHaveBeenCalled()
expect(console.warn.calls.argsFor(0)[0]).toMatch('vue-router] Duplicate param keys in route with path: "/foo/:id/bar/:id"')
})
+
+ describe('path-to-regexp options', function () {
+ const routes = [
+ { path: '/foo', name: 'foo', component: Foo },
+ { path: '/bar', name: 'bar', component: Bar, caseSensitive: false },
+ { path: '/FooBar', name: 'FooBar', component: FooBar, caseSensitive: true },
+ { path: '/foobar', name: 'foobar', component: Foobar, caseSensitive: true }
+ ]
+
+ it('caseSensitive option in route', function () {
+ const { nameMap } = createRouteMap(routes)
+
+ expect(nameMap.FooBar.regex.ignoreCase).toBe(false)
+ expect(nameMap.bar.regex.ignoreCase).toBe(true)
+ expect(nameMap.foo.regex.ignoreCase).toBe(true)
+ })
+
+ it('pathToRegexpOptions option in route', function () {
+ const { nameMap } = createRouteMap([
+ {
+ name: 'foo',
+ path: '/foo',
+ component: Foo,
+ pathToRegexpOptions: {
+ sensitive: true
+ }
+ },
+ {
+ name: 'bar',
+ path: '/bar',
+ component: Bar,
+ pathToRegexpOptions: {
+ sensitive: false
+ }
+ }
+ ])
+
+ expect(nameMap.foo.regex.ignoreCase).toBe(false)
+ expect(nameMap.bar.regex.ignoreCase).toBe(true)
+ })
+
+ it('caseSensitive over pathToRegexpOptions in route', function () {
+ const { nameMap } = createRouteMap([
+ {
+ name: 'foo',
+ path: '/foo',
+ component: Foo,
+ caseSensitive: true,
+ pathToRegexpOptions: {
+ sensitive: false
+ }
+ }
+ ])
+
+ expect(nameMap.foo.regex.ignoreCase).toBe(false)
+ })
+ })
})
diff --git a/types/router.d.ts b/types/router.d.ts
index ac702ab11..6992461de 100644
--- a/types/router.d.ts
+++ b/types/router.d.ts
@@ -60,6 +60,12 @@ export interface RouterOptions {
type RoutePropsFunction = (route: Route) => Object;
+export interface PathToRegexpOptions {
+ sensitive?: boolean;
+ strict?: boolean;
+ end?: boolean;
+}
+
export interface RouteConfig {
path: string;
name?: string;
@@ -71,6 +77,8 @@ export interface RouteConfig {
meta?: any;
beforeEnter?: NavigationGuard;
props?: boolean | Object | RoutePropsFunction;
+ caseSensitive?: boolean;
+ pathToRegexpOptions?: PathToRegexpOptions;
}
export interface RouteRecord {