Skip to content

Commit 29ff9bc

Browse files
kingyue737Justineo
authored andcommitted
feat: support native listener in Vue 3
1 parent 54d196c commit 29ff9bc

File tree

2 files changed

+41
-3
lines changed

2 files changed

+41
-3
lines changed

README.md

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -464,6 +464,30 @@ Vue-ECharts support the following events:
464464

465465
See supported events [here →](https://echarts.apache.org/en/api.html#events)
466466

467+
#### Native DOM Events
468+
469+
<details open>
470+
<summary>Vue 3</summary>
471+
472+
```vue
473+
<template>
474+
<v-chart @native:click="handleClick" />
475+
</template>
476+
```
477+
478+
</details>
479+
480+
<details open>
481+
<summary>Vue 2</summary>
482+
483+
```vue
484+
<template>
485+
<v-chart @click.native="handleClick" />
486+
</template>
487+
```
488+
489+
</details>
490+
467491
## CSP: `style-src` or `style-src-elem`
468492

469493
If you are applying a CSP to prevent inline `<style>` injection, you need to use files from `dist/csp` directory and include `dist/csp/style.css` into your app manually.

src/ECharts.ts

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ import {
3737
useLoading,
3838
loadingProps
3939
} from "./composables";
40-
import { omitOn, unwrapInjected } from "./utils";
40+
import { isOn, omitOn, unwrapInjected } from "./utils";
4141
import { register, TAG_NAME, type EChartsElement } from "./wc";
4242
import "./style.css";
4343

@@ -95,6 +95,7 @@ export default defineComponent({
9595
() => props.updateOptions || unwrapInjected(defaultUpdateOptions, {})
9696
);
9797
const nonEventAttrs = computed(() => omitOn(attrs));
98+
const nativeEventAttrs: Record<string, unknown> = {};
9899

99100
// @ts-expect-error listeners for Vue 2 compatibility
100101
const listeners = getCurrentInstance().proxy.$listeners;
@@ -119,12 +120,22 @@ export default defineComponent({
119120
realListeners = {};
120121

121122
Object.keys(attrs)
122-
.filter(key => key.indexOf("on") === 0 && key.length > 2)
123+
.filter(key => isOn(key))
123124
.forEach(key => {
124125
// onClick -> c + lick
125126
// onZr:click -> z + r:click
126127
let event = key.charAt(2).toLowerCase() + key.slice(3);
127128

129+
// Collect native events
130+
if (event.startsWith("native:")) {
131+
// native:click -> onClick
132+
const nativeKey =
133+
"on" + event.charAt(7).toUpperCase() + event.slice(8);
134+
135+
nativeEventAttrs[nativeKey] = attrs[key];
136+
return;
137+
}
138+
128139
// clickOnce -> ~click
129140
// zr:clickOnce -> ~zr:click
130141
if (event.substring(event.length - 4) === "Once") {
@@ -296,14 +307,17 @@ export default defineComponent({
296307
inner,
297308
setOption,
298309
nonEventAttrs,
310+
nativeEventAttrs,
299311
...publicApi
300312
};
301313
},
302314
render() {
303315
// Vue 3 and Vue 2 have different vnode props format:
304316
// See https://v3-migration.vuejs.org/breaking-changes/render-function-api.html#vnode-props-format
305317
const attrs = (
306-
Vue2 ? { attrs: this.nonEventAttrs } : { ...this.nonEventAttrs }
318+
Vue2
319+
? { attrs: this.nonEventAttrs }
320+
: { ...this.nonEventAttrs, ...this.nativeEventAttrs }
307321
) as any;
308322
attrs.ref = "root";
309323
attrs.class = attrs.class ? ["echarts"].concat(attrs.class) : "echarts";

0 commit comments

Comments
 (0)