8000 feat(hmr): improved Page HMR · saidv/nativescript-vue@0e7406d · GitHub
[go: up one dir, main page]

Skip to content

Commit 0e7406d

Browse files
committed
feat(hmr): improved Page HMR
1 parent fda7405 commit 0e7406d

File tree

3 files changed

+72
-20
lines changed

3 files changed

+72
-20
lines changed

demo/app/components/Home.vue

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
11
<script setup lang="ts">
2-
import Test from './Test.vue';
2+
import { ListItem, onMounted, onUnmounted } from 'nativescript-vue';
33
import { goHome } from '~/composables/goHome';
4-
import { onUnmounted 8000 } from 'nativescript-vue';
5-
import { ListItem } from 'nativescript-vue';
4+
import Test from './Test.vue';
65
76
defineProps({
87
depth: {
@@ -11,7 +10,7 @@ defineProps({
1110
},
1211
});
1312
14-
const message = 'Hello World!';
13+
const message = 'Hello World!!';
1514
1615
interface Test {
1716
name: string;
@@ -31,6 +30,10 @@ function selector(item: ListItem<Test>) {
3130
return item.even ? 'default' : 'odd';
3231
}
3332
33+
onMounted(() => {
34+
console.log('MOUNTED HOME');
35+
});
36+
3437
onUnmounted(() => {
3538
console.log('UNMOUNTED HOME');
3639
});

src/plugins/navigation.ts

Lines changed: 60 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { Frame, NavigationEntry, Page } from '@nativescript/core';
22
import { App, Component, Ref, nextTick, unref } from '@vue/runtime-core';
3-
import { NSVElement } from '../dom';
3+
import { NSVElement, NSVRoot } from '../dom';
44
import { createNativeView } from '../runtimeHelpers';
55

66
declare module '@vue/runtime-core' {
@@ -69,28 +69,75 @@ export function $navigateTo(
6969
throw new Error('Failed to resolve frame. Make sure your frame exists.');
7070
}
7171

72-
let view = createNativeView<Page>(target, options?.props);
72+
const root = new NSVRoot();
73+
let isReloading = false;
7374

74-
view.mount();
75+
const attachDisposeCallback = (page: Page) => {
76+
const dispose = page.disposeNativeView;
7577

76-
const page = view.nativeView;
77-
const dispose = page.disposeNativeView;
78+
page.disposeNativeView = () => {
79+
dispose.call(page);
7880

79-
page.disposeNativeView = () => {
80-
dispose.call(page);
81-
82-
nextTick(() => {
83-
view.unmount();
84-
view = null;
81+
// if we are reloading, don't unmount the view, as the reload will unmount/remount it.
82+
if (!isReloading) {
83+
view.unmount();
84+
view = null;
85+
}
86+
};
87+
};
88+
const reloadPage = () => {
89+
if (isReloading) {
90+
return;
91+
}
92+
93+
// if the page we are reloading is not the current page, wait for it to be navigated to
94+
if (frame.currentPage !== view.nativeView) {
95+
view.nativeView.once('navigatedTo', () => {
96+
nextTick(() => {
97+
reloadPage();
98+
});
99+
});
100+
return;
101+
}
102+
103+
isReloading = true;
104+
view.unmount();
105+
view.mount(root);
106+
attachDisposeCallback(view.nativeView);
107+
108+
const originalTransition = frame.currentEntry.transition;
109+
// replace current page
110+
frame.replacePage({
111+
...options,
112+
transition: {
113+
name: 'fade',
114+
duration: 10,
115+
},
116+
create: () => view.nativeView,
117+
});
118+
// reset the transition to the original one
119+
frame.once('navigatedTo', () => {
120+
frame.currentEntry.transition = originalTransition;
121+
isReloading = false;
85122
});
86123
};
87124

125+
let view = createNativeView<Page>(target, options?.props, {
126+
/**
127+
* Called by @vue/runtime-core when the component is reloaded during HMR.
128+
*/
129+
reload: reloadPage,
130+
});
131+
132+
view.mount(root);
133+
attachDisposeCallback(view.nativeView);
134+
88135
frame.navigate({
89136
...options,
90-
create: () => page,
137+
create: () => view.nativeView,
91138
});
92139

93-
return page;
140+
return view.nativeView;
94141
} catch (e) {
95142
console.error('[$navigateTo] Failed to navigate:\n\n');
96143
console.error(e, e.stack);

src/runtimeHelpers.ts

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,12 +22,13 @@ export const setRootContext = (context: AppContext) => {
2222

2323
export const createNativeView = <T = View>(
2424
component: Component,
25-
props?: Props
25+
props?: Props,
26+
contextOverrides?: any
2627
) => {
2728
let vnode: VNode;
2829
let isMounted = false;
2930
let container: NSVNode;
30-
const context = { ...rootContext };
31+
const context = { ...rootContext, ...contextOverrides };
3132

3233
type M = VNode<RendererNode, RendererElement, { nativeView: T }>;
3334

@@ -54,8 +55,9 @@ export const createNativeView = <T = View>(
5455
},
5556
unmount() {
5657
if (!isMounted) return;
57-
renderer.render(null, container);
5858
vnode = null;
59+
renderer.render(null, container);
60+
isMounted = false;
5961
container = null;
6062
3CAB },
6163
};

0 commit comments

Comments
 (0)
0