Skip to content

Commit

Permalink
fix: fix asyncData hmr (#353)
Browse files Browse the repository at this point in the history
Co-authored-by: Florian Weber <f.weber@ppm-vi.de>
  • Loading branch information
exreplay and Florian Weber authored Apr 25, 2021
1 parent e6db761 commit 8f0efd5
Showing 1 changed file with 37 additions and 19 deletions.
56 changes: 37 additions & 19 deletions packages/@averjs/vue-app/templates/entry-client.js
Original file line number Diff line number Diff line change
Expand Up @@ -75,15 +75,28 @@ import { applyAsyncData, composeComponentOptions, sanitizeComponent } from './ut

hotReload() {
if (module.hot) {
const components = this.deepMapChildren(app.$root.$children, []);
const route = router.match(this.getLocation(router.options.base));
// Map the matched routes and return their ctor
const routes = route.matched.map(m => {
const component = m.components.default;
if (typeof component === 'object' && !component.options) return component._Ctor[0];
else return component;
});
const components = this.deepMapChildren(app.$root.$children, [], routes);
components.forEach(this.applyHmrUpdate.bind(this));
}
}

deepMapChildren(children, components) {
deepMapChildren(children, components, routes) {
for (const child of children) {
if (child.$options.asyncData) components.push(child);
if (child.$children && child.$children.length) this.deepMapChildren(child.$children, components);
// Compare the components ctor to find only router components
const isRoute = routes.find(r => r === child.$options._Ctor[0]);
if (isRoute) components.push(child);
// If App.vue component has no asyncData, push it anyway so that hmr works if it gets added later.
// Because the App.vue component always is the entry point we check if the parent is the root instance.
else if (!isRoute && child.$options.parent === app.$root) components.push(child);

if (child.$children && child.$children.length) this.deepMapChildren(child.$children, components, routes);
}

return components;
Expand All @@ -99,6 +112,7 @@ import { applyAsyncData, composeComponentOptions, sanitizeComponent } from './ut
component.$vnode.context.$forceUpdate = async function() {
if (index - 1 >= 0) {
const matched = router.currentRoute.matched[index - 1];
if (!matched) return;
for (const key of Object.keys(matched.components)) {
let Component = matched.components[key];

Expand All @@ -108,13 +122,15 @@ import { applyAsyncData, composeComponentOptions, sanitizeComponent } from './ut
}

const { asyncData } = Component.options;
const data = await asyncData({
app,
store,
route: { to: router.currentRoute },
isServer: false
});
applyAsyncData(Component, data);
if (asyncData) {
const data = await asyncData({
app,
store,
route: { to: router.currentRoute },
isServer: false
});
applyAsyncData(Component, data);
}
}
_forceUpdate();
setTimeout(() => hotReload(), 100);
Expand All @@ -124,15 +140,17 @@ import { applyAsyncData, composeComponentOptions, sanitizeComponent } from './ut
const Component = this.$children[0];

const { asyncData } = Component.$options;
const data = await asyncData({
app,
store,
route: { to: router.currentRoute },
isServer: false
});
if (asyncData) {
const data = await asyncData({
app,
store,
route: { to: router.currentRoute },
isServer: false
});

for (const key of Object.keys(data || {})) {
Component[key] = data[key];
for (const key of Object.keys(data || {})) {
Component[key] = data[key];
}
}

setTimeout(() => hotReload(), 100);
Expand Down

0 comments on commit 8f0efd5

Please sign in to comment.