ソースを参照

feat: 新增基础事件功能

奔跑的面条 3 年 前
コミット
3308a7abbb

+ 34 - 5
src/hooks/useLifeHandler.hook.ts

@@ -1,4 +1,4 @@
-import { CreateComponentType, EventLife } from '@/packages/index.d'
+import { CreateComponentType, CreateComponentGroupType, EventLife, BaseEvent } from '@/packages/index.d'
 import * as echarts from 'echarts'
 
 // 所有图表组件集合对象
@@ -7,9 +7,20 @@ const components: { [K in string]?: any } = {}
 // 项目提供的npm 包变量
 export const npmPkgs = { echarts }
 
-export const useLifeHandler = (chartConfig: CreateComponentType) => {
-  const events = chartConfig.events.advancedEvents || {}
+// 组件事件处理 hook
+export const useLifeHandler = (chartConfig: CreateComponentType | CreateComponentGroupType) => {
+  // 处理基础事件
+  const baseEvent: { [key: string]: any } = {}
+  for (const key in chartConfig.events.baseEvent) {
+    const fnStr: string | undefined = (chartConfig.events.baseEvent as any)[key]
+    // 动态绑定基础事件
+    if (fnStr) {
+      baseEvent[key] = generateBaseFunc(fnStr)
+    }
+  }
+
   // 生成生命周期事件
+  const events = chartConfig.events.advancedEvents || {}
   const lifeEvents = {
     [EventLife.VNODE_BEFORE_MOUNT](e: any) {
       // 存储组件
@@ -22,11 +33,29 @@ export const useLifeHandler = (chartConfig: CreateComponentType) => {
       generateFunc(fnStr, e)
     }
   }
-  return lifeEvents
+  return { ...baseEvent, ...lifeEvents }
+}
+
+/**
+ * 生成基础函数
+ * @param fnStr 用户方法体代码
+ * @param event 鼠标事件
+ */
+ export function generateBaseFunc(fnStr: string) {
+  try {
+    return new Function(`
+      return (
+        async function(mouseEvent){
+          ${fnStr}
+        }
+      )`)()
+  } catch (error) {
+    console.error(error)
+  }
 }
 
 /**
- *
+ * 生成高级函数
  * @param fnStr 用户方法体代码
  * @param e 执行生命周期的动态组件实例
  */

+ 5 - 5
src/packages/index.d.ts

@@ -90,16 +90,16 @@ export const BlendModeEnumList = [
   { label: '亮度', value: 'luminosity' }
 ]
 
-// 基础事件类型
+// 基础事件类型(vue不加 on)
 export enum BaseEvent {
   // 点击
-  ON_CLICK = 'onClick',
+  ON_CLICK = 'click',
   // 双击
-  ON_DBL_CLICK = 'onDblClick',
+  ON_DBL_CLICK = 'dblclick',
   // 移入
-  ON_MOUSE_ENTER = 'onMouseenter',
+  ON_MOUSE_ENTER = 'mouseenter',
   // 移出
-  ON_MOUSE_LEAVE = 'onMouseleave',
+  ON_MOUSE_LEAVE = 'mouseleave',
 }
 
 // vue3 生命周期事件

+ 2 - 2
src/views/chart/ContentConfigurations/components/ChartEvent/components/ChartEventAdvancedHandle/index.vue

@@ -40,7 +40,7 @@
           <n-tabs v-model:value="editTab" type="card" tab-style="min-width: 100px;">
             <!-- 提示 -->
             <template #suffix>
-              <n-text class="tab-tip" type="warning">tips: {{ EventLifeTip[editTab] }}</n-text>
+              <n-text class="tab-tip" type="warning">提示: {{ EventLifeTip[editTab] }}</n-text>
             </template>
             <n-tab-pane
               v-for="(eventName, index) in EventLife"
@@ -140,7 +140,7 @@
               <template #icon>
                 <n-icon :component="DocumentTextIcon" />
               </template>
-              提示
+              说明
             </n-tag>
             <n-text class="go-ml-2" depth="2">通过提供的参数可为图表增加定制化的tooltip、交互事件等等</n-text>
           </div>

+ 11 - 10
src/views/chart/ContentConfigurations/components/ChartEvent/components/ChartEventBaseHandle/index.vue

@@ -39,6 +39,10 @@
       <n-layout has-sider sider-placement="right">
         <n-layout style="height: 580px; padding-right: 20px">
           <n-tabs v-model:value="editTab" type="card" tab-style="min-width: 100px;">
+            <!-- 提示 -->
+            <template #suffix>
+              <n-text class="tab-tip" type="warning">提示: ECharts 组件会拦截鼠标事件</n-text>
+            </template>
             <n-tab-pane
               v-for="(eventName, index) in BaseEvent"
               :key="index"
@@ -48,7 +52,7 @@
               <!-- 函数名称 -->
               <p class="go-pl-3">
                 <span class="func-keyword">async function &nbsp;&nbsp;</span>
-                <span class="func-keyNameWord">{{ eventName }}(mouseEvent, components)&nbsp;&nbsp;{</span>
+                <span class="func-keyNameWord">{{ eventName }}(mouseEvent)&nbsp;&nbsp;{</span>
               </p>
               <!-- 编辑主体 -->
               <monaco-editor v-model:modelValue="baseEvent[eventName]" height="480px" language="javascript" />
@@ -88,10 +92,7 @@
               <n-scrollbar trigger="none" style="max-height: 505px">
                 <n-collapse class="go-px-3" arrow-placement="right" :default-expanded-names="[1, 2]">
                   <n-collapse-item title="mouseEvent" :name="1">
-                    <n-text depth="3">事件对象</n-text>
-                  </n-collapse-item>
-                  <n-collapse-item title="components" :name="2">
-                    <n-text depth="3">当前图表组件实例</n-text>
+                    <n-text depth="3">鼠标事件对象</n-text>
                   </n-collapse-item>
                 </n-collapse>
               </n-scrollbar>
@@ -107,7 +108,7 @@
               <template #icon>
                 <n-icon :component="DocumentTextIcon" />
               </template>
-              提示
+              说明
             </n-tag>
             <n-text class="go-ml-2" depth="2">编写方式同正常 JavaScript 写法</n-text>
           </div>
@@ -188,10 +189,10 @@ const saveEvents = () => {
   if (Object.values(baseEvent.value).join('').trim() === '') {
     // 清空事件
     targetData.value.events.baseEvent = {
-      onClick: undefined,
-      onDblClick: undefined,
-      onMouseenter: undefined,
-      onMouseleave: undefined,
+      [BaseEvent.ON_CLICK]: undefined,
+      [BaseEvent.ON_DBL_CLICK]: undefined,
+      [BaseEvent.ON_MOUSE_ENTER]: undefined,
+      [BaseEvent.ON_MOUSE_LEAVE]: undefined
     }
   } else {
     targetData.value.events.baseEvent = { ...baseEvent.value }

+ 2 - 0
src/views/preview/components/PreviewRenderGroup/index.vue

@@ -14,6 +14,7 @@
   >
     <component
       :is="item.chartConfig.chartKey"
+      :id="item.id"
       :chartConfig="item"
       :themeSetting="themeSetting"
       :themeColor="themeColor"
@@ -29,6 +30,7 @@ import { CreateComponentGroupType } from '@/packages/index.d'
 import { animationsClass, getFilterStyle, getTransformStyle, getBlendModeStyle } from '@/utils'
 import { getSizeStyle, getComponentAttrStyle, getStatusStyle } from '../../utils'
 import { useLifeHandler } from '@/hooks'
+
 const props = defineProps({
   groupData: {
     type: Object as PropType<CreateComponentGroupType>,

+ 2 - 0
src/views/preview/components/PreviewRenderList/index.vue

@@ -25,6 +25,7 @@
     <component
       v-else
       :is="item.chartConfig.chartKey"
+      :id="item.id"
       :chartConfig="item"
       :themeSetting="themeSetting"
       :themeColor="themeColor"
@@ -43,6 +44,7 @@ import { chartColors } from '@/settings/chartThemes/index'
 import { animationsClass, getFilterStyle, getTransformStyle, getBlendModeStyle } from '@/utils'
 import { getSizeStyle, getComponentAttrStyle, getStatusStyle } from '../../utils'
 import { useLifeHandler } from '@/hooks'
+
 const props = defineProps({
   localStorageInfo: {
     type: Object as PropType<ChartEditStorageType>,