feat: support ref for provide api

This commit is contained in:
Justineo
2021-02-22 14:14:54 +08:00
parent 5744cd1f53
commit cd02c3131c
6 changed files with 128 additions and 7 deletions

View File

@ -80,6 +80,14 @@ new Vue(...)
</details> </details>
We encourage manually importing components and charts from ECharts for smaller bundle size. See all supported renderers/charts/components [here →](https://github.com/apache/echarts/blob/master/src/echarts.all.ts)
But if you really want to import the whole ECharts bundle without having to import modules manually, just add this in your code:
```js
import "echarts";
```
### CDN & Global variable ### CDN & Global variable
Drop `<script>` inside your HTML file as follows: Drop `<script>` inside your HTML file as follows:
@ -141,6 +149,8 @@ See more examples [here](https://github.com/ecomfe/vue-echarts/tree/next/src/dem
Optional chart init configurations. See `echarts.init`'s `opts` parameter [here →](https://echarts.apache.org/en/api.html#echarts.init) Optional chart init configurations. See `echarts.init`'s `opts` parameter [here →](https://echarts.apache.org/en/api.html#echarts.init)
Injection key: `INIT_OPTIONS_KEY`.
- `theme: string | object` - `theme: string | object`
Theme to be applied. See `echarts.init`'s `theme` parameter [here →](https://echarts.apache.org/en/api.html#echarts.init) Theme to be applied. See `echarts.init`'s `theme` parameter [here →](https://echarts.apache.org/en/api.html#echarts.init)
@ -153,6 +163,8 @@ See more examples [here](https://github.com/ecomfe/vue-echarts/tree/next/src/dem
Options for updating chart option. See `echartsInstance.setOption`'s `opts` parameter [here →](https://echarts.apache.org/en/api.html#echartsInstance.setOption) Options for updating chart option. See `echartsInstance.setOption`'s `opts` parameter [here →](https://echarts.apache.org/en/api.html#echartsInstance.setOption)
Injection key: `UPDATE_OPTIONS_KEY`.
- `group: string` - `group: string`
Group name to be used in chart [connection](https://echarts.apache.org/en/api.html#echarts.connect). See `echartsInstance.group` [here →](https://echarts.apache.org/en/api.html#echartsInstance.group) Group name to be used in chart [connection](https://echarts.apache.org/en/api.html#echarts.connect). See `echartsInstance.group` [here →](https://echarts.apache.org/en/api.html#echartsInstance.group)
@ -169,10 +181,52 @@ See more examples [here](https://github.com/ecomfe/vue-echarts/tree/next/src/dem
Configuration item of loading animation. See `echartsInstance.showLoading`'s `opts` parameter [here →](https://echarts.apache.org/en/api.html#echartsInstance.showLoading) Configuration item of loading animation. See `echartsInstance.showLoading`'s `opts` parameter [here →](https://echarts.apache.org/en/api.html#echartsInstance.showLoading)
Injection key: `LOADING_OPTIONS_KEY`.
- `manual-update: boolean` (default: `false`) - `manual-update: boolean` (default: `false`)
For performance critical scenarios (having a large dataset) we'd better bypass Vue's reactivity system for `option` prop. By specifying `manual-update` prop with `true` and not providing `option` prop, the dataset won't be watched any more. After doing so, you need to retrieve the component instance with `ref` and manually call `setOption` method to update the chart. For performance critical scenarios (having a large dataset) we'd better bypass Vue's reactivity system for `option` prop. By specifying `manual-update` prop with `true` and not providing `option` prop, the dataset won't be watched any more. After doing so, you need to retrieve the component instance with `ref` and manually call `setOption` method to update the chart.
### Provide / Inject
Vue-ECharts provides provide/inject API for `init-options`, `update-options` and `loading-options` to help configuring contextual options. eg. for `init-options` you can use the provide API like this:
<details open>
<summary>Vue 3</summary>
```js
import { INIT_OPTIONS_KEY } from 'vue-echarts'
import { provide } from 'vue'
// composition API
provide(INIT_OPTIONS_KEY, ...)
// options API
{
provide: {
[INIT_OPTIONS_KEY]: { ... }
}
}
```
</details>
<details>
<summary>Vue 2</summary>
```js
import { INIT_OPTIONS_KEY } from 'vue-echarts'
// in component options
{
provide: {
[INIT_OPTIONS_KEY]: { ... }
}
}
```
</details>
### Methods ### Methods
- `setOption` [](https://echarts.apache.org/en/api.html#echartsInstance.setOption) - `setOption` [](https://echarts.apache.org/en/api.html#echartsInstance.setOption)

View File

@ -78,6 +78,14 @@ new Vue(...)
</details> </details>
为了更小的打包体积,我们建议手动从 ECharts 引入单个图表和组件。请参考所有支持的渲染器/图表/组件。[前往 →](https://github.com/apache/echarts/blob/master/src/echarts.all.ts)
但如果你实在需要全量引入 ECharts 从而无需手动引入模块,只需要在代码中添加:
```js
import "echarts";
```
### CDN & 全局变量 ### CDN & 全局变量
用如下方式在 HTML 中插入 `<script>` 标签: 用如下方式在 HTML 中插入 `<script>` 标签:
@ -139,6 +147,8 @@ Vue.component("v-chart", VueECharts);
初始化附加参数。请参考 `echarts.init``opts` 参数。[前往 →](https://echarts.apache.org/zh/api.html#echarts.init) 初始化附加参数。请参考 `echarts.init``opts` 参数。[前往 →](https://echarts.apache.org/zh/api.html#echarts.init)
Inject 键名:`INIT_OPTIONS_KEY`
- `theme: string | object` - `theme: string | object`
要应用的主题。请参考 `echarts.init``theme` 参数。[前往 →](https://echarts.apache.org/zh/api.html#echarts.init) 要应用的主题。请参考 `echarts.init``theme` 参数。[前往 →](https://echarts.apache.org/zh/api.html#echarts.init)
@ -151,6 +161,8 @@ Vue.component("v-chart", VueECharts);
图表更新的配置项。请参考 `echartsInstance.setOption``opts` 参数。[前往 →](https://echarts.apache.org/zh/api.html#echartsInstance.setOption) 图表更新的配置项。请参考 `echartsInstance.setOption``opts` 参数。[前往 →](https://echarts.apache.org/zh/api.html#echartsInstance.setOption)
Inject 键名:`UPDATE_OPTIONS_KEY`
- `group: string` - `group: string`
图表的分组,用于[联动](https://echarts.apache.org/zh/api.html#echarts.connect)。请参考 `echartsInstance.group`。[前往 →](https://echarts.apache.org/zh/api.html#echartsInstance.group) 图表的分组,用于[联动](https://echarts.apache.org/zh/api.html#echarts.connect)。请参考 `echartsInstance.group`。[前往 →](https://echarts.apache.org/zh/api.html#echartsInstance.group)
@ -167,10 +179,52 @@ Vue.component("v-chart", VueECharts);
加载动画配置项。请参考 `echartsInstance.showLoading``opts` 参数。[前往 →](https://echarts.apache.org/zh/api.html#echartsInstance.showLoading) 加载动画配置项。请参考 `echartsInstance.showLoading``opts` 参数。[前往 →](https://echarts.apache.org/zh/api.html#echartsInstance.showLoading)
Inject 键名:`LOADING_OPTIONS_KEY`
- `manual-update: boolean`(默认值`false` - `manual-update: boolean`(默认值`false`
在性能敏感(数据量很大)的场景下,我们最好对于 `option` prop 绕过 Vue 的响应式系统。当将 `manual-update` prop 指定为 `true` 且不传入 `option` prop 时,数据将不会被监听。然后,需要用 `ref` 获取组件实例以后手动调用 `setOption` 方法来更新图表。 在性能敏感(数据量很大)的场景下,我们最好对于 `option` prop 绕过 Vue 的响应式系统。当将 `manual-update` prop 指定为 `true` 且不传入 `option` prop 时,数据将不会被监听。然后,需要用 `ref` 获取组件实例以后手动调用 `setOption` 方法来更新图表。
### Provide / Inject
Vue-ECharts 为 `init-options``update-options``loading-options` 提供了 provide/inject API以通过上下文配置选项。例如可以通过如下方式来使用 provide API 为 `init-options` 提供上下文配置:
<details open>
<summary>Vue 3</summary>
```js
import { INIT_OPTIONS_KEY } from 'vue-echarts'
import { provide } from 'vue'
// composition API
provide(INIT_OPTIONS_KEY, ...)
// options API
{
provide: {
[INIT_OPTIONS_KEY]: { ... }
}
}
```
</details>
<details>
<summary>Vue 2</summary>
```js
import { INIT_OPTIONS_KEY } from 'vue-echarts'
// in component options
{
provide: {
[INIT_OPTIONS_KEY]: { ... }
}
}
```
</details>
### 方法 ### 方法
- `setOption` [](https://echarts.apache.org/zh/api.html#echartsInstance.setOption) - `setOption` [](https://echarts.apache.org/zh/api.html#echartsInstance.setOption)

View File

@ -18,8 +18,10 @@ import { init as initChart } from "echarts/core";
import { import {
EChartsType, EChartsType,
InitOptions, InitOptions,
InitOptionsInjection,
Option, Option,
UpdateOptions, UpdateOptions,
UpdateOptionsInjection,
Theme Theme
} from "./types"; } from "./types";
import { import {
@ -50,11 +52,14 @@ export default defineComponent({
...loadingProps ...loadingProps
}, },
setup(props, { attrs }) { setup(props, { attrs }) {
const defaultInitOptions = inject(INIT_OPTIONS_KEY, {}) as InitOptions; const defaultInitOptions = inject(
INIT_OPTIONS_KEY,
{}
) as InitOptionsInjection;
const defaultUpdateOptions = inject( const defaultUpdateOptions = inject(
UPDATE_OPTIONS_KEY, UPDATE_OPTIONS_KEY,
{} {}
) as UpdateOptions; ) as UpdateOptionsInjection;
const root = ref<HTMLElement>(); const root = ref<HTMLElement>();
const chart = shallowRef<EChartsType>(); const chart = shallowRef<EChartsType>();
const manualOption = shallowRef<Option>(); const manualOption = shallowRef<Option>();
@ -62,11 +67,11 @@ export default defineComponent({
() => manualOption.value || props.option || Object.create(null) () => manualOption.value || props.option || Object.create(null)
); );
const realInitOptions = computed(() => ({ const realInitOptions = computed(() => ({
...defaultInitOptions, ...unref(defaultInitOptions),
...props.initOptions ...props.initOptions
})); }));
const realUpdateOptions = computed(() => ({ const realUpdateOptions = computed(() => ({
...defaultUpdateOptions, ...unref(defaultUpdateOptions),
...props.updateOptions ...props.updateOptions
})); }));
const { autoresize, manualUpdate, loading, loadingOptions } = toRefs(props); const { autoresize, manualUpdate, loading, loadingOptions } = toRefs(props);

View File

@ -1,4 +1,4 @@
import { inject, computed, Ref, watchEffect } from "vue-demi"; import { inject, unref, computed, Ref, watchEffect } from "vue-demi";
import { EChartsType } from "../types"; import { EChartsType } from "../types";
export const LOADING_OPTIONS_KEY = "ecLoadingOptions"; export const LOADING_OPTIONS_KEY = "ecLoadingOptions";
@ -8,9 +8,11 @@ export function useLoading(
loading: Ref<boolean>, loading: Ref<boolean>,
loadingOptions?: Ref<object | undefined> loadingOptions?: Ref<object | undefined>
): void { ): void {
const defaultLoadingOptions = inject(LOADING_OPTIONS_KEY, {}) as object; const defaultLoadingOptions = inject(LOADING_OPTIONS_KEY, {}) as
| object
| Ref<object>;
const realLoadingOptions = computed(() => ({ const realLoadingOptions = computed(() => ({
...defaultLoadingOptions, ...unref(defaultLoadingOptions),
...loadingOptions?.value ...loadingOptions?.value
})); }));

View File

@ -4,6 +4,9 @@
class="echarts" id="logo" :option="logo" :init-options="initOptions" autoresize /> --> class="echarts" id="logo" :option="logo" :init-options="initOptions" autoresize /> -->
<h1><a href="https://github.com/Justineo/vue-echarts">Vue-ECharts</a></h1> <h1><a href="https://github.com/Justineo/vue-echarts">Vue-ECharts</a></h1>
<p class="desc">ECharts component for Vue.js.</p> <p class="desc">ECharts component for Vue.js.</p>
<p>
<a href="https://github.com/ecomfe/vue-echarts#readme">Docs &rarr;</a>
</p>
<h2 id="bar"> <h2 id="bar">
<a href="#bar" <a href="#bar"

View File

@ -1,9 +1,11 @@
import { init } from "echarts/core"; import { init } from "echarts/core";
import { Ref } from "vue";
type InitType = typeof init; type InitType = typeof init;
export type InitParameters = Parameters<InitType>; export type InitParameters = Parameters<InitType>;
export type Theme = NonNullable<InitParameters[1]>; export type Theme = NonNullable<InitParameters[1]>;
export type InitOptions = NonNullable<InitParameters[2]>; export type InitOptions = NonNullable<InitParameters[2]>;
export type InitOptionsInjection = InitOptions | Ref<InitOptions>;
export type EChartsType = ReturnType<InitType>; export type EChartsType = ReturnType<InitType>;
type SetOptionType = EChartsType["setOption"]; type SetOptionType = EChartsType["setOption"];
@ -18,3 +20,4 @@ export interface UpdateOptions {
replaceMerge?: any; replaceMerge?: any;
transition?: any; transition?: any;
} }
export type UpdateOptionsInjection = UpdateOptions | Ref<UpdateOptions>;