diff --git a/packages/vue-app/template/components/nuxt.js b/packages/vue-app/template/components/nuxt.js index f4c8d7d69e..7bb698e6c4 100644 --- a/packages/vue-app/template/components/nuxt.js +++ b/packages/vue-app/template/components/nuxt.js @@ -40,10 +40,30 @@ export default { if (typeof this.nuxtChildKey !== 'undefined' || this.$route.matched.length > 1) { return this.nuxtChildKey || compile(this.$route.matched[0].path)(this.$route.params) } + const Component = this.$route.matched[0] && this.$route.matched[0].components.default - if (Component && Component.options && Component.options.key) { - return (typeof Component.options.key === 'function' ? Component.options.key(this.$route) : Component.options.key) + if (Component && Component.options) { + const { key, watchQuery } = Component.options + + if (key) { + return (typeof key === 'function' ? key(this.$route) : key) + } + + if (watchQuery) { + if (watchQuery.length) { + const pickedQuery = {} + for (const queryKey of watchQuery) { + pickedQuery[queryKey] = this.$route.query[queryKey] + } + return this.$router.resolve({ + path: this.$route.path, + query: pickedQuery + }).href + } + return this.$route.fullPath + } } + return this.$route.path } }, diff --git a/test/e2e/basic.browser.test.js b/test/e2e/basic.browser.test.js index 4a0e446822..51cff0feeb 100644 --- a/test/e2e/basic.browser.test.js +++ b/test/e2e/basic.browser.test.js @@ -123,11 +123,59 @@ describe('basic browser', () => { expect(await page.$text('h1')).toBe('User: 1') }) - test('/scroll-to-top', async () => { + test('/scroll-to-top with scrollToTop set to true', async () => { const page = await browser.page(url('/scroll-to-top')) await page.evaluate(() => window.scrollBy(0, window.innerHeight)) - await page.nuxt.navigate('/scroll-to-top/other') + await page.nuxt.navigate('/scroll-to-top/scroll-to-top-true') const pageYOffset = await page.evaluate(() => window.pageYOffset) + expect(pageYOffset).toBe(0) + page.close() + }) + + test('/scroll-to-top with scrollToTop set to false', async () => { + const page = await browser.page(url('/scroll-to-top')) + await page.evaluate(() => window.scrollBy(0, window.innerHeight)) + await page.nuxt.navigate('/scroll-to-top/scroll-to-top-false') + const pageYOffset = await page.evaluate(() => window.pageYOffset) + expect(pageYOffset).toBeGreaterThan(0) + page.close() + }) + + test('/scroll-to-top in the same page', async () => { + const page = await browser.page(url('/scroll-to-top')) + await page.evaluate(() => window.scrollBy(0, window.innerHeight)) + await page.nuxt.navigate('/scroll-to-top?test=1') + const pageYOffset = await page.evaluate(() => window.pageYOffset) + expect(pageYOffset).toBeGreaterThan(0) + page.close() + }) + + test('/scroll-to-top in the same page with watchQuery: true', async () => { + const page = await browser.page(url('/scroll-to-top/watch-query-true')) + await page.evaluate(() => window.scrollBy(0, window.innerHeight)) + await page.nuxt.navigate('/scroll-to-top/watch-query-true?test=1') + let pageYOffset = await page.evaluate(() => window.pageYOffset) + expect(pageYOffset).toBe(0) + await page.nuxt.go(-1) + pageYOffset = await page.evaluate(() => window.pageYOffset) + expect(pageYOffset).toBeGreaterThan(0) + page.close() + }) + + test('/scroll-to-top in the same page with watchQuery array', async () => { + const page = await browser.page(url('/scroll-to-top/watch-query-array')) + await page.evaluate(() => window.scrollBy(0, window.innerHeight)) + await page.nuxt.navigate('/scroll-to-top/watch-query-array?other=1') + let pageYOffset = await page.evaluate(() => window.pageYOffset) + expect(pageYOffset).toBeGreaterThan(0) + await page.nuxt.go(-1) + pageYOffset = await page.evaluate(() => window.pageYOffset) + expect(pageYOffset).toBeGreaterThan(0) + await page.nuxt.navigate('/scroll-to-top/watch-query-array?test=1') + pageYOffset = await page.evaluate(() => window.pageYOffset) + expect(pageYOffset).toBe(0) + await page.nuxt.go(-1) + pageYOffset = await page.evaluate(() => window.pageYOffset) expect(pageYOffset).toBeGreaterThan(0) page.close() }) diff --git a/test/fixtures/basic/pages/scroll-to-top/index.vue b/test/fixtures/basic/pages/scroll-to-top/index.vue index a22be0381c..451d861a8a 100644 --- a/test/fixtures/basic/pages/scroll-to-top/index.vue +++ b/test/fixtures/basic/pages/scroll-to-top/index.vue @@ -1,7 +1,13 @@ diff --git a/test/fixtures/basic/pages/scroll-to-top/other.vue b/test/fixtures/basic/pages/scroll-to-top/scroll-to-top-false.vue similarity index 100% rename from test/fixtures/basic/pages/scroll-to-top/other.vue rename to test/fixtures/basic/pages/scroll-to-top/scroll-to-top-false.vue diff --git a/test/fixtures/basic/pages/scroll-to-top/scroll-to-top-true.vue b/test/fixtures/basic/pages/scroll-to-top/scroll-to-top-true.vue new file mode 100644 index 0000000000..050b4a7737 --- /dev/null +++ b/test/fixtures/basic/pages/scroll-to-top/scroll-to-top-true.vue @@ -0,0 +1,13 @@ + + + diff --git a/test/fixtures/basic/pages/scroll-to-top/watch-query-array.vue b/test/fixtures/basic/pages/scroll-to-top/watch-query-array.vue new file mode 100644 index 0000000000..2c5ee3c602 --- /dev/null +++ b/test/fixtures/basic/pages/scroll-to-top/watch-query-array.vue @@ -0,0 +1,19 @@ + + + + + diff --git a/test/fixtures/basic/pages/scroll-to-top/watch-query-true.vue b/test/fixtures/basic/pages/scroll-to-top/watch-query-true.vue new file mode 100644 index 0000000000..c6df045b3b --- /dev/null +++ b/test/fixtures/basic/pages/scroll-to-top/watch-query-true.vue @@ -0,0 +1,19 @@ + + + + + diff --git a/test/utils/browser.js b/test/utils/browser.js index 6bd173d344..1898099759 100644 --- a/test/utils/browser.js +++ b/test/utils/browser.js @@ -73,6 +73,22 @@ export default class Browser { } return { hook } }, + async go(n, waitEnd = true) { + const hook = page.evaluate(` + new Promise(resolve => + ${page.$nuxtGlobalHandle}.$once('routeChanged', resolve) + ).then(() => new Promise(resolve => setTimeout(resolve, 50))) + `) + await page.evaluate( + ($nuxt, n) => $nuxt.$router.go(n), + page.$nuxt, + n + ) + if (waitEnd) { + await hook + } + return { hook } + }, routeData() { return page.evaluate(($nuxt) => { return {