Skip to content

Commit 0a4601b

Browse files
committed
feat: delay disposal to disconnection if possible
1 parent 3b2f2b5 commit 0a4601b

File tree

6 files changed

+75
-9
lines changed

6 files changed

+75
-9
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
## 6.4.0
2+
3+
* Delay the disposal of the ECharts instance to the moment the element is disconnected from the DOM if possible (#433).
4+
15
## 6.3.3
26

37
* Make autoresize work for grid layout by default (#675).

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -227,7 +227,7 @@ Drop `<script>` inside your HTML file and access the component via `window.VueEC
227227
```html
228228
<script src="https://cdn.jsdelivr.net/npm/[email protected]"></script>
229229
<script src="https://cdn.jsdelivr.net/npm/[email protected]"></script>
230-
<script src="https://cdn.jsdelivr.net/npm/vue-echarts@6.3.3"></script>
230+
<script src="https://cdn.jsdelivr.net/npm/vue-echarts@6.4.0"></script>
231231
```
232232
<!-- vue3Scripts:end -->
233233

@@ -247,7 +247,7 @@ app.component('v-chart', VueECharts)
247247
```html
248248
<script src="https://cdn.jsdelivr.net/npm/[email protected]"></script>
249249
<script src="https://cdn.jsdelivr.net/npm/[email protected]"></script>
250-
<script src="https://cdn.jsdelivr.net/npm/vue-echarts@6.3.3"></script>
250+
<script src="https://cdn.jsdelivr.net/npm/vue-echarts@6.4.0"></script>
251251
```
252252
<!-- vue2Scripts:end -->
253253

README.zh-Hans.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -225,7 +225,7 @@ import "echarts";
225225
```html
226226
<script src="https://cdn.jsdelivr.net/npm/[email protected]"></script>
227227
<script src="https://cdn.jsdelivr.net/npm/[email protected]"></script>
228-
<script src="https://cdn.jsdelivr.net/npm/vue-echarts@6.3.3"></script>
228+
<script src="https://cdn.jsdelivr.net/npm/vue-echarts@6.4.0"></script>
229229
```
230230
<!-- vue3Scripts:end -->
231231

@@ -245,7 +245,7 @@ app.component('v-chart', VueECharts)
245245
```html
246246
<script src="https://cdn.jsdelivr.net/npm/[email protected]"></script>
247247
<script src="https://cdn.jsdelivr.net/npm/[email protected]"></script>
248-
<script src="https://cdn.jsdelivr.net/npm/vue-echarts@6.3.3"></script>
248+
<script src="https://cdn.jsdelivr.net/npm/vue-echarts@6.4.0"></script>
249249
```
250250
<!-- vue2Scripts:end -->
251251

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "vue-echarts",
3-
"version": "6.3.3",
3+
"version": "6.4.0",
44
"description": "Vue.js component for Apache ECharts.",
55
"author": "GU Yiling <[email protected]>",
66
"scripts": {

src/ECharts.ts

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import {
88
computed,
99
inject,
1010
onMounted,
11-
onUnmounted,
11+
onBeforeUnmount,
1212
h,
1313
nextTick,
1414
watchEffect,
@@ -38,9 +38,10 @@ import {
3838
loadingProps
3939
} from "./composables";
4040
import { omitOn, unwrapInjected } from "./utils";
41+
import { register, TAG_NAME, type EChartsElement } from "./wc";
4142
import "./style.css";
4243

43-
const TAG_NAME = "x-vue-echarts";
44+
const wcRegistered = register();
4445

4546
if (Vue2) {
4647
Vue2.config.ignoredElements.push(TAG_NAME);
@@ -70,7 +71,7 @@ export default defineComponent({
7071
emits: [] as unknown as Emits,
7172
inheritAttrs: false,
7273
setup(props, { attrs }) {
73-
const root = shallowRef<HTMLElement>();
74+
const root = shallowRef<EChartsElement>();
7475
const chart = shallowRef<EChartsType>();
7576
const manualOption = shallowRef<Option>();
7677
const defaultTheme = inject(THEME_KEY, null);
@@ -273,7 +274,17 @@ export default defineComponent({
273274
init();
274275
});
275276

276-
onUnmounted(cleanup);
277+
onBeforeUnmount(() => {
278+
if (wcRegistered && root.value) {
279+
// For registered web component, we can leverage the
280+
// `disconnectedCallback` to dispose the chart instance
281+
// so that we can delay the cleanup after exsiting leaving
282+
// transition.
283+
root.value.__dispose = cleanup;
284+
} else {
285+
cleanup();
286+
}
287+
});
277288

278289
return {
279290
chart,

src/wc.ts

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
let registered: boolean | null = null;
2+
3+
export const TAG_NAME = "x-vue-echarts";
4+
5+
export interface EChartsElement extends HTMLElement {
6+
__dispose: (() => void) | null;
7+
}
8+
9+
export function register(): boolean {
10+
if (registered != null) {
11+
return registered;
12+
}
13+
14+
if (
15+
typeof HTMLElement === "undefined" ||
16+
typeof customElements === "undefined"
17+
) {
18+
return (registered = false);
19+
}
20+
21+
try {
22+
// Class definitions cannot be transpiled to ES5
23+
// so we are doing a little trick here to ensure
24+
// we are using native classes. As we use this as
25+
// a progressive enhancement, it will be fine even
26+
// if the browser doesn't support native classes.
27+
const reg = new Function(
28+
"tag",
29+
`class EChartsElement extends HTMLElement {
30+
__dispose = null;
31+
32+
disconnectedCallback() {
33+
if (this.__dispose) {
34+
this.__dispose();
35+
this.__dispose = null;
36+
}
37+
}
38+
}
39+
40+
if (customElements.get(tag) == null) {
41+
customElements.define(tag, EChartsElement);
42+
}
43+
`
44+
);
45+
reg(TAG_NAME);
46+
} catch (e) {
47+
return (registered = false);
48+
}
49+
50+
return (registered = true);
51+
}

0 commit comments

Comments
 (0)