feat!: remove vue 2

This commit is contained in:
Yue JIN
2025-05-11 16:00:37 +08:00
committed by Yue JIN
parent b7852ab643
commit ca6d44f8db
14 changed files with 350 additions and 368 deletions

View File

@ -212,7 +212,7 @@ Drop `<script>` inside your HTML file and access the component via `window.VueEC
<!-- vue3Scripts:start --> <!-- vue3Scripts:start -->
```html ```html
<script src="https://cdn.jsdelivr.net/npm/vue@3.4.33"></script> <script src="https://cdn.jsdelivr.net/npm/vue@3.5.13"></script>
<script src="https://cdn.jsdelivr.net/npm/echarts@5.5.1"></script> <script src="https://cdn.jsdelivr.net/npm/echarts@5.5.1"></script>
<script src="https://cdn.jsdelivr.net/npm/vue-echarts@7.0.3"></script> <script src="https://cdn.jsdelivr.net/npm/vue-echarts@7.0.3"></script>
``` ```
@ -227,24 +227,6 @@ app.component('v-chart', VueECharts)
</details> </details>
<details>
<summary>Vue 2 <a href="https://stackblitz.com/edit/vue-echarts-vue-2-global?file=index.html">Demo →</a></summary>
<!-- vue2Scripts:start -->
```html
<script src="https://cdn.jsdelivr.net/npm/vue@2.7.16"></script>
<script src="https://cdn.jsdelivr.net/npm/echarts@5.5.1"></script>
<script src="https://cdn.jsdelivr.net/npm/vue-echarts@7.0.3"></script>
```
<!-- vue2Scripts:end -->
```js
// register globally (or you can do it locally)
Vue.component("v-chart", VueECharts);
```
</details>
See more examples [here](https://github.com/ecomfe/vue-echarts/tree/main/src/demo). See more examples [here](https://github.com/ecomfe/vue-echarts/tree/main/src/demo).
### Props ### Props

View File

@ -212,7 +212,7 @@ import "echarts";
<!-- vue3Scripts:start --> <!-- vue3Scripts:start -->
```html ```html
<script src="https://cdn.jsdelivr.net/npm/vue@3.4.33"></script> <script src="https://cdn.jsdelivr.net/npm/vue@3.5.13"></script>
<script src="https://cdn.jsdelivr.net/npm/echarts@5.5.1"></script> <script src="https://cdn.jsdelivr.net/npm/echarts@5.5.1"></script>
<script src="https://cdn.jsdelivr.net/npm/vue-echarts@7.0.3"></script> <script src="https://cdn.jsdelivr.net/npm/vue-echarts@7.0.3"></script>
``` ```
@ -227,24 +227,6 @@ app.component('v-chart', VueECharts)
</details> </details>
<details>
<summary>Vue 2 <a href="https://stackblitz.com/edit/vue-echarts-vue-2-global?file=index.html">Demo →</a></summary>
<!-- vue2Scripts:start -->
```html
<script src="https://cdn.jsdelivr.net/npm/vue@2.7.16"></script>
<script src="https://cdn.jsdelivr.net/npm/echarts@5.5.1"></script>
<script src="https://cdn.jsdelivr.net/npm/vue-echarts@7.0.3"></script>
```
<!-- vue2Scripts:end -->
```js
// 全局注册组件(也可以使用局部注册)
Vue.component("v-chart", VueECharts);
```
</details>
可以在[这里](https://github.com/ecomfe/vue-echarts/tree/main/src/demo)查看更多例子。 可以在[这里](https://github.com/ecomfe/vue-echarts/tree/main/src/demo)查看更多例子。
### Prop ### Prop

View File

@ -8,7 +8,7 @@
"scripts": { "scripts": {
"serve": "vue-cli-service serve", "serve": "vue-cli-service serve",
"build": "pnpm run docs && rimraf dist && pnpm run build:rollup", "build": "pnpm run docs && rimraf dist && pnpm run build:rollup",
"build:rollup": "vue-demi-switch 3 && rollup -c rollup.config.js", "build:rollup": "rollup -c rollup.config.js",
"lint": "vue-cli-service lint", "lint": "vue-cli-service lint",
"publint": "publint", "publint": "publint",
"build:demo": "vue-cli-service build", "build:demo": "vue-cli-service build",
@ -29,13 +29,10 @@
"dist", "dist",
"scripts/postinstall.js" "scripts/postinstall.js"
], ],
"dependencies": {
"vue-demi": "^0.13.11"
},
"peerDependencies": { "peerDependencies": {
"@vue/runtime-core": "^3.0.0", "@vue/runtime-core": "^3.0.0",
"echarts": "^5.5.1", "echarts": "^5.5.1",
"vue": "^2.7.0 || ^3.1.1" "vue": "^3.1.1"
}, },
"peerDependenciesMeta": { "peerDependenciesMeta": {
"@vue/runtime-core": { "@vue/runtime-core": {
@ -57,7 +54,7 @@
"@vue/compiler-sfc": "^3.4.33", "@vue/compiler-sfc": "^3.4.33",
"@vue/eslint-config-prettier": "^9.0.0", "@vue/eslint-config-prettier": "^9.0.0",
"@vue/eslint-config-typescript": "^13.0.0", "@vue/eslint-config-typescript": "^13.0.0",
"@vueuse/core": "^10.11.0", "@vueuse/core": "^13.1.0",
"comment-mark": "^1.1.1", "comment-mark": "^1.1.1",
"core-js": "^3.37.1", "core-js": "^3.37.1",
"echarts": "^5.5.1", "echarts": "^5.5.1",
@ -68,7 +65,7 @@
"eslint-plugin-prettier": "^5.2.1", "eslint-plugin-prettier": "^5.2.1",
"eslint-plugin-vue": "^9.27.0", "eslint-plugin-vue": "^9.27.0",
"highlight.js": "^11.10.0", "highlight.js": "^11.10.0",
"pinia": "^2.1.7", "pinia": "^3.0.2",
"postcss": "^8.4.39", "postcss": "^8.4.39",
"postcss-loader": "^8.1.1", "postcss-loader": "^8.1.1",
"postcss-nested": "^6.2.0", "postcss-nested": "^6.2.0",
@ -83,8 +80,7 @@
"rollup-plugin-import-css": "^3.5.1", "rollup-plugin-import-css": "^3.5.1",
"tslib": "^2.6.3", "tslib": "^2.6.3",
"typescript": "5.5.4", "typescript": "5.5.4",
"vue": "^3.4.33", "vue": "^3.5.13",
"vue2": "npm:vue@^2.7.16",
"webpack": "^5.93.0" "webpack": "^5.93.0"
} }
} }

475
pnpm-lock.yaml generated

File diff suppressed because it is too large Load Diff

View File

@ -2,7 +2,6 @@ import replace from "@rollup/plugin-replace";
import esbuild from "rollup-plugin-esbuild"; import esbuild from "rollup-plugin-esbuild";
import { dts } from "rollup-plugin-dts"; import { dts } from "rollup-plugin-dts";
import css from "rollup-plugin-import-css"; import css from "rollup-plugin-import-css";
import { injectVueDemi } from "./scripts/rollup.mjs";
/** /**
* Modifies the Rollup options for a build to support strict CSP * Modifies the Rollup options for a build to support strict CSP
@ -39,7 +38,7 @@ const builds = [
{ {
input: "src/index.ts", input: "src/index.ts",
plugins: [esbuild()], plugins: [esbuild()],
external: ["vue-demi", /^echarts/], external: ["vue", /^echarts/],
output: [ output: [
{ {
file: "dist/index.js", file: "dist/index.js",
@ -51,7 +50,7 @@ const builds = [
{ {
input: "src/global.ts", input: "src/global.ts",
plugins: [esbuild({ minify: true })], plugins: [esbuild({ minify: true })],
external: ["vue-demi", /^echarts/], external: ["vue", /^echarts/],
output: [ output: [
{ {
file: "dist/index.min.js", // for unpkg/jsdelivr file: "dist/index.min.js", // for unpkg/jsdelivr
@ -60,11 +59,10 @@ const builds = [
exports: "default", exports: "default",
sourcemap: true, sourcemap: true,
globals: { globals: {
"vue-demi": "VueDemi", vue: "vue",
echarts: "echarts", echarts: "echarts",
"echarts/core": "echarts" "echarts/core": "echarts"
}, }
plugins: [injectVueDemi]
} }
] ]
} }

View File

@ -7,19 +7,13 @@ const { name, version } = getPackageMeta();
const CDN_PREFIX = "https://cdn.jsdelivr.net/npm/"; const CDN_PREFIX = "https://cdn.jsdelivr.net/npm/";
const DEP_VERSIONS = { const DEP_VERSIONS = {
"vue@3": "3.4.33", "vue@3": "3.5.13",
"vue@2": "2.7.16",
echarts: "5.5.1", echarts: "5.5.1",
[name]: version [name]: version
}; };
const markConfig = { function getScripts() {
vue3Scripts: ["vue@3", "echarts", name], const deps = ["vue@3", "echarts", name];
vue2Scripts: ["vue@2", "echarts", name]
};
function getScripts(version) {
const deps = markConfig[`vue${version}Scripts`];
return deps return deps
.map(dep => { .map(dep => {
const [, name] = dep.match(/^(.+?)(?:@.+)?$/) || []; const [, name] = dep.match(/^(.+?)(?:@.+)?$/) || [];
@ -32,11 +26,6 @@ function getCodeBlock(code) {
return "```html\n" + code + "\n```"; return "```html\n" + code + "\n```";
} }
const scripts = {
2: getScripts(2),
3: getScripts(3)
};
const README_FILES = ["README.md", "README.zh-Hans.md"].map(name => const README_FILES = ["README.md", "README.zh-Hans.md"].map(name =>
resolvePath(import.meta.url, "..", name) resolvePath(import.meta.url, "..", name)
); );
@ -47,8 +36,7 @@ README_FILES.forEach(file => {
writeFileSync( writeFileSync(
file, file,
commentMark(content, { commentMark(content, {
vue2Scripts: getCodeBlock(scripts[2]), vue3Scripts: getCodeBlock(getScripts())
vue3Scripts: getCodeBlock(scripts[3])
}), }),
"utf8" "utf8"
); );

View File

@ -1,17 +0,0 @@
import { readFileSync } from "node:fs";
import { createRequire } from "node:module";
const require = createRequire(import.meta.url);
const VUE_DEMI_IIFE = readFileSync(
require.resolve("vue-demi/lib/index.iife.js"),
"utf8"
);
/** @type {import('rollup').Plugin} */
export const injectVueDemi = {
name: "inject-vue-demi",
banner() {
return `${VUE_DEMI_IIFE};\n;`;
}
};

View File

@ -12,9 +12,8 @@ import {
h, h,
nextTick, nextTick,
watchEffect, watchEffect,
getCurrentInstance, unref
Vue2 } from "vue";
} from "vue-demi";
import { init as initChart } from "echarts/core"; import { init as initChart } from "echarts/core";
import { import {
@ -24,10 +23,10 @@ import {
useLoading, useLoading,
loadingProps loadingProps
} from "./composables"; } from "./composables";
import { isOn, omitOn, unwrapInjected } from "./utils"; import { isOn, omitOn } from "./utils";
import { register, TAG_NAME } from "./wc"; import { register, TAG_NAME } from "./wc";
import type { PropType, InjectionKey } from "vue-demi"; import type { PropType, InjectionKey } from "vue";
import type { import type {
EChartsType, EChartsType,
EventTarget, EventTarget,
@ -47,10 +46,6 @@ import "./style.css";
const __CSP__ = false; const __CSP__ = false;
const wcRegistered = __CSP__ ? false : register(); const wcRegistered = __CSP__ ? false : register();
if (Vue2) {
Vue2.config.ignoredElements.push(TAG_NAME);
}
export const THEME_KEY = "ecTheme" as unknown as InjectionKey<ThemeInjection>; export const THEME_KEY = "ecTheme" as unknown as InjectionKey<ThemeInjection>;
export const INIT_OPTIONS_KEY = export const INIT_OPTIONS_KEY =
"ecInitOptions" as unknown as InjectionKey<InitOptionsInjection>; "ecInitOptions" as unknown as InjectionKey<InitOptionsInjection>;
@ -58,8 +53,6 @@ export const UPDATE_OPTIONS_KEY =
"ecUpdateOptions" as unknown as InjectionKey<UpdateOptionsInjection>; "ecUpdateOptions" as unknown as InjectionKey<UpdateOptionsInjection>;
export { LOADING_OPTIONS_KEY } from "./composables"; export { LOADING_OPTIONS_KEY } from "./composables";
const NATIVE_EVENT_RE = /(^&?~?!?)native:/;
export default defineComponent({ export default defineComponent({
name: "echarts", name: "echarts",
props: { props: {
@ -89,24 +82,18 @@ export default defineComponent({
const realOption = computed( const realOption = computed(
() => manualOption.value || props.option || null () => manualOption.value || props.option || null
); );
const realTheme = computed( const realTheme = computed(() => props.theme || unref(defaultTheme) || {});
() => props.theme || unwrapInjected(defaultTheme, {})
);
const realInitOptions = computed( const realInitOptions = computed(
() => props.initOptions || unwrapInjected(defaultInitOptions, {}) () => props.initOptions || unref(defaultInitOptions) || {}
); );
const realUpdateOptions = computed( const realUpdateOptions = computed(
() => props.updateOptions || unwrapInjected(defaultUpdateOptions, {}) () => props.updateOptions || unref(defaultUpdateOptions) || {}
); );
const nonEventAttrs = computed(() => omitOn(attrs)); const nonEventAttrs = computed(() => omitOn(attrs));
const nativeListeners: Record<string, unknown> = {}; const nativeListeners: Record<string, unknown> = {};
// @ts-expect-error listeners for Vue 2 compatibility
const listeners = getCurrentInstance().proxy.$listeners;
const realListeners: Record<string, any> = {}; const realListeners: Record<string, any> = {};
if (!listeners) {
// This is for Vue 3.
// We are converting all `on<Event>` props to event listeners compatible with Vue 2 // We are converting all `on<Event>` props to event listeners compatible with Vue 2
// and collect them into `realListeners` so that we can bind them to the chart instance // and collect them into `realListeners` so that we can bind them to the chart instance
// later in the same way. // later in the same way.
@ -138,23 +125,6 @@ export default defineComponent({
realListeners[event] = attrs[key]; realListeners[event] = attrs[key];
}); });
} else {
// This is for Vue 2.
// We just need to distinguish normal events and `native:<event>` events and
// collect them into `realListeners` and `nativeListeners` respectively.
// For `native:<event>` events, we just strip the `native:` part and collect them
// into `nativeListeners` so that we can bind them to the root element directly.
// native:click -> click
// ~native:click -> ~click
// &~!native:click -> &~!click
Object.keys(listeners).forEach(key => {
if (NATIVE_EVENT_RE.test(key)) {
nativeListeners[key.replace(NATIVE_EVENT_RE, "$1")] = listeners[key];
} else {
realListeners[key] = listeners[key];
}
});
}
function init(option?: Option) { function init(option?: Option) {
if (!root.value) { if (!root.value) {
@ -336,13 +306,7 @@ export default defineComponent({
}; };
}, },
render() { render() {
// Vue 3 and Vue 2 have different vnode props format: const attrs = { ...this.nonEventAttrs, ...this.nativeListeners };
// See https://v3-migration.vuejs.org/breaking-changes/render-function-api.html#vnode-props-format
const attrs = (
Vue2
? { attrs: this.nonEventAttrs, on: this.nativeListeners }
: { ...this.nonEventAttrs, ...this.nativeListeners }
) as any;
attrs.ref = "root"; attrs.ref = "root";
attrs.class = attrs.class ? ["echarts"].concat(attrs.class) : "echarts"; attrs.class = attrs.class ? ["echarts"].concat(attrs.class) : "echarts";
return h(TAG_NAME, attrs); return h(TAG_NAME, attrs);

View File

@ -1,5 +1,5 @@
/* eslint-disable @typescript-eslint/no-explicit-any */ /* eslint-disable @typescript-eslint/no-explicit-any */
import type { Ref } from "vue-demi"; import type { Ref } from "vue";
import type { EChartsType } from "../types"; import type { EChartsType } from "../types";
const METHOD_NAMES = [ const METHOD_NAMES = [

View File

@ -1,7 +1,7 @@
import { watch } from "vue-demi"; import { watch } from "vue";
import { throttle } from "echarts/core"; import { throttle } from "echarts/core";
import type { Ref, PropType } from "vue-demi"; import type { Ref, PropType } from "vue";
import type { EChartsType, AutoResize } from "../types"; import type { EChartsType, AutoResize } from "../types";
export function useAutoresize( export function useAutoresize(

View File

@ -1,7 +1,6 @@
import { unwrapInjected } from "../utils"; import { inject, computed, watchEffect, unref } from "vue";
import { inject, computed, watchEffect } from "vue-demi";
import type { Ref, InjectionKey, PropType } from "vue-demi"; import type { Ref, InjectionKey, PropType } from "vue";
import type { EChartsType, LoadingOptions } from "../types"; import type { EChartsType, LoadingOptions } from "../types";
export const LOADING_OPTIONS_KEY = export const LOADING_OPTIONS_KEY =
@ -16,7 +15,7 @@ export function useLoading(
): void { ): void {
const defaultLoadingOptions = inject(LOADING_OPTIONS_KEY, {}); const defaultLoadingOptions = inject(LOADING_OPTIONS_KEY, {});
const realLoadingOptions = computed(() => ({ const realLoadingOptions = computed(() => ({
...unwrapInjected(defaultLoadingOptions, {}), ...(unref(defaultLoadingOptions) || {}),
...loadingOptions?.value ...loadingOptions?.value
})); }));

2
src/index.d.ts vendored
View File

@ -1,5 +1,5 @@
/* eslint-disable @typescript-eslint/ban-types */ /* eslint-disable @typescript-eslint/ban-types */
import type { Ref, DefineComponent, InjectionKey } from "vue-demi"; import type { Ref, DefineComponent, InjectionKey } from "vue";
import type { import type {
Option, Option,
Theme, Theme,

View File

@ -1,9 +1,9 @@
import { init } from "echarts/core"; import { init } from "echarts/core";
import type { SetOptionOpts, ECElementEvent, ElementEvent } from "echarts/core"; import type { SetOptionOpts, ECElementEvent, ElementEvent } from "echarts/core";
import type { Ref } from "vue-demi"; import type { MaybeRef } from "vue";
export type Injection<T> = T | null | Ref<T | null> | { value: T | null }; export type Injection<T> = MaybeRef<T | null>;
type InitType = typeof init; type InitType = typeof init;
export type InitParameters = Parameters<InitType>; export type InitParameters = Parameters<InitType>;

View File

@ -1,7 +1,3 @@
import { unref, isRef } from "vue-demi";
import type { Injection } from "./types";
type Attrs = { type Attrs = {
// eslint-disable-next-line @typescript-eslint/no-explicit-any // eslint-disable-next-line @typescript-eslint/no-explicit-any
[key: string]: any; [key: string]: any;
@ -22,16 +18,3 @@ export function omitOn(attrs: Attrs): Attrs {
return result; return result;
} }
export function unwrapInjected<T, V>(
injection: Injection<T>,
defaultValue: V
): T | V {
const value = isRef(injection) ? unref(injection) : injection;
if (value && typeof value === "object" && "value" in value) {
return value.value || defaultValue;
}
return value || defaultValue;
}