diff --git a/packages/vue-app/template/client.js b/packages/vue-app/template/client.js index 2b67e2517d..8989281d4a 100644 --- a/packages/vue-app/template/client.js +++ b/packages/vue-app/template/client.js @@ -356,6 +356,7 @@ async function render(to, from, next) { return next() } + let instances // Call asyncData & fetch hooks on components matched by the route. await Promise.all(Components.map((Component, i) => { // Check if only children route changed @@ -371,6 +372,11 @@ async function render(to, from, next) { Component._dataRefresh = true } else if (Array.isArray(watchQuery)) { Component._dataRefresh = watchQuery.some(key => this._diffQuery[key]) + } else if (typeof watchQuery === 'function') { + if (!instances) { + instances = getMatchedComponentsInstances(to) + } + Component._dataRefresh = watchQuery.apply(instances[i], [to.query, from.query]) } } if (!this._hadError && this._isMounted && !Component._dataRefresh) { @@ -491,18 +497,13 @@ function showNextPage(to) { function fixPrepatch(to, ___) { if (this._pathChanged === false && this._queryChanged === false) return - const matches = [] - const instances = getMatchedComponentsInstances(to, matches) - const Components = getMatchedComponents(to, matches) + const instances = getMatchedComponentsInstances(to) + const Components = getMatchedComponents(to) Vue.nextTick(() => { instances.forEach((instance, i) => { if (!instance || instance._isDestroyed) return - // if ( - // !this._queryChanged && - // to.matched[matches[i]].path.indexOf(':') === -1 && - // to.matched[matches[i]].path.indexOf('*') === -1 - // ) return // If not a dynamic route, skip + if ( instance.constructor._dataRefresh && Components[i] === instance.constructor && diff --git a/test/e2e/basic.browser.test.js b/test/e2e/basic.browser.test.js index 8584efedd2..bc667f09df 100644 --- a/test/e2e/basic.browser.test.js +++ b/test/e2e/basic.browser.test.js @@ -180,6 +180,24 @@ describe('basic browser', () => { page.close() }) + test('/scroll-to-top in the same page with watchQuery function', async () => { + const page = await browser.page(url('/scroll-to-top/watch-query-fn')) + await page.evaluate(() => window.scrollBy(0, window.innerHeight)) + await page.nuxt.navigate('/scroll-to-top/watch-query-fn?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-fn?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).toBe(0) + page.close() + }) + test('/validate should display a 404', async () => { await page.nuxt.navigate('/validate') diff --git a/test/fixtures/basic/pages/scroll-to-top/watch-query-fn.vue b/test/fixtures/basic/pages/scroll-to-top/watch-query-fn.vue new file mode 100644 index 0000000000..4d49ec094a --- /dev/null +++ b/test/fixtures/basic/pages/scroll-to-top/watch-query-fn.vue @@ -0,0 +1,24 @@ + + + + go to the same page with other test + + + go to the same page with param other + + + + + + +