Skip to content

Commit

Permalink
feature: echarts
Browse files Browse the repository at this point in the history
  • Loading branch information
jsxiaosi committed Jan 4, 2022
1 parent 805e579 commit 2577f5b
Show file tree
Hide file tree
Showing 9 changed files with 248 additions and 78 deletions.
146 changes: 73 additions & 73 deletions .eslintrc.js
Original file line number Diff line number Diff line change
@@ -1,74 +1,74 @@
module.exports = {
root: true,
globals: {
defineProps: 'readonly',
defineEmits: 'readonly',
defineExpose: 'readonly',
withDefaults: 'readonly',
},
env: {
browser: true,
commonjs: true,
es6: true,
node: true,
},
extends: [
'plugin:vue/vue3-recommended',
'plugin:@typescript-eslint/recommended',
'prettier',
'plugin:prettier/recommended',
],
parser: 'vue-eslint-parser',
parserOptions: {
ecmaVersion: 2016,
parser: '@typescript-eslint/parser',
// 对Babel解析器的包装使其与 ESLint 兼容。
// parser: 'babel-eslint',
// 代码是 ECMAScript 模块
sourceType: 'module',
},
plugins: ['vue'],
rules: {
// 'prettier/prettier': 'error',
// 是否禁止使用any类型
'@typescript-eslint/no-explicit-any': 'off',
// 是否开启函数必须要指定类型
'@typescript-eslint/explicit-module-boundary-types': 'off',
// 是否禁止使用 @ts-ignore 注解
'@typescript-eslint/ban-ts-comment': 'off',
// 是否禁止空函数
'@typescript-eslint/no-empty-function': 'off',
// 是否禁止使用特定类型
'@typescript-eslint/ban-types': 'off',
// 是否不允许向模板添加多个根节点
'vue/no-multiple-template-root': 'off',
camelcase: 0,
'vue/component-tags-order': [
'error',
{
order: ['template', 'script', 'style'],
},
],
// 是否要求组件名称始终为多字
'vue/multi-word-component-names': [
'error',
{
ignores: ['index'],
},
],
'@typescript-eslint/no-unused-vars': [
'error',
{
argsIgnorePattern: '^_',
varsIgnorePattern: '^_',
},
],
'no-unused-vars': [
'error',
{
argsIgnorePattern: '^_',
varsIgnorePattern: '^_',
},
],
},
}
root: true,
globals: {
defineProps: 'readonly',
defineEmits: 'readonly',
defineExpose: 'readonly',
withDefaults: 'readonly',
},
env: {
browser: true,
commonjs: true,
es6: true,
node: true,
},
extends: [
'plugin:vue/vue3-recommended',
'plugin:@typescript-eslint/recommended',
'prettier',
'plugin:prettier/recommended',
],
parser: 'vue-eslint-parser',
parserOptions: {
ecmaVersion: 2016,
parser: '@typescript-eslint/parser',
// 对Babel解析器的包装使其与 ESLint 兼容。
// parser: 'babel-eslint',
// 代码是 ECMAScript 模块
sourceType: 'module',
},
// plugins: ['vue'],
rules: {
// 'prettier/prettier': 'error',
// 是否禁止使用any类型
'@typescript-eslint/no-explicit-any': 'off',
// 是否开启函数必须要指定类型
'@typescript-eslint/explicit-module-boundary-types': 'off',
// 是否禁止使用 @ts-ignore 注解
'@typescript-eslint/ban-ts-comment': 'off',
// 是否禁止空函数
'@typescript-eslint/no-empty-function': 'off',
// 是否禁止使用特定类型
'@typescript-eslint/ban-types': 'off',
// 是否不允许向模板添加多个根节点
'vue/no-multiple-template-root': 'off',
camelcase: 0,
'vue/component-tags-order': [
'error',
{
order: ['template', 'script', 'style'],
},
],
// 是否要求组件名称始终为多字
'vue/multi-word-component-names': [
'error',
{
ignores: ['index'],
},
],
'@typescript-eslint/no-unused-vars': [
'error',
{
argsIgnorePattern: '^_',
varsIgnorePattern: '^_',
},
],
'no-unused-vars': [
'error',
{
argsIgnorePattern: '^_',
varsIgnorePattern: '^_',
},
],
},
};
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
"dependencies": {
"@element-plus/icons-vue": "^0.2.4",
"axios": "^0.24.0",
"echarts": "^5.2.2",
"element-plus": "^1.3.0-beta.1",
"es6-promise": "^4.2.8",
"lodash-es": "^4.17.21",
Expand Down
57 changes: 57 additions & 0 deletions src/hooks/event/useEventListener.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import type { Ref } from 'vue';
import { ref, watch, unref } from 'vue';
import { useThrottleFn, useDebounceFn } from '@vueuse/core';

export type RemoveEventFn = () => void;
export interface UseEventParams {
el?: Element | Ref<Element | undefined> | Window | any;
name: string;
listener: EventListener;
options?: boolean | AddEventListenerOptions;
autoRemove?: boolean;
isDebounce?: boolean;
wait?: number;
}
export function useEventListener({
el = window,
name,
listener,
options,
autoRemove = true,
isDebounce = true,
wait = 80,
}: UseEventParams): { removeEvent: RemoveEventFn } {
/* eslint-disable-next-line */
let remove: RemoveEventFn = () => {};
const isAddRef = ref(false);

if (el) {
const element = ref(el as Element) as Ref<Element>;
const handler = isDebounce ? useDebounceFn(listener, wait) : useThrottleFn(listener, wait);
const realHandler = wait ? handler : listener;
const removeEventListener = (e: Element) => {
isAddRef.value = true;
e.removeEventListener(name, realHandler, options);
};
const addEventListener = (e: Element) => e.addEventListener(name, realHandler, options);

const removeWatch = watch(
element,
(v, _ov, cleanUp) => {
if (v) {
!unref(isAddRef) && addEventListener(v);
cleanUp(() => {
autoRemove && removeEventListener(v);
});
}
},
{ immediate: true },
);

remove = () => {
removeEventListener(element.value);
removeWatch();
};
}
return { removeEvent: remove };
}
67 changes: 67 additions & 0 deletions src/hooks/web/useECharts.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
import { nextTick, ref, Ref, unref } from 'vue';
import type { EChartsOption } from 'echarts';
import { useDebounceFn, tryOnUnmounted } from '@vueuse/core';
import echarts from '@/utils/plugin/echarts';
import { useEventListener } from '@/hooks/event/useEventListener';

export function useECharts(elRef: Ref<HTMLDivElement>) {
let chartInstance: echarts.ECharts | null = null;
const cacheOptions = ref({}) as Ref<EChartsOption>;
let resizeFn: Fn = resize;
let removeResizeFn: Fn = () => {};
resizeFn = useDebounceFn(resize, 200);

// 创建echarts
function initCharts() {
// 获取ref demo
const el = unref(elRef);
if (!el || !unref(el)) {
return;
}
chartInstance = echarts.init(el, 'default');

// 监听window宽度变化重新渲染echarts
const { removeEvent } = useEventListener({
el: window,
name: 'resize',
listener: resizeFn,
});
removeResizeFn = removeEvent;
}

// 配置echarts属性,如果chartInstance为空就创建echarts实例;
function setOptions(options: EChartsOption, clear = true) {
cacheOptions.value = options;
nextTick(() => {
// 判断是否创建echarts实例
if (!chartInstance) {
initCharts();
if (!chartInstance) return;
}

// 清空当前实例,会移除实例中所有的组件和图表
clear && chartInstance?.clear();

chartInstance?.setOption(unref(cacheOptions));
});
}

// 改变图表大小
function resize() {
console.log('每次都执行?');
chartInstance?.resize();
}

tryOnUnmounted(() => {
if (!chartInstance) return;
removeResizeFn();
chartInstance.dispose();
chartInstance = null;
});

return {
echarts,
setOptions,
resize,
};
}
2 changes: 1 addition & 1 deletion src/layouts/components/Sidebar/Item.vue
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<template>
<SvgIcon :class-name="className" :name="icon"></SvgIcon>
<SvgIcon :class-name="className" :name="icon" />
<span v-if="title">{{ t(title) }}</span>
</template>

Expand Down
2 changes: 1 addition & 1 deletion src/styles/sidebar.scss
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
box-sizing: border-box;
flex: 1;
width: calc(100vw - #{$sideBarWidth});
width: 100%;
// width: 100%;
min-height: 100%;
padding-top: #{$navBarHeight};
// margin-left: #{$sideBarWidth};
Expand Down
9 changes: 9 additions & 0 deletions src/utils/plugin/echarts.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import * as echarts from 'echarts/core';
import { GridComponent } from 'echarts/components';
import { LineChart } from 'echarts/charts';
import { UniversalTransition } from 'echarts/features';
import { CanvasRenderer } from 'echarts/renderers';

echarts.use([GridComponent, LineChart, CanvasRenderer, UniversalTransition]);

export default echarts;
38 changes: 35 additions & 3 deletions src/views/index/index.vue
Original file line number Diff line number Diff line change
@@ -1,14 +1,46 @@
<template>
<div class="page-container">
<div class=""> </div>
<div ref="chartRef" class="line"> </div>
</div>
</template>

<script setup>
<script setup lang="ts">
// 直接导入组件
// import HelloWorld from '@/components/HelloWorld.vue';
// import { useContext } from 'vue'
// console.log(useContext())
import { ref, Ref, onMounted } from 'vue';
import { useECharts } from '@/hooks/web/useECharts';
const chartRef = ref<HTMLDivElement | null>(null);
const { setOptions } = useECharts(chartRef as Ref<HTMLDivElement>);
onMounted(() => {
setOptions({
xAxis: {
type: 'category',
boundaryGap: false,
data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'],
},
yAxis: {
type: 'value',
},
series: [
{
data: [820, 932, 901, 934, 1290, 1330, 1320],
type: 'line',
areaStyle: {},
},
],
});
});
// console.log(chartRef);
</script>

<style lang="scss" scoped></style>
<style lang="scss" scoped>
.line {
width: 100%;
height: 100%;
}
</style>
4 changes: 4 additions & 0 deletions types/index.d.ts
Original file line number Diff line number Diff line change
@@ -1 +1,5 @@
declare type RefType<T> = T | null;

declare interface Fn<T = any, R = T> {
(...arg: T[]): R;
}

0 comments on commit 2577f5b

Please sign in to comment.