st-comp 0.0.45 → 0.0.47
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/bundle.js +25409 -27447
- package/lib/bundle.umd.cjs +61 -65
- package/lib/style.css +1 -1
- package/package.json +3 -3
- package/packages/KlineNew/components/KlineSlide/index.vue +19 -43
- package/packages/KlineNew/components/KlineSub/index.vue +143 -154
- package/packages/KlineNew/components/{MainTips → KlineTips}/index.vue +9 -9
- package/packages/KlineNew/components/KlineUtils/index.vue +304 -0
- package/packages/KlineNew/index.ts +8 -2
- package/src/pages/KlineNew/components/KlineAction/components/ContextMenu/index.vue +91 -0
- package/src/pages/KlineNew/components/KlineAction/components/YearChart/index.vue +532 -0
- package/src/pages/KlineNew/components/KlineAction/images/pen.png +0 -0
- package/src/pages/KlineNew/components/KlineAction/index.vue +716 -0
- package/src/pages/KlineNew/components/KlineAction/mockApi/index.js +13 -0
- package/src/pages/KlineNew/components/KlineAction/utils.js +571 -0
- package/src/pages/KlineNew/components/KlineBasic/index.vue +336 -0
- package/src/pages/KlineNew/components/KlineBasic/utils.js +33 -0
- package/src/pages/KlineNew/components/KlineSlide/index.vue +446 -0
- package/src/pages/KlineNew/components/KlineSlide/utils.js +78 -0
- package/src/pages/KlineNew/index.vue +60 -32
- package/vitePlugins/createExportFile.ts +2 -1
- package/packages/KlineNew/index.vue +0 -363
- package/packages/KlineNew/klineConfig.ts +0 -44
- package/packages/KlineNew/option.ts +0 -111
- package/packages/KlineNew/utils.ts +0 -156
- package/vite.config.ts +0 -61
|
@@ -0,0 +1,304 @@
|
|
|
1
|
+
<template></template>
|
|
2
|
+
|
|
3
|
+
<script setup lang="ts">
|
|
4
|
+
import * as talib from 'talib.js'
|
|
5
|
+
|
|
6
|
+
let isInit = false // 是否初始化
|
|
7
|
+
let loading = true // 初始化loading
|
|
8
|
+
let requestPromise: any[] = [] // 用于存储loading中的计算请求
|
|
9
|
+
|
|
10
|
+
// 导出数据长度处理
|
|
11
|
+
const sliceData = (data: any[], length: number) => {
|
|
12
|
+
return data.length > length ? data.slice(data.length - length) : data
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
defineExpose({
|
|
16
|
+
// 注册计算指标线方法
|
|
17
|
+
initTalib: async () => {
|
|
18
|
+
if (!isInit) {
|
|
19
|
+
// 未初始化
|
|
20
|
+
isInit = true
|
|
21
|
+
await talib.init('./talib.wasm')
|
|
22
|
+
loading = false
|
|
23
|
+
requestPromise.forEach(resolve => {
|
|
24
|
+
resolve()
|
|
25
|
+
})
|
|
26
|
+
} else if(loading) {
|
|
27
|
+
// 正在初始化
|
|
28
|
+
return new Promise((resolve) => {
|
|
29
|
+
requestPromise.push(resolve)
|
|
30
|
+
})
|
|
31
|
+
}
|
|
32
|
+
},
|
|
33
|
+
// 键盘事件处理
|
|
34
|
+
handleKeyDown: (e: any, params: any) => {
|
|
35
|
+
let { startValue, endValue, maxIndex } = params
|
|
36
|
+
if (e.code === 'ArrowLeft') {
|
|
37
|
+
// 左按键
|
|
38
|
+
if (startValue === 0) {
|
|
39
|
+
return
|
|
40
|
+
}
|
|
41
|
+
startValue = startValue - 1
|
|
42
|
+
endValue = endValue - 1
|
|
43
|
+
} else if (e.code === 'ArrowRight') {
|
|
44
|
+
// 右按键
|
|
45
|
+
if (endValue === maxIndex) {
|
|
46
|
+
return
|
|
47
|
+
}
|
|
48
|
+
startValue = startValue + 1
|
|
49
|
+
endValue = endValue + 1
|
|
50
|
+
} else if (e.code === 'ArrowUp') {
|
|
51
|
+
// 上按键-放大 最少保持5条数据
|
|
52
|
+
if(endValue - startValue < 5) {
|
|
53
|
+
return
|
|
54
|
+
}
|
|
55
|
+
const diff = Math.floor((endValue - startValue) / 2) + 1
|
|
56
|
+
startValue = startValue + diff
|
|
57
|
+
if (endValue - startValue < 5) {
|
|
58
|
+
startValue = endValue - 4
|
|
59
|
+
}
|
|
60
|
+
} else if (e.code === 'ArrowDown') {
|
|
61
|
+
// 下按键-缩小
|
|
62
|
+
const diff = Math.min(500, (endValue - startValue))
|
|
63
|
+
startValue = startValue - diff - 1
|
|
64
|
+
}
|
|
65
|
+
return({
|
|
66
|
+
startValue,
|
|
67
|
+
endValue
|
|
68
|
+
})
|
|
69
|
+
},
|
|
70
|
+
// 根据时间解析dataZoom
|
|
71
|
+
getDataZoomInfoByTime: (params: any) => {
|
|
72
|
+
const { showStartTime, showEndTime, xAxisData, maxShowDays } = params
|
|
73
|
+
let startValue = -1
|
|
74
|
+
let endValue = -1
|
|
75
|
+
let dayPerTime: any = {}
|
|
76
|
+
xAxisData.forEach((time: any, index: number) => {
|
|
77
|
+
const date = time.split(' ')[0]
|
|
78
|
+
dayPerTime[date] = dayPerTime[date] || 0
|
|
79
|
+
dayPerTime[date] += 1
|
|
80
|
+
if (new Date(time) >= new Date(showStartTime) && startValue === -1) {
|
|
81
|
+
startValue = index
|
|
82
|
+
}
|
|
83
|
+
if (new Date(time) <= new Date(showEndTime)) {
|
|
84
|
+
endValue = index
|
|
85
|
+
}
|
|
86
|
+
})
|
|
87
|
+
return {
|
|
88
|
+
startValue,
|
|
89
|
+
endValue,
|
|
90
|
+
maxValueSpan: Math.max(...Object.values(dayPerTime)) * maxShowDays,
|
|
91
|
+
}
|
|
92
|
+
},
|
|
93
|
+
// 计算绘图数据(拖动轴使用)
|
|
94
|
+
formatDataBySlide: (formatDataParams: any) => {
|
|
95
|
+
const { originDrawData, addData, startTime, endTime, mainIndicator, mainIndicatorList, subIndicator, subIndicatorList, config, timeRange } = formatDataParams
|
|
96
|
+
let drawData: any = {}
|
|
97
|
+
const { loadAddCount, preLoadCount } = config
|
|
98
|
+
|
|
99
|
+
const time: any[] = [] // 新增数据全部时间数据,用于计算指标线
|
|
100
|
+
const open: any[] = [] // 新增数据全部开盘价,用于指标线计算
|
|
101
|
+
const close: any[] = [] // 新增数据全部收盘价,用于指标线计算
|
|
102
|
+
const high: any[] = [] // 新增数据全部最高价,用于指标线计算
|
|
103
|
+
const low: any[] = [] // 新增数据全部最低价,用于指标线计算
|
|
104
|
+
let xAxisData: any[] = [] // 用于绘图的x轴时间数据
|
|
105
|
+
let candlestickData: any[] = [] // 用于绘图的k线图数据
|
|
106
|
+
|
|
107
|
+
const originData = addData.filter((item: any, index: number) => {
|
|
108
|
+
// 赋值
|
|
109
|
+
time.push(item[0])
|
|
110
|
+
open.push(item[1])
|
|
111
|
+
close.push(item[4])
|
|
112
|
+
high.push(item[2])
|
|
113
|
+
low.push(item[3])
|
|
114
|
+
xAxisData.push(item[0])
|
|
115
|
+
candlestickData.push([ item[1], item[4], item[3], item[2], index === 0 ? 0 : addData[index - 1][4] ])
|
|
116
|
+
// 取范围中的数据
|
|
117
|
+
if (startTime && endTime) {
|
|
118
|
+
return new Date(startTime) <= new Date(item[0]) && new Date(item[0]) <= new Date(endTime)
|
|
119
|
+
} else if (endTime) {
|
|
120
|
+
return index >= addData.length - loadAddCount && new Date(timeRange[0]) <= new Date(item[0]) && new Date(item[0]) <= new Date(timeRange[1])
|
|
121
|
+
} else if (startTime) {
|
|
122
|
+
return index >= preLoadCount && new Date(timeRange[0]) <= new Date(item[0]) && new Date(item[0]) <= new Date(timeRange[1])
|
|
123
|
+
}
|
|
124
|
+
return false
|
|
125
|
+
})
|
|
126
|
+
xAxisData = sliceData(xAxisData, originData.length)
|
|
127
|
+
candlestickData = sliceData(candlestickData, originData.length)
|
|
128
|
+
// 指标线相关计算
|
|
129
|
+
const indicatorFormatData = { time, open, close, high, low, originData: addData }
|
|
130
|
+
const mainIndicatorConfig = mainIndicatorList.find((item: any) => item.value === mainIndicator).config
|
|
131
|
+
const mainIndicatorData = mainIndicatorConfig.map((item: any) => ({
|
|
132
|
+
...item,
|
|
133
|
+
data: sliceData(item.calculationFn ? item.calculationFn(talib, indicatorFormatData, {
|
|
134
|
+
time: [], open: [], close: [], high: [], low: [], originData: []
|
|
135
|
+
}) : [], xAxisData.length),
|
|
136
|
+
}))
|
|
137
|
+
const subIndicatorConfig = subIndicatorList.find((item: any) => item.value === subIndicator).config
|
|
138
|
+
const subIndicatorData = subIndicatorConfig.reduce((res: any[], item: any) => {
|
|
139
|
+
if (item.source === 'calculation') {
|
|
140
|
+
return [
|
|
141
|
+
...res,
|
|
142
|
+
{
|
|
143
|
+
...item,
|
|
144
|
+
data: sliceData(item.calculationFn ? item.calculationFn(talib, indicatorFormatData) : [], xAxisData.length)
|
|
145
|
+
}
|
|
146
|
+
]
|
|
147
|
+
}
|
|
148
|
+
return res
|
|
149
|
+
}, [])
|
|
150
|
+
// 根据不同情况处理数据
|
|
151
|
+
if (startTime && endTime) {
|
|
152
|
+
// 重新搜索
|
|
153
|
+
drawData = {
|
|
154
|
+
originData, // 原数据
|
|
155
|
+
xAxisData, // 时间数据
|
|
156
|
+
candlestickData, // k线数据
|
|
157
|
+
mainIndicatorData, // 主图指标线数据
|
|
158
|
+
subIndicatorData, // 副图数据
|
|
159
|
+
}
|
|
160
|
+
} else if (endTime) {
|
|
161
|
+
// 加载历史数据
|
|
162
|
+
drawData = {
|
|
163
|
+
originData: [...originData, ...originDrawData.originData], // 原数据
|
|
164
|
+
xAxisData: [...xAxisData, ...originDrawData.xAxisData], // 时间数据
|
|
165
|
+
candlestickData: [...candlestickData, ...originDrawData.candlestickData], // k线数据
|
|
166
|
+
mainIndicatorData: originDrawData.mainIndicatorData.map((item: any, index: number) => {
|
|
167
|
+
return {
|
|
168
|
+
...item,
|
|
169
|
+
data: [...mainIndicatorData[index].data, ...item.data],
|
|
170
|
+
}
|
|
171
|
+
}), // 主图指标线数据
|
|
172
|
+
subIndicatorData: originDrawData.subIndicatorData.map((item: any, index: number) => {
|
|
173
|
+
return {
|
|
174
|
+
...item,
|
|
175
|
+
data: [...subIndicatorData[index].data, ...item.data],
|
|
176
|
+
}
|
|
177
|
+
}), // 副图数据
|
|
178
|
+
}
|
|
179
|
+
} else if (startTime) {
|
|
180
|
+
// 加载新数据
|
|
181
|
+
drawData = {
|
|
182
|
+
originData: [...originDrawData.originData, ...originData], // 原数据
|
|
183
|
+
xAxisData: [...originDrawData.xAxisData, ...xAxisData], // 时间数据
|
|
184
|
+
candlestickData: [...originDrawData.candlestickData, ...candlestickData], // k线数据
|
|
185
|
+
mainIndicatorData: originDrawData.mainIndicatorData.map((item: any, index: number) => {
|
|
186
|
+
return {
|
|
187
|
+
...item,
|
|
188
|
+
data: [...item.data, ...mainIndicatorData[index].data],
|
|
189
|
+
}
|
|
190
|
+
}), // 主图指标线数据
|
|
191
|
+
subIndicatorData: originDrawData.subIndicatorData.map((item: any, index: number) => {
|
|
192
|
+
return {
|
|
193
|
+
...item,
|
|
194
|
+
data: [...item.data, ...subIndicatorData[index].data],
|
|
195
|
+
}
|
|
196
|
+
}), // 副图数据
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
// 添加一些字段,用于方便使用
|
|
200
|
+
drawData.length = drawData.xAxisData.length
|
|
201
|
+
drawData.startTime = drawData.xAxisData[0]
|
|
202
|
+
drawData.endTime = drawData.xAxisData[drawData.length - 1]
|
|
203
|
+
return drawData
|
|
204
|
+
},
|
|
205
|
+
// 计算绘图数据(根据长度使用)
|
|
206
|
+
formatDataByCount: (formatDataParams: any) => {
|
|
207
|
+
const { originDrawData, addData, mainIndicator, mainIndicatorList, subIndicator, subIndicatorList, config } = formatDataParams
|
|
208
|
+
let drawData: any = {}
|
|
209
|
+
const { addCount, preLoadCount } = config
|
|
210
|
+
|
|
211
|
+
const time: any[] = [] // 新增数据全部时间数据,用于计算指标线
|
|
212
|
+
const open: any[] = [] // 新增数据全部开盘价,用于指标线计算
|
|
213
|
+
const close: any[] = [] // 新增数据全部收盘价,用于指标线计算
|
|
214
|
+
const high: any[] = [] // 新增数据全部最高价,用于指标线计算
|
|
215
|
+
const low: any[] = [] // 新增数据全部最低价,用于指标线计算
|
|
216
|
+
let xAxisData: any[] = [] // 用于绘图的x轴时间数据
|
|
217
|
+
let candlestickData: any[] = [] // 用于绘图的k线图数据
|
|
218
|
+
|
|
219
|
+
const originData = addData.filter((item: any, index: number) => {
|
|
220
|
+
// 赋值
|
|
221
|
+
time.push(item[0])
|
|
222
|
+
open.push(item[1])
|
|
223
|
+
close.push(item[4])
|
|
224
|
+
high.push(item[2])
|
|
225
|
+
low.push(item[3])
|
|
226
|
+
xAxisData.push(item[0])
|
|
227
|
+
candlestickData.push([ item[1], item[4], item[3], item[2], index === 0 ? 0 : addData[index - 1][4] ])
|
|
228
|
+
if (addData.length >= addCount + preLoadCount - 1) {
|
|
229
|
+
// 还有未加载数据
|
|
230
|
+
return index >= preLoadCount
|
|
231
|
+
} else {
|
|
232
|
+
// 全部剩余数据
|
|
233
|
+
return true
|
|
234
|
+
}
|
|
235
|
+
})
|
|
236
|
+
xAxisData = sliceData(xAxisData, originData.length)
|
|
237
|
+
candlestickData = sliceData(candlestickData, originData.length)
|
|
238
|
+
// 指标线相关计算
|
|
239
|
+
const indicatorFormatData = { time, open, close, high, low, originData: addData }
|
|
240
|
+
const mainIndicatorConfig = mainIndicatorList.find((item: any) => item.value === mainIndicator).config
|
|
241
|
+
const mainIndicatorData = mainIndicatorConfig.map((item: any) => ({
|
|
242
|
+
...item,
|
|
243
|
+
data: sliceData(item.calculationFn ? item.calculationFn(talib, indicatorFormatData, {
|
|
244
|
+
time: [], open: [], close: [], high: [], low: [], originData: []
|
|
245
|
+
}) : [], xAxisData.length),
|
|
246
|
+
}))
|
|
247
|
+
let subIndicatorData = []
|
|
248
|
+
if (subIndicator && subIndicatorList) {
|
|
249
|
+
const subIndicatorConfig = subIndicatorList.find((item: any) => item.value === subIndicator).config
|
|
250
|
+
subIndicatorData = subIndicatorConfig.reduce((res: any[], item: any) => {
|
|
251
|
+
if (item.source === 'calculation') {
|
|
252
|
+
return [
|
|
253
|
+
...res,
|
|
254
|
+
{
|
|
255
|
+
...item,
|
|
256
|
+
data: sliceData(item.calculationFn ? item.calculationFn(talib, indicatorFormatData) : [], xAxisData.length)
|
|
257
|
+
}
|
|
258
|
+
]
|
|
259
|
+
}
|
|
260
|
+
return res
|
|
261
|
+
}, [])
|
|
262
|
+
}
|
|
263
|
+
// 根据不同情况处理数据
|
|
264
|
+
if (originDrawData.length) {
|
|
265
|
+
// 加载历史数据
|
|
266
|
+
drawData = {
|
|
267
|
+
originData: [...originData, ...originDrawData.originData], // 原数据
|
|
268
|
+
xAxisData: [...xAxisData, ...originDrawData.xAxisData], // 时间数据
|
|
269
|
+
candlestickData: [...candlestickData, ...originDrawData.candlestickData], // k线数据
|
|
270
|
+
mainIndicatorData: originDrawData.mainIndicatorData.map((item: any, index: number) => {
|
|
271
|
+
return {
|
|
272
|
+
...item,
|
|
273
|
+
data: [...mainIndicatorData[index].data, ...item.data],
|
|
274
|
+
}
|
|
275
|
+
}), // 主图指标线数据
|
|
276
|
+
subIndicatorData: originDrawData.subIndicatorData.map((item: any, index: number) => {
|
|
277
|
+
return {
|
|
278
|
+
...item,
|
|
279
|
+
data: [...subIndicatorData[index].data, ...item.data],
|
|
280
|
+
}
|
|
281
|
+
}), // 副图数据
|
|
282
|
+
}
|
|
283
|
+
} else {
|
|
284
|
+
// 首屏数据
|
|
285
|
+
drawData = {
|
|
286
|
+
originData, // 原数据
|
|
287
|
+
xAxisData, // 时间数据
|
|
288
|
+
candlestickData, // k线数据
|
|
289
|
+
mainIndicatorData, // 主图指标线数据
|
|
290
|
+
subIndicatorData, // 副图数据
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
// 添加一些字段,用于方便使用
|
|
294
|
+
drawData.length = drawData.xAxisData.length
|
|
295
|
+
drawData.startTime = drawData.xAxisData[0]
|
|
296
|
+
drawData.endTime = drawData.xAxisData[drawData.length - 1]
|
|
297
|
+
return drawData
|
|
298
|
+
},
|
|
299
|
+
fn: () => {},
|
|
300
|
+
})
|
|
301
|
+
</script>
|
|
302
|
+
|
|
303
|
+
<style lang="scss" scoped>
|
|
304
|
+
</style>
|
|
@@ -1,8 +1,14 @@
|
|
|
1
1
|
import { App } from "vue";
|
|
2
|
-
import
|
|
2
|
+
import KlineUtils from "./components/KlineUtils/index.vue"
|
|
3
|
+
import KlineTips from "./components/KlineTips/index.vue"
|
|
4
|
+
import KlineSub from "./components/KlineSub/index.vue"
|
|
5
|
+
import KlineSlide from "./components/KlineSlide/index.vue"
|
|
3
6
|
|
|
4
7
|
export default {
|
|
5
8
|
install(app: App) {
|
|
6
|
-
app.component("st-
|
|
9
|
+
app.component("st-klineUtils", KlineUtils);
|
|
10
|
+
app.component("st-klineSub", KlineSub);
|
|
11
|
+
app.component("st-klineTips", KlineTips);
|
|
12
|
+
app.component("st-klineSlide", KlineSlide);
|
|
7
13
|
},
|
|
8
14
|
}
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
<!-- 提供右键菜单的父级DOM组件 -->
|
|
2
|
+
<template>
|
|
3
|
+
<div ref="contextmenuRef" class="contextmenu" @contextmenu="handleContextMenu" @mouseleave="handleMouseLeave">
|
|
4
|
+
<!-- 主DOM插槽 -->
|
|
5
|
+
<slot />
|
|
6
|
+
<!-- 自定义菜单插槽 -->
|
|
7
|
+
<div ref="menuRef" v-if="menuStyle.display !== 'none'" class="contextmenu-popover" :style="menuStyle">
|
|
8
|
+
<slot name="popover" />
|
|
9
|
+
</div>
|
|
10
|
+
</div>
|
|
11
|
+
</template>
|
|
12
|
+
|
|
13
|
+
<script setup>
|
|
14
|
+
import { ref, nextTick } from "vue";
|
|
15
|
+
// 自定义事件函数: 关闭悬浮菜单回调
|
|
16
|
+
const emits = defineEmits(["closeMenuCallBack"]);
|
|
17
|
+
// 组件Ref
|
|
18
|
+
const contextmenuRef = ref();
|
|
19
|
+
// 悬浮菜单Ref
|
|
20
|
+
const menuRef = ref();
|
|
21
|
+
// 悬浮菜单样式
|
|
22
|
+
const menuStyle = ref({
|
|
23
|
+
display: "none", // 是否展示
|
|
24
|
+
top: "0px", // 位置:上边距
|
|
25
|
+
left: "0px", // 位置:左边距
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
// 打开悬浮菜单
|
|
29
|
+
const handleContextMenu = (el) => {
|
|
30
|
+
// 1.阻止默认事件 + 冒泡
|
|
31
|
+
el.preventDefault();
|
|
32
|
+
el.stopPropagation();
|
|
33
|
+
// @todo: 解决: 右键菜单项,重复触发本函数导致菜单位置异常问题
|
|
34
|
+
if (menuStyle.value.display === "block") {
|
|
35
|
+
// 判断鼠标位置是否在悬浮菜单内,如果是,则return,否则继续执行在新的位置打开
|
|
36
|
+
const { offsetX, offsetY } = el; // 鼠标
|
|
37
|
+
const { offsetWidth, offsetHeight } = menuRef.value;
|
|
38
|
+
if (offsetX <= offsetWidth && offsetY <= offsetHeight) {
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
contextmenuRef.value.click();
|
|
43
|
+
// 2.初始化展示悬浮菜单位置
|
|
44
|
+
menuStyle.value = {
|
|
45
|
+
display: "block",
|
|
46
|
+
top: `${el.offsetY}px`,
|
|
47
|
+
left: `${el.offsetX}px`,
|
|
48
|
+
};
|
|
49
|
+
// 3.计算悬浮菜单是否超出范围
|
|
50
|
+
nextTick(() => {
|
|
51
|
+
const { bottom, height, right, width } = menuRef.value.getBoundingClientRect();
|
|
52
|
+
if (bottom > window.innerHeight) {
|
|
53
|
+
// 高度超出
|
|
54
|
+
menuStyle.value = {
|
|
55
|
+
display: "block",
|
|
56
|
+
top: `${el.offsetY - height}px`,
|
|
57
|
+
left: `${el.offsetX}px`,
|
|
58
|
+
};
|
|
59
|
+
} else if (right > window.innerWidth) {
|
|
60
|
+
// 宽度超出
|
|
61
|
+
menuStyle.value = {
|
|
62
|
+
display: "block",
|
|
63
|
+
top: `${el.offsetY}px`,
|
|
64
|
+
left: `${el.offsetX - width}px`,
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
});
|
|
68
|
+
// 4.监听点击事件 -> 调用关闭悬浮菜单事件
|
|
69
|
+
document.addEventListener("click", handleMouseLeave);
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
// 关闭悬浮菜单
|
|
73
|
+
const handleMouseLeave = () => {
|
|
74
|
+
menuStyle.value.display = "none";
|
|
75
|
+
emits("closeMenuCallBack");
|
|
76
|
+
document.removeEventListener("click", handleMouseLeave);
|
|
77
|
+
};
|
|
78
|
+
</script>
|
|
79
|
+
|
|
80
|
+
<style lang="scss" scoped>
|
|
81
|
+
.contextmenu {
|
|
82
|
+
position: relative;
|
|
83
|
+
width: 100%;
|
|
84
|
+
height: 100%;
|
|
85
|
+
&-popover {
|
|
86
|
+
position: absolute;
|
|
87
|
+
z-index: 10;
|
|
88
|
+
display: none;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
</style>
|