feat: support native listener in Vue 3

This commit is contained in:
Yue JIN
2024-02-29 14:52:27 +08:00
committed by GU Yiling
parent 54d196c9d5
commit 29ff9bc52a
2 changed files with 41 additions and 3 deletions

View File

@ -464,6 +464,30 @@ Vue-ECharts support the following events:
See supported events [here →](https://echarts.apache.org/en/api.html#events)
#### Native DOM Events
<details open>
<summary>Vue 3</summary>
```vue
<template>
<v-chart @native:click="handleClick" />
</template>
```
</details>
<details open>
<summary>Vue 2</summary>
```vue
<template>
<v-chart @click.native="handleClick" />
</template>
```
</details>
## CSP: `style-src` or `style-src-elem`
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.

View File

@ -37,7 +37,7 @@ import {
useLoading,
loadingProps
} from "./composables";
import { omitOn, unwrapInjected } from "./utils";
import { isOn, omitOn, unwrapInjected } from "./utils";
import { register, TAG_NAME, type EChartsElement } from "./wc";
import "./style.css";
@ -95,6 +95,7 @@ export default defineComponent({
() => props.updateOptions || unwrapInjected(defaultUpdateOptions, {})
);
const nonEventAttrs = computed(() => omitOn(attrs));
const nativeEventAttrs: Record<string, unknown> = {};
// @ts-expect-error listeners for Vue 2 compatibility
const listeners = getCurrentInstance().proxy.$listeners;
@ -119,12 +120,22 @@ export default defineComponent({
realListeners = {};
Object.keys(attrs)
.filter(key => key.indexOf("on") === 0 && key.length > 2)
.filter(key => isOn(key))
.forEach(key => {
// onClick -> c + lick
// onZr:click -> z + r:click
let event = key.charAt(2).toLowerCase() + key.slice(3);
// Collect native events
if (event.startsWith("native:")) {
// native:click -> onClick
const nativeKey =
"on" + event.charAt(7).toUpperCase() + event.slice(8);
nativeEventAttrs[nativeKey] = attrs[key];
return;
}
// clickOnce -> ~click
// zr:clickOnce -> ~zr:click
if (event.substring(event.length - 4) === "Once") {
@ -296,6 +307,7 @@ export default defineComponent({
inner,
setOption,
nonEventAttrs,
nativeEventAttrs,
...publicApi
};
},
@ -303,7 +315,9 @@ export default defineComponent({
// Vue 3 and Vue 2 have different vnode props format:
// See https://v3-migration.vuejs.org/breaking-changes/render-function-api.html#vnode-props-format
const attrs = (
Vue2 ? { attrs: this.nonEventAttrs } : { ...this.nonEventAttrs }
Vue2
? { attrs: this.nonEventAttrs }
: { ...this.nonEventAttrs, ...this.nativeEventAttrs }
) as any;
attrs.ref = "root";
attrs.class = attrs.class ? ["echarts"].concat(attrs.class) : "echarts";