Compare commits
2 Commits
9e07cf0214
...
2e06e013b1
Author | SHA1 | Date |
---|---|---|
z9130 | 2e06e013b1 | |
z9130 | 221dde6793 |
|
@ -1,10 +1,12 @@
|
|||
<script setup>
|
||||
import {
|
||||
defineAsyncComponent,
|
||||
defineExpose,
|
||||
getCurrentInstance,
|
||||
markRaw,
|
||||
nextTick,
|
||||
onMounted,
|
||||
provide,
|
||||
ref,
|
||||
toRefs,
|
||||
} from 'vue';
|
||||
|
@ -27,6 +29,8 @@ const props = defineProps({
|
|||
},
|
||||
});
|
||||
|
||||
const emit = defineEmits(['provideGridLayoutRef']);
|
||||
|
||||
const tilesStore = UseTilesStore();
|
||||
|
||||
const { list } = toRefs(props);
|
||||
|
@ -89,6 +93,7 @@ let currentDragCom = null;
|
|||
|
||||
/** 行高 */
|
||||
const rowHeight = ref(0);
|
||||
const colNums = ref(4);
|
||||
/** 屏幕宽度 */
|
||||
const screenW = ref(0);
|
||||
|
||||
|
@ -96,12 +101,12 @@ const domId = `child-${generateRandomString(8)}`;
|
|||
|
||||
// 防抖的 updateRowHeight 函数,等待 200ms 后执行
|
||||
const debouncedUpdateRowHeight = debounce(() => {
|
||||
rowHeight.value = updateRowHeightByGroup(`#${domId}`);
|
||||
[rowHeight.value, colNums.value] = updateRowHeightByGroup(`#${domId}`); // 初始调用
|
||||
}, 0);
|
||||
|
||||
onMounted(() => {
|
||||
window.addEventListener('resize', debouncedUpdateRowHeight);
|
||||
rowHeight.value = updateRowHeightByGroup(`#${domId}`); // 初始调用
|
||||
[rowHeight.value, colNums.value] = updateRowHeightByGroup(`#${domId}`); // 初始调用
|
||||
|
||||
document.addEventListener(
|
||||
'dragover',
|
||||
|
@ -182,7 +187,7 @@ const drag = (e, item) => {
|
|||
el.calcXY(mouseXY.y - parentRect.top, mouseXY.x - parentRect.left);
|
||||
if (mouseInGrid === true) {
|
||||
// function dragEvent(eventName, id, x, y, h, w)
|
||||
proxy.$refs.gridLayout.dragEvent(
|
||||
gridLayoutRef.value.dragEvent(
|
||||
'dragstart',
|
||||
'drop',
|
||||
new_pos.x || 0,
|
||||
|
@ -195,7 +200,7 @@ const drag = (e, item) => {
|
|||
DragPos.y = layout.value[index].y;
|
||||
}
|
||||
if (mouseInGrid === false) {
|
||||
proxy.$refs.gridLayout.dragEvent(
|
||||
gridLayoutRef.value.dragEvent(
|
||||
'dragend',
|
||||
'drop',
|
||||
new_pos.x || 0,
|
||||
|
@ -224,7 +229,7 @@ const dragend = (e) => {
|
|||
mouseInGrid = true;
|
||||
}
|
||||
if (mouseInGrid === true) {
|
||||
proxy.$refs.gridLayout.dragEvent(
|
||||
gridLayoutRef.value.dragEvent(
|
||||
'dragend',
|
||||
'drop',
|
||||
DragPos.x,
|
||||
|
@ -246,7 +251,7 @@ const dragend = (e) => {
|
|||
component: currentDragCom,
|
||||
loadComp,
|
||||
});
|
||||
proxy.$refs.gridLayout.dragEvent(
|
||||
gridLayoutRef.value.dragEvent(
|
||||
'dragend',
|
||||
DragPos.i,
|
||||
DragPos.x,
|
||||
|
@ -317,18 +322,39 @@ const goPage = (item) => {
|
|||
if (tilesIsMove) return;
|
||||
router.push(item?.path);
|
||||
};
|
||||
|
||||
const gridLayoutRef = ref(null);
|
||||
|
||||
console.log(gridLayoutRef.value);
|
||||
provide('gridLayoutRef', gridLayoutRef);
|
||||
|
||||
onMounted(() => {
|
||||
console.log(gridLayoutRef.value);
|
||||
setTimeout(() => {
|
||||
console.log(gridLayoutRef.value);
|
||||
}, 3000);
|
||||
|
||||
nextTick(() => {
|
||||
console.log('我是孙组件', gridLayoutRef.value);
|
||||
emit('provideGridLayoutRef', gridLayoutRef);
|
||||
});
|
||||
});
|
||||
defineExpose({
|
||||
gridLayoutRef: gridLayoutRef.value,
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div :id="domId" class="container-group">
|
||||
<!-- 自定义布局的部分 -->
|
||||
<!-- {{ rowHeight }} -->
|
||||
<div class="grid-box select-none">
|
||||
<grid-layout
|
||||
v-if="rowHeight !== 0"
|
||||
ref="gridLayout"
|
||||
ref="gridLayoutRef"
|
||||
v-model:layout="layout"
|
||||
:auto-size="true"
|
||||
:col-num="4"
|
||||
:col-num="colNums"
|
||||
:is-draggable="tilesIsMove"
|
||||
:is-mirrored="false"
|
||||
:is-resizable="false"
|
||||
|
|
|
@ -27,6 +27,21 @@ const setNewName = () => {
|
|||
emits('editGroupName', props.data.i, cardName.value);
|
||||
};
|
||||
const { data } = toRefs(props);
|
||||
|
||||
const gridLayoutRef = ref(null);
|
||||
|
||||
setTimeout(() => {
|
||||
console.log(gridLayoutRef.value);
|
||||
}, 1000);
|
||||
|
||||
const handleGridLayoutRef = (ref) => {
|
||||
// 这里可以处理孙组件传递过来的 ref
|
||||
console.log('子组件 B 收到孙组件的 ref:', ref.value);
|
||||
};
|
||||
|
||||
defineExpose({
|
||||
childRef: gridLayoutRef.value,
|
||||
});
|
||||
</script>
|
||||
<template>
|
||||
<div class="custom-card flex h-[100%] w-[100%] flex-col">
|
||||
|
@ -53,7 +68,12 @@ const { data } = toRefs(props);
|
|||
<CloseOutlined @click="isEdit = !isEdit" />
|
||||
</Space>
|
||||
</div>
|
||||
<GridGroup :list="data.childer" class="flex-1" />
|
||||
<GridGroup
|
||||
ref="gridLayoutRef"
|
||||
:list="data.childer"
|
||||
class="flex-1"
|
||||
@provide-grid-layout-ref="handleGridLayoutRef"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
<style lang="scss" scoped>
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
import {
|
||||
defineAsyncComponent,
|
||||
getCurrentInstance,
|
||||
inject,
|
||||
markRaw,
|
||||
nextTick,
|
||||
onBeforeUnmount,
|
||||
|
@ -47,6 +48,14 @@ const tilesStore = UseTilesStore();
|
|||
|
||||
const router = useRouter();
|
||||
|
||||
// 组件ref map 形式
|
||||
const componentsRef = ref(new Map());
|
||||
// 设置组件的 ref
|
||||
const setComponentRef = (el, id) => {
|
||||
if (el) {
|
||||
componentsRef.value.set(`child-${id}`, el);
|
||||
}
|
||||
};
|
||||
// import GridGroup from './components/GridGroup/index.vue'
|
||||
|
||||
const { proxy, ctx: that } = getCurrentInstance();
|
||||
|
@ -90,10 +99,17 @@ const debouncedUpdateRowHeight = debounce(() => {
|
|||
rowHeight.value = updateRowHeight('#container-canvas');
|
||||
}, 0);
|
||||
|
||||
// 使用 inject 来获取孙组件 C 的 ref
|
||||
const gridLayoutRef = inject('gridLayoutRef');
|
||||
|
||||
onMounted(() => {
|
||||
window.addEventListener('resize', debouncedUpdateRowHeight);
|
||||
rowHeight.value = updateRowHeight('#container-canvas'); // 初始调用
|
||||
|
||||
setTimeout(() => {
|
||||
console.log(gridLayoutRef); // 获取孙组件 C 的 ref
|
||||
}, 1000);
|
||||
|
||||
document.addEventListener(
|
||||
'dragover',
|
||||
(e) => {
|
||||
|
@ -259,6 +275,10 @@ const dragend = (e) => {
|
|||
tilesIsMove.value = true;
|
||||
});
|
||||
};
|
||||
|
||||
/** targetLayout */
|
||||
const targetLayout = ref({});
|
||||
|
||||
// 尺寸变更后,触发resize事件,使图表resize
|
||||
const resizedEvent = (e) => {
|
||||
if (document.createEvent) {
|
||||
|
@ -268,6 +288,62 @@ const resizedEvent = (e) => {
|
|||
window.fireEvent('onresize');
|
||||
}
|
||||
};
|
||||
|
||||
const domIdxxxxx = ref(null);
|
||||
|
||||
/** 布局更新事件 */
|
||||
const layoutUpdatedEvent = (e) => {
|
||||
// 获取分组元素dom
|
||||
|
||||
// console.log(domIdxxxxx.value);
|
||||
// console.log(dom);
|
||||
console.log('layoutUpdatedEvent', e);
|
||||
};
|
||||
|
||||
/**
|
||||
* 查找当前页面都有哪些分组
|
||||
*/
|
||||
function findGroup() {
|
||||
const group = [];
|
||||
layout.value.forEach((item) => {
|
||||
if (item.childer) {
|
||||
group.push(item);
|
||||
}
|
||||
});
|
||||
console.log('当前画布存在分组:', group);
|
||||
return group;
|
||||
}
|
||||
|
||||
// 检查当前拖拽的元素是否进入目标画布区域
|
||||
const checkIfOverTargetCanvas = (item) => {
|
||||
// 假设目标画布位置为 (2, 0) 宽 4 高 6
|
||||
const targetCanvas = targetLayout.value;
|
||||
const isOver =
|
||||
item.x >= targetCanvas.x &&
|
||||
item.x < targetCanvas.x + targetCanvas.w &&
|
||||
item.y >= targetCanvas.y &&
|
||||
item.y < targetCanvas.y + targetCanvas.h;
|
||||
return isOver;
|
||||
};
|
||||
|
||||
const moveEvent = (e) => {
|
||||
//
|
||||
const group = findGroup();
|
||||
// console.log('当前画布存在分组:', group);
|
||||
console.log('moveEvent', e);
|
||||
// 事件返回的是元素的id
|
||||
// 1. 根据元素id查找元素对应的宽高
|
||||
const dom = layout.value.findIndex((el) => el.i === e);
|
||||
// console.log(dom);
|
||||
|
||||
if (dom !== -1) {
|
||||
targetLayout.value = layout.value[dom];
|
||||
console.log(layout.value[dom]);
|
||||
// 检查是否进入目标画布区域
|
||||
checkIfOverTargetCanvas(e);
|
||||
}
|
||||
};
|
||||
|
||||
// 删除item
|
||||
const delItem = (item) => {
|
||||
const delIndex = layout.value.findIndex((el) => el.i === item.i);
|
||||
|
@ -413,6 +489,18 @@ const formState = reactive({
|
|||
<template>
|
||||
<div id="container-canvas" class="container h-[calc(100%-10px)] px-[20px]">
|
||||
<!-- 自定义布局的部分 -->
|
||||
<!-- {{ screenW }} - {{ rowHeight }}
|
||||
|
||||
<div class="layoutJSON">
|
||||
Displayed as <code>[x, y, w, h]</code>:
|
||||
<div class="columns">
|
||||
<div v-for="item in layout">
|
||||
<b>{{ item.i }}</b
|
||||
>: [{{ item.x }}, {{ item.y }}, {{ item.w }}, {{ item.h }}]
|
||||
</div>
|
||||
</div>
|
||||
</div> -->
|
||||
|
||||
<div class="grid-box index-grid select-none">
|
||||
<grid-layout
|
||||
v-if="rowHeight != 0"
|
||||
|
@ -427,6 +515,7 @@ const formState = reactive({
|
|||
:responsive="false"
|
||||
:row-height="rowHeight"
|
||||
:vertical-compact="true"
|
||||
@layout-updated="layoutUpdatedEvent"
|
||||
>
|
||||
<grid-item
|
||||
v-for="(item, index) in layout"
|
||||
|
@ -441,6 +530,7 @@ const formState = reactive({
|
|||
:w="item.w"
|
||||
:x="item.x"
|
||||
:y="item.y"
|
||||
@move="moveEvent"
|
||||
@resized="resizedEvent"
|
||||
>
|
||||
<span v-if="tilesIsMove" class="close" @click="delItem(item)">
|
||||
|
@ -453,6 +543,7 @@ const formState = reactive({
|
|||
<component
|
||||
:is="item.loadComp"
|
||||
:key="item.i"
|
||||
:ref="(el) => setComponentRef(el, item.i)"
|
||||
:data="item"
|
||||
@edit-group-name="editGroupName"
|
||||
/>
|
||||
|
|
|
@ -1,3 +1,30 @@
|
|||
export const groupList = [
|
||||
{ label: '个人工作台', value: 'workbench', sort: 1 },
|
||||
{ label: '综合行政', value: 'commonoffice', sort: 2 },
|
||||
{ label: '经营管理', value: 'management', sort: 3 },
|
||||
{ label: '安全生产', value: 'Production', sort: 4 },
|
||||
{ label: '勘探开发', value: 'engineering', sort: 5 },
|
||||
{ label: '数据管理', value: 'datamanagement', sort: 6 },
|
||||
{ label: '中心工作', value: 'xxzxzxgz', sort: 7 },
|
||||
{ label: '总部系统', value: 'zongbbm', sort: 8 },
|
||||
{ label: '功能模块', value: 'gongnmk', sort: 9 },
|
||||
{ label: '工程院系统', value: 'gcyyyxt', sort: 10 },
|
||||
];
|
||||
|
||||
export const typeList = [
|
||||
{ label: '多媒体', value: 'dmt', sort: 1 },
|
||||
{ label: '柱状图', value: 'zzt', sort: 2 },
|
||||
{ label: '卡片', value: 'kp', sort: 3 },
|
||||
{ label: '自定义', value: 'zdy', sort: 4 },
|
||||
{ label: '仪表盘', value: 'bgx', sort: 5 },
|
||||
{ label: '折线图', value: 'zxt', sort: 6 },
|
||||
{ label: '列表', value: 'lb', sort: 7 },
|
||||
{ label: '数字', value: 'sz', sort: 8 },
|
||||
{ label: '饼图', value: 'bt', sort: 9 },
|
||||
{ label: '快捷入口', value: 'kjrk', sort: 10 },
|
||||
{ label: '文本', value: 'wb', sort: 11 },
|
||||
];
|
||||
|
||||
const tilesList = [
|
||||
{
|
||||
name1: 'WORKBENCH_USER_TMPL.png',
|
||||
|
@ -9,6 +36,8 @@ const tilesList = [
|
|||
component: './components/Output1/index.vue',
|
||||
i: 131,
|
||||
path: '/usertemplate',
|
||||
group: 'grgzt',
|
||||
type: 'user',
|
||||
},
|
||||
{
|
||||
name1: 'WORKBENCH_BUSINESS.png',
|
||||
|
@ -86,6 +115,8 @@ const tilesList = [
|
|||
h: 2,
|
||||
minW: 1,
|
||||
minH: 2,
|
||||
maxW: 2,
|
||||
maxH: 4,
|
||||
i: 0,
|
||||
x: 1,
|
||||
y: 1,
|
||||
|
|
|
@ -51,51 +51,67 @@ export const updateRowHeight = (domId: string) => {
|
|||
/**
|
||||
* 根据页面宽度,计算行高
|
||||
*/
|
||||
export const updateRowHeightByGroup = (domId: string) => {
|
||||
export const updateRowHeightByGroup = (domId: string): [number, number] => {
|
||||
// const screenWidth = (screenW.value = window.innerWidth);
|
||||
let rowHeight = 0;
|
||||
let colNum = 4;
|
||||
// 获取 id 为 'container-canvas' 的元素宽度
|
||||
const container = document.querySelector(domId);
|
||||
if (!container) {
|
||||
return; // 如果没有找到容器,直接返回
|
||||
return [0, 4]; // 如果没有找到容器,直接返回
|
||||
}
|
||||
const containerWidth = container.offsetWidth; // 获取容器宽度
|
||||
// const containerWidth = container.offsetWidth; // 获取容器宽度
|
||||
// screenW.value = containerWidth;
|
||||
if (containerWidth > 1500) {
|
||||
rowHeight = 100; // 超大屏 (大于1500px)
|
||||
rowHeight = 70; // 超大屏 (大于1500px)
|
||||
colNum = 12;
|
||||
} else if (containerWidth > 1400) {
|
||||
rowHeight = 95; // 宽度 1400px ~ 1500px
|
||||
rowHeight = 70; // 宽度 1400px ~ 1500px
|
||||
colNum = 12;
|
||||
} else if (containerWidth > 1300) {
|
||||
rowHeight = 90; // 宽度 1300px ~ 1400px
|
||||
rowHeight = 70; // 宽度 1300px ~ 1400px
|
||||
colNum = 12;
|
||||
} else if (containerWidth > 1200) {
|
||||
rowHeight = 85; // 宽度 1200px ~ 1300px
|
||||
rowHeight = 70; // 宽度 1200px ~ 1300px
|
||||
colNum = 12;
|
||||
} else if (containerWidth > 1100) {
|
||||
rowHeight = 80; // 宽度 1100px ~ 1200px
|
||||
rowHeight = 70; // 宽度 1100px ~ 1200px
|
||||
colNum = 8;
|
||||
} else if (containerWidth > 1000) {
|
||||
rowHeight = 75; // 宽度 1000px ~ 1100px
|
||||
colNum = 8;
|
||||
} else if (containerWidth > 900) {
|
||||
rowHeight = 70; // 宽度 900px ~ 1000px
|
||||
colNum = 8;
|
||||
} else if (containerWidth > 800) {
|
||||
rowHeight = 65; // 宽度 800px ~ 900px
|
||||
colNum = 8;
|
||||
} else if (containerWidth > 700) {
|
||||
rowHeight = 60; // 宽度 700px ~ 800px
|
||||
colNum = 8;
|
||||
} else if (containerWidth > 600) {
|
||||
rowHeight = 55; // 宽度 600px ~ 700px
|
||||
colNum = 8;
|
||||
} else if (containerWidth > 500) {
|
||||
rowHeight = 50; // 宽度 500px ~ 600px
|
||||
colNum = 6;
|
||||
} else if (containerWidth > 400) {
|
||||
rowHeight = 45; // 宽度 400px ~ 500px
|
||||
colNum = 6;
|
||||
} else if (containerWidth > 300) {
|
||||
rowHeight = 40; // 宽度 300px ~ 400px
|
||||
colNum = 4;
|
||||
} else if (containerWidth > 200) {
|
||||
rowHeight = 35; // 宽度 200px ~ 300px
|
||||
colNum = 4;
|
||||
} else {
|
||||
rowHeight = 30; // 宽度 150px ~ 200px (最小屏幕)
|
||||
colNum = 4;
|
||||
}
|
||||
console.log(`屏幕 ${domId}resize 监测:`, containerWidth, rowHeight);
|
||||
|
||||
return rowHeight;
|
||||
return [rowHeight, colNum];
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
Loading…
Reference in New Issue