mirror of
https://github.com/nuxt/nuxt.git
synced 2024-11-30 09:27:13 +00:00
feat(vue-app): trigger watchParam when param is changed in same route (#6244)
This commit is contained in:
parent
52caef2053
commit
a7052b637b
@ -137,20 +137,21 @@ function mapTransitions (toComponents, to, from) {
|
||||
}
|
||||
<% } %>
|
||||
<% if (loading) { %>async <% } %>function loadAsyncComponents (to, from, next) {
|
||||
// Check if route path changed (this._pathChanged), only if the page is not an error (for validate())
|
||||
this._pathChanged = Boolean(app.nuxt.err) || from.path !== to.path
|
||||
this._queryChanged = JSON.stringify(to.query) !== JSON.stringify(from.query)
|
||||
// Check if route changed (this._routeChanged), only if the page is not an error (for validate())
|
||||
this._routeChanged = Boolean(app.nuxt.err) || from.name !== to.name
|
||||
this._paramChanged = !this._routeChanged && from.path !== to.path
|
||||
this._queryChanged = !this._paramChanged && from.fullPath !== to.fullPath
|
||||
this._diffQuery = (this._queryChanged ? getQueryDiff(to.query, from.query) : [])
|
||||
|
||||
<% if (loading) { %>
|
||||
if (this._pathChanged && this.$loading.start && !this.$loading.manual) {
|
||||
if ((this._routeChanged || this._paramChanged) && this.$loading.start && !this.$loading.manual) {
|
||||
this.$loading.start()
|
||||
}
|
||||
<% } %>
|
||||
|
||||
try {
|
||||
<% if (loading) { %>
|
||||
if (!this._pathChanged && this._queryChanged) {
|
||||
if (this._queryChanged) {
|
||||
const Components = await resolveRouteComponents(
|
||||
to,
|
||||
(Component, instance) => ({ Component, instance })
|
||||
@ -268,7 +269,7 @@ function callMiddleware () {
|
||||
}
|
||||
<% } %>
|
||||
async function render (to, from, next) {
|
||||
if (this._pathChanged === false && this._queryChanged === false) {
|
||||
if (this._routeChanged === false && this._paramChanged === false && this._queryChanged === false) {
|
||||
return next()
|
||||
}
|
||||
// Handle first render on SPA mode
|
||||
@ -432,11 +433,17 @@ async function render (to, from, next) {
|
||||
// Check if only children route changed
|
||||
Component._path = compile(to.matched[matches[i]].path)(to.params)
|
||||
Component._dataRefresh = false
|
||||
// Check if Component need to be refreshed (call asyncData & fetch)
|
||||
// Only if its slug has changed or is watch query changes
|
||||
if ((this._pathChanged && this._queryChanged) || Component._path !== _lastPaths[i]) {
|
||||
const childPathChanged = Component._path !== _lastPaths[i]
|
||||
// Refresh component (call asyncData & fetch) when:
|
||||
// Route path changed part includes current component
|
||||
// Or route param changed part includes current component and watchParam is not `false`
|
||||
// Or route query is changed and watchQuery returns `true`
|
||||
if (this._routeChanged && childPathChanged) {
|
||||
Component._dataRefresh = true
|
||||
} else if (!this._pathChanged && this._queryChanged) {
|
||||
} else if (this._paramChanged && childPathChanged) {
|
||||
const watchParam = Component.options.watchParam
|
||||
Component._dataRefresh = watchParam !== false
|
||||
} else if (this._queryChanged) {
|
||||
const watchQuery = Component.options.watchQuery
|
||||
if (watchQuery === true) {
|
||||
Component._dataRefresh = true
|
||||
@ -584,7 +591,7 @@ function showNextPage (to) {
|
||||
// When navigating on a different route but the same component is used, Vue.js
|
||||
// Will not update the instance data, so we have to update $data ourselves
|
||||
function fixPrepatch (to, ___) {
|
||||
if (this._pathChanged === false && this._queryChanged === false) {
|
||||
if (this._routeChanged === false && this._paramChanged === false && this._queryChanged === false) {
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -20,7 +20,6 @@ describe('nuxt minimal vue-app bundle size limit', () => {
|
||||
it('should stay within the size limit range', async () => {
|
||||
const filter = filename => filename === 'vue-app.nuxt.js'
|
||||
const legacyResourcesSize = await getResourcesSize(distDir, 'client', { filter })
|
||||
|
||||
const LEGACY_JS_RESOURCES_KB_SIZE = 15.7
|
||||
expect(legacyResourcesSize.uncompressed).toBeWithinSize(LEGACY_JS_RESOURCES_KB_SIZE)
|
||||
})
|
||||
|
@ -27,7 +27,7 @@ describe('children patch (browser)', () => {
|
||||
})
|
||||
})
|
||||
|
||||
test('Loading /patch and keep ', async () => {
|
||||
test('Loading /patch and keep', async () => {
|
||||
page = await browser.page(url('/patch'))
|
||||
|
||||
const h1 = await page.$text('h1')
|
||||
@ -37,86 +37,119 @@ describe('children patch (browser)', () => {
|
||||
dates.patch = await page.$text('[data-date-patch]')
|
||||
})
|
||||
|
||||
test('Navigate to /patch/1', async () => {
|
||||
const { hook } = await page.nuxt.navigate('/patch/1', false)
|
||||
await hook
|
||||
describe('refresh child component if param changed', () => {
|
||||
test('Navigate to /patch/1', async () => {
|
||||
const { hook } = await page.nuxt.navigate('/patch/1', false)
|
||||
await hook
|
||||
|
||||
const h2 = await page.$text('h2')
|
||||
expect(h2.includes('_id:')).toBe(true)
|
||||
dates.id = await page.$text('[data-date-id]')
|
||||
const h2 = await page.$text('h2')
|
||||
expect(h2.includes('_id:')).toBe(true)
|
||||
dates.id = await page.$text('[data-date-id]')
|
||||
|
||||
expect(dates.patch).toBe(await page.$text('[data-date-patch]'))
|
||||
expect(dates.patch).toBe(await page.$text('[data-date-patch]'))
|
||||
})
|
||||
|
||||
test('Navigate to /patch/2', async () => {
|
||||
await page.nuxt.navigate('/patch/2')
|
||||
const date = await page.$text('[data-date-id]')
|
||||
|
||||
expect(await page.$text('h3')).toBe('Index')
|
||||
expect(dates.patch).toBe(await page.$text('[data-date-patch]'))
|
||||
expect(+dates.id < +date).toBe(true)
|
||||
dates.id = date
|
||||
})
|
||||
})
|
||||
|
||||
test('Navigate to /patch/2', async () => {
|
||||
await page.nuxt.navigate('/patch/2')
|
||||
const date = await page.$text('[data-date-id]')
|
||||
describe('resue component if only query is changed', () => {
|
||||
test('Navigate to /patch/2?test=true', async () => {
|
||||
await page.nuxt.navigate('/patch/2?test=true')
|
||||
expect(dates.patch).toBe(await page.$text('[data-date-patch]'))
|
||||
expect(dates.id).toBe(await page.$text('[data-date-id]'))
|
||||
})
|
||||
|
||||
expect(await page.$text('h3')).toBe('Index')
|
||||
expect(dates.patch).toBe(await page.$text('[data-date-patch]'))
|
||||
expect(+dates.id < +date).toBe(true)
|
||||
dates.id = date
|
||||
test('Navigate to /patch/2#test', async () => {
|
||||
await page.nuxt.navigate('/patch/2#test')
|
||||
expect(dates.patch).toBe(await page.$text('[data-date-patch]'))
|
||||
expect(dates.id).toBe(await page.$text('[data-date-id]'))
|
||||
})
|
||||
})
|
||||
|
||||
test('Navigate to /patch/2?test=true', async () => {
|
||||
await page.nuxt.navigate('/patch/2?test=true')
|
||||
expect(dates.patch).toBe(await page.$text('[data-date-patch]'))
|
||||
expect(dates.id).toBe(await page.$text('[data-date-id]'))
|
||||
describe('refresh child component if param is changed', () => {
|
||||
test('Navigate to /patch/2/child', async () => {
|
||||
await page.nuxt.navigate('/patch/2/child')
|
||||
dates.child = await page.$text('[data-date-child]')
|
||||
dates.slug = await page.$text('[data-date-child-slug]')
|
||||
|
||||
expect(dates.patch).toBe(await page.$text('[data-date-patch]'))
|
||||
expect(dates.id).toBe(await page.$text('[data-date-id]'))
|
||||
expect(+dates.child > +dates.id).toBe(true)
|
||||
expect(+dates.slug > +dates.child).toBe(true)
|
||||
})
|
||||
|
||||
test('Navigate to /patch/2/child/1', async () => {
|
||||
await page.nuxt.navigate('/patch/2/child/1')
|
||||
const date = await page.$text('[data-date-child-slug]')
|
||||
|
||||
expect(dates.patch).toBe(await page.$text('[data-date-patch]'))
|
||||
expect(dates.id).toBe(await page.$text('[data-date-id]'))
|
||||
expect(dates.child).toBe(await page.$text('[data-date-child]'))
|
||||
expect(+date > +dates.slug).toBe(true)
|
||||
dates.slug = date
|
||||
})
|
||||
|
||||
test('Navigate to /patch/2/child/1?foo=bar', async () => {
|
||||
await page.nuxt.navigate('/patch/2/child/1?foo=bar')
|
||||
|
||||
expect(dates.patch).toBe(await page.$text('[data-date-patch]'))
|
||||
expect(dates.id).toBe(await page.$text('[data-date-id]'))
|
||||
expect(dates.child).toBe(await page.$text('[data-date-child]'))
|
||||
expect(dates.slug).toBe(await page.$text('[data-date-child-slug]'))
|
||||
})
|
||||
|
||||
test('Search a country', async () => {
|
||||
const countries = await page.$$text('[data-test-search-result]')
|
||||
expect(countries.length).toBe(5)
|
||||
|
||||
await page.type('[data-test-search-input]', 'gu')
|
||||
|
||||
await waitFor(250)
|
||||
const newCountries = await page.$$text('[data-test-search-result]', true)
|
||||
expect(newCountries.length).toBe(1)
|
||||
expect(newCountries).toEqual(['Guinea'])
|
||||
expect(await page.nuxt.routeData()).toEqual({
|
||||
path: '/patch/2/child/1',
|
||||
query: {
|
||||
foo: 'bar',
|
||||
q: 'gu'
|
||||
}
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
test('Navigate to /patch/2#test', async () => {
|
||||
await page.nuxt.navigate('/patch/2#test')
|
||||
expect(dates.patch).toBe(await page.$text('[data-date-patch]'))
|
||||
expect(dates.id).toBe(await page.$text('[data-date-id]'))
|
||||
})
|
||||
describe('reuse child component if param is changed but watchParam is false', () => {
|
||||
test('Navigate to /patch/2/reuse', async () => {
|
||||
await page.nuxt.navigate('/patch/2/reuse')
|
||||
dates.slug = await page.$text('[data-date-slug]')
|
||||
|
||||
test('Navigate to /patch/2/child', async () => {
|
||||
await page.nuxt.navigate('/patch/2/child')
|
||||
dates.child = await page.$text('[data-date-child]')
|
||||
dates.slug = await page.$text('[data-date-child-slug]')
|
||||
expect(dates.patch).toBe(await page.$text('[data-date-patch]'))
|
||||
expect(dates.id).toBe(await page.$text('[data-date-id]'))
|
||||
expect(+dates.child > +dates.id).toBe(true)
|
||||
})
|
||||
|
||||
expect(dates.patch).toBe(await page.$text('[data-date-patch]'))
|
||||
expect(dates.id).toBe(await page.$text('[data-date-id]'))
|
||||
expect(+dates.child > +dates.id).toBe(true)
|
||||
expect(+dates.slug > +dates.child).toBe(true)
|
||||
})
|
||||
test('Navigate to /patch/2/reuse/1', async () => {
|
||||
await page.nuxt.navigate('/patch/2/reuse/1')
|
||||
|
||||
test('Navigate to /patch/2/child/1', async () => {
|
||||
await page.nuxt.navigate('/patch/2/child/1')
|
||||
const date = await page.$text('[data-date-child-slug]')
|
||||
expect(dates.patch).toBe(await page.$text('[data-date-patch]'))
|
||||
expect(dates.id).toBe(await page.$text('[data-date-id]'))
|
||||
expect(dates.slug).toBe(await page.$text('[data-date-slug]'))
|
||||
})
|
||||
|
||||
expect(dates.patch).toBe(await page.$text('[data-date-patch]'))
|
||||
expect(dates.id).toBe(await page.$text('[data-date-id]'))
|
||||
expect(dates.child).toBe(await page.$text('[data-date-child]'))
|
||||
expect(+date > +dates.slug).toBe(true)
|
||||
dates.slug = date
|
||||
})
|
||||
test('Navigate to /patch/2/reuse/2', async () => {
|
||||
await page.nuxt.navigate('/patch/2/reuse/2')
|
||||
|
||||
test('Navigate to /patch/2/child/1?foo=bar', async () => {
|
||||
await page.nuxt.navigate('/patch/2/child/1?foo=bar')
|
||||
|
||||
expect(dates.patch).toBe(await page.$text('[data-date-patch]'))
|
||||
expect(dates.id).toBe(await page.$text('[data-date-id]'))
|
||||
expect(dates.child).toBe(await page.$text('[data-date-child]'))
|
||||
expect(dates.slug).toBe(await page.$text('[data-date-child-slug]'))
|
||||
})
|
||||
|
||||
test('Search a country', async () => {
|
||||
const countries = await page.$$text('[data-test-search-result]')
|
||||
expect(countries.length).toBe(5)
|
||||
|
||||
await page.type('[data-test-search-input]', 'gu')
|
||||
|
||||
await waitFor(250)
|
||||
const newCountries = await page.$$text('[data-test-search-result]', true)
|
||||
expect(newCountries.length).toBe(1)
|
||||
expect(newCountries).toEqual(['Guinea'])
|
||||
expect(await page.nuxt.routeData()).toEqual({
|
||||
path: '/patch/2/child/1',
|
||||
query: {
|
||||
foo: 'bar',
|
||||
q: 'gu'
|
||||
}
|
||||
expect(dates.patch).toBe(await page.$text('[data-date-patch]'))
|
||||
expect(dates.id).toBe(await page.$text('[data-date-id]'))
|
||||
expect(dates.slug).toBe(await page.$text('[data-date-slug]'))
|
||||
})
|
||||
})
|
||||
|
||||
|
15
test/fixtures/children/layouts/patch.vue
vendored
15
test/fixtures/children/layouts/patch.vue
vendored
@ -42,6 +42,21 @@
|
||||
/patch/2/child/1?query=true#test
|
||||
</NuxtLink>
|
||||
</li>
|
||||
<li>
|
||||
<NuxtLink data-test-id="patch-id-2-reuse" to="/patch/2/reuse">
|
||||
/patch/2/reuse
|
||||
</NuxtLink>
|
||||
</li>
|
||||
<li>
|
||||
<NuxtLink data-test-id="patch-id-2-reuse-2" to="/patch/2/reuse/1">
|
||||
/patch/2/reuse/1
|
||||
</NuxtLink>
|
||||
</li>
|
||||
<li>
|
||||
<NuxtLink data-test-id="patch-id-2-reuse-2" to="/patch/2/reuse/2">
|
||||
/patch/2/reuse/2
|
||||
</NuxtLink>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</template>
|
||||
|
20
test/fixtures/children/pages/patch/_id/reuse/_slug.vue
vendored
Normal file
20
test/fixtures/children/pages/patch/_id/reuse/_slug.vue
vendored
Normal file
@ -0,0 +1,20 @@
|
||||
<template>
|
||||
<div>
|
||||
<h4>
|
||||
_slug: <i data-date-slug>
|
||||
{{ date }}
|
||||
</i>
|
||||
</h4>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
watchParam: false,
|
||||
asyncData () {
|
||||
return {
|
||||
date: Date.now()
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
Loading…
Reference in New Issue
Block a user