diff --git a/src/history/hash.js b/src/history/hash.js index e0ddf2d7c..81ee1fc3c 100644 --- a/src/history/hash.js +++ b/src/history/hash.js @@ -3,6 +3,7 @@ import type Router from '../index' import { History } from './base' import { cleanPath } from '../util/path' +import { isSameRoute, createPlainRoute } from '../util/route' import { getLocation } from './html5' import { setupScroll, handleScroll } from '../util/scroll' import { pushState, replaceState, supportsPushState } from '../util/push-state' @@ -87,8 +88,10 @@ export class HashHistory extends History { } ensureURL (push?: boolean) { - const current = this.current.fullPath - if (getHash() !== current) { + const location = getHash() + const plainRoute = createPlainRoute(location) + if (!isSameRoute(plainRoute, this.current)) { + const current = this.current.fullPath push ? pushHash(current) : replaceHash(current) } } diff --git a/src/history/html5.js b/src/history/html5.js index 9af347fe8..5ae0b1b81 100644 --- a/src/history/html5.js +++ b/src/history/html5.js @@ -3,7 +3,7 @@ import type Router from '../index' import { History } from './base' import { cleanPath } from '../util/path' -import { START } from '../util/route' +import { START, isSameRoute, createPlainRoute } from '../util/route' import { setupScroll, handleScroll } from '../util/scroll' import { pushState, replaceState, supportsPushState } from '../util/push-state' @@ -74,7 +74,9 @@ export class HTML5History extends History { } ensureURL (push?: boolean) { - if (getLocation(this.base) !== this.current.fullPath) { + const location = getLocation(this.base) + const plainRoute = createPlainRoute(location) + if (!isSameRoute(plainRoute, this.current)) { const current = cleanPath(this.base + this.current.fullPath) push ? pushState(current) : replaceState(current) } diff --git a/src/util/route.js b/src/util/route.js index 37a499272..75df6236a 100644 --- a/src/util/route.js +++ b/src/util/route.js @@ -2,6 +2,7 @@ import type VueRouter from '../index' import { stringifyQuery } from './query' +import { normalizeLocation } from './location' const trailingSlashRE = /\/?$/ @@ -149,3 +150,8 @@ export function handleRouteEntered (route: Route) { } } } +/** just create a route without any added process */ +export function createPlainRoute (url: string) { + const location = normalizeLocation(url) + return createRoute(null, location) +} diff --git a/test/unit/specs/route.spec.js b/test/unit/specs/route.spec.js index c9483ab7d..14d84d59f 100644 --- a/test/unit/specs/route.spec.js +++ b/test/unit/specs/route.spec.js @@ -1,4 +1,4 @@ -import { isSameRoute, isIncludedRoute } from '../../../src/util/route' +import { isSameRoute, isIncludedRoute, createPlainRoute } from '../../../src/util/route' describe('Route utils', () => { describe('isSameRoute', () => { @@ -150,4 +150,21 @@ describe('Route utils', () => { expect(isIncludedRoute(d, f)).toBe(false) }) }) + + describe('createPlainRoute', () => { + it('path', () => { + const a = { path: '/a?arr=1&foo=bar&arr=2#hi' } + const b = { path: '/a?arr=1&arr=2&foo=bar#hi' } + const route = { + path: '/a', + hash: '#hi', + query: { foo: 'bar', arr: [1, 2] } + } + const aRoute = createPlainRoute(a) + const bRoute = createPlainRoute(b) + expect(isSameRoute(aRoute, route)).toBe(true) + expect(isSameRoute(aRoute, route)).toBe(true) + expect(isSameRoute(aRoute, bRoute)).toBe(true) + }) + }) })