自定义跟随逻辑更新
parent
37ebdb9d45
commit
5708d439be
|
|
@ -1,7 +1,7 @@
|
|||
<template>
|
||||
<card-container>
|
||||
<div class="mb-12">定位设置</div>
|
||||
<el-form-item label="跟随组件">
|
||||
<el-form-item v-if="isFollow" label="跟随组件">
|
||||
<el-select v-model="data_follow.id" clearable filterable placeholder="请选择跟随的组件" size="default" class="flex-1" @change="operation_end">
|
||||
<el-option v-for="item in componentOptions" :key="item.id" :label="!isEmpty(item.new_name) ? item.new_name : item.name" :value="item.id" />
|
||||
</el-select>
|
||||
|
|
@ -33,6 +33,10 @@ const props = defineProps({
|
|||
type: Array<any>,
|
||||
default: () => [],
|
||||
},
|
||||
isFollow: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
}
|
||||
});
|
||||
// 跟随内容
|
||||
const data_follow = defineModel('follow', { type: Object, default: { follow_type: 'none', follow_id: '', follow_spacing: 0, is_disable_x: false, is_disable_y: false }});
|
||||
|
|
@ -49,39 +53,28 @@ const location_x_change = (val: number) => {
|
|||
}
|
||||
// y轴变化时,更新记录的位置
|
||||
const location_y_change = (val: number) => {
|
||||
console.log(val);
|
||||
data_location.value.record_y = val;
|
||||
data_location.value.staging_y = val
|
||||
};
|
||||
|
||||
// 跟随id发生变化时的处理
|
||||
watch(() => data_follow.value, (val) => {
|
||||
const { spacing = 0, type = 'left', id = '' } = data_follow.value;
|
||||
const { spacing = 0, type = 'left', id = '' } = val;
|
||||
props.componentOptions.forEach((item: any) => {
|
||||
if (item.id == id) {
|
||||
const { location, com_data } = item;
|
||||
const new_x = location.x + com_data.com_width + spacing;
|
||||
const new_y = location.y + com_data.com_height + spacing;
|
||||
// // 先解除不可移动的处理 is_disable_x true 为不可移动,false为可以拖动
|
||||
// // 先解除不可移动的处理 is_disable_x true 为不可移动,false为可以拖动, 频繁切换会导致引用的组件报错,暂时使用当前内容
|
||||
// data_follow.value.is_disable_x = false;
|
||||
// data_follow.value.is_disable_y = false;
|
||||
if (type =='left') {
|
||||
data_location.value.x = new_x;
|
||||
data_location.value.record_x = new_x;
|
||||
// setTimeout(() => {
|
||||
// // // 等赋值完成之后再放开定位处理
|
||||
// data_follow.value.is_disable_x = true;
|
||||
// data_follow.value.is_disable_y = false;
|
||||
// }, 0);
|
||||
} else if (type =='top') {
|
||||
data_location.value.y = new_y;
|
||||
data_location.value.record_y = new_y;
|
||||
data_location.value.staging_y = new_y
|
||||
// setTimeout(() => {
|
||||
// // // 等赋值完成之后再添加禁止移动处理
|
||||
// data_follow.value.is_disable_x = false;
|
||||
// data_follow.value.is_disable_y = true;
|
||||
// }, 0);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
<template>
|
||||
<div class="w h re custom-other">
|
||||
<div v-for="(item, index) in list" :key="item.id" :class="`main-content flex-row ${ animation_class(item.com_data) }`" :style="{'left': percentage_count(item.location.x) , 'top': percentage_count(item.location.y), 'width': percentage_count(item.com_data.com_width), 'height': percentage_count(item.com_data.com_height), 'z-index': (customList.length - 1) - index}">
|
||||
<template v-if="item.key == 'text'">
|
||||
<div v-for="(item, index) in list" :key="item.id" ref="signList" :data-id="item.id" :data-location-x="item.location.x" :data-location-y="item.location.y" :class="`main-content flex-row ${ animation_class(item.com_data) }`" :style="`left: ${ percentage_count(item.location.x, item.com_data.data_follow, 'left') }; top: ${ percentage_count(item.location.y, item.com_data.data_follow, 'top') }; width: ${ percentage_count(item.com_data.com_width, item.com_data.data_follow, 'width', item.com_data.is_width_auto, item.com_data.max_width) }; height: ${ percentage_count(item.com_data.com_height, item.com_data.data_follow, 'height', item.com_data.is_height_auto, item.com_data.max_height) };z-index: ${ (list.length - 1) - index};`">
|
||||
<template v-if="item.key == 'text'">
|
||||
<model-text :key="item.id" :value="item.com_data" :scale="scale" :source-list="sourceList" :config-loop="configLoop" :is-custom="isCustom" :custom-group-field-id="customGroupFieldId" :is-custom-group="isCustomGroup" :title-params="showData?.data_name || 'name'" :is-display-panel="true"></model-text>
|
||||
</template>
|
||||
<template v-else-if="item.key == 'img'">
|
||||
|
|
@ -93,9 +93,68 @@ const props = defineProps({
|
|||
}
|
||||
});
|
||||
|
||||
const list = computed(() => props.customList);
|
||||
const percentage_count = (val: number) => {
|
||||
return val * props.scale + 'px';
|
||||
const list = ref(props.customList);
|
||||
const signList = ref<HTMLElement[] | null>(null);
|
||||
watch(() => props.customList, async (val) => {
|
||||
list.value = val;
|
||||
const follow_list = val.filter(item => item.com_data?.data_follow?.id !== '');
|
||||
if (follow_list.length > 0) {
|
||||
await nextTick();
|
||||
if (signList.value && signList.value.length > 0) {
|
||||
// 使用双重for循环确保每个组件都进行了刷新
|
||||
signList.value.forEach((item) => {
|
||||
follow_list.forEach((item1) => {
|
||||
const { data_follow } = item1.com_data;
|
||||
if (data_follow?.id === item.dataset.id) {
|
||||
if (data_follow?.type == 'left') {
|
||||
if (item1.location && item.dataset.locationX) {
|
||||
const locationX = parseFloat(item.dataset.locationX);
|
||||
if (!isNaN(locationX)) {
|
||||
item1.location.x = ((locationX + data_follow.spacing) * props.scale) + item.clientWidth;
|
||||
}
|
||||
}
|
||||
} else if (data_follow?.type == 'top') {
|
||||
if (item1.location && item.dataset.locationY) {
|
||||
const locationY = parseFloat(item.dataset.locationY);
|
||||
if (!isNaN(locationY)) {
|
||||
item1.location.y = ((locationY + data_follow.spacing) * props.scale) + item.clientWidth;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
});
|
||||
}
|
||||
}
|
||||
}, { immediate: true, deep: true });
|
||||
|
||||
const percentage_count = (val: number, data_follow: { id: string, type: string }, type: string, is_auto?: string, max_size?: number) => {
|
||||
if (['left', 'top'].includes(type)) {
|
||||
const { id = '', type: follow_type = 'left' } = data_follow;
|
||||
if (id !== '' && follow_type == type) {
|
||||
return val + 'px';
|
||||
} else {
|
||||
return val * props.scale + 'px';
|
||||
}
|
||||
} else {
|
||||
if (is_auto == '1') {
|
||||
if (type === 'width') {
|
||||
if (max_size !== undefined && max_size > 0) {
|
||||
return `auto; max-width:${max_size * props.scale}px;`;
|
||||
} else {
|
||||
return 'auto;';
|
||||
}
|
||||
} else if (type === 'height') {
|
||||
if (max_size !== undefined && max_size > 0) {
|
||||
return `auto; max-height:${max_size * props.scale}px;`;
|
||||
} else {
|
||||
return 'auto;';
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return val * props.scale + 'px';
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const custom_height = computed(() => props.dataHeight * props.scale + 'px');
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@
|
|||
</div>
|
||||
</div>
|
||||
<template v-else>
|
||||
<div class="w h" :style="style_chunk_container">
|
||||
<div :style="style_chunk_container">
|
||||
<div class="w h oh" :style="style_chunk_img_container">
|
||||
<data-rendering :custom-list="form.custom_list" :data-height="dataHeight" :scale="custom_scale" :is-custom-group="true" :is-custom="isCustom" :config-loop="configLoop !== '1' ? form.is_use_parent_data : '1'"></data-rendering>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
<template>
|
||||
<div class="w h bg-f">
|
||||
<el-form :model="form" label-width="70">
|
||||
<custom-location v-model="diy_data.location" v-model:follow="form.data_follow" :component-options="componentOptions" @operation_end="operation_end"></custom-location>
|
||||
<custom-location v-model="diy_data.location" v-model:follow="form.data_follow" :is-follow="!followName.includes(diy_data.id)" :component-options="componentOptions" @operation_end="operation_end"></custom-location>
|
||||
<div class="bg-f5 divider-line" />
|
||||
<card-container>
|
||||
<div class="mb-12">容器设置</div>
|
||||
|
|
@ -49,7 +49,11 @@ const props = defineProps({
|
|||
componentOptions: {
|
||||
type: Array<any>,
|
||||
default: () => [],
|
||||
}
|
||||
},
|
||||
followName: {
|
||||
type: Array<string>,
|
||||
default: [],
|
||||
},
|
||||
});
|
||||
// 默认值
|
||||
const tabs_name = ref('content');
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
<template>
|
||||
<div class="w h bg-f">
|
||||
<el-form :model="form" label-width="70">
|
||||
<custom-location v-model="diy_data.location" v-model:follow="form.data_follow" :component-options="componentOptions" @operation_end="operation_end"></custom-location>
|
||||
<custom-location v-model="diy_data.location" v-model:follow="form.data_follow" :is-follow="!followName.includes(diy_data.id)" :component-options="componentOptions" @operation_end="operation_end"></custom-location>
|
||||
<div class="bg-f5 divider-line" />
|
||||
<card-container>
|
||||
<div class="mb-12">文本设置</div>
|
||||
|
|
@ -110,7 +110,11 @@ const props = defineProps({
|
|||
componentOptions: {
|
||||
type: Array<any>,
|
||||
default: () => [],
|
||||
}
|
||||
},
|
||||
followName: {
|
||||
type: Array<string>,
|
||||
default: [],
|
||||
},
|
||||
});
|
||||
// 默认值
|
||||
const state = reactive({
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
<template>
|
||||
<div class="w h bg-f">
|
||||
<el-form :model="form" label-width="70">
|
||||
<custom-location v-model="diy_data.location" v-model:follow="form.data_follow" :component-options="componentOptions" @operation_end="operation_end"></custom-location>
|
||||
<custom-location v-model="diy_data.location" v-model:follow="form.data_follow" :is-follow="!followName.includes(diy_data.id)" :component-options="componentOptions" @operation_end="operation_end"></custom-location>
|
||||
<div class="bg-f5 divider-line" />
|
||||
<card-container>
|
||||
<div class="mb-12">图片设置</div>
|
||||
|
|
@ -84,7 +84,11 @@ const props = defineProps({
|
|||
componentOptions: {
|
||||
type: Array<any>,
|
||||
default: () => [],
|
||||
}
|
||||
},
|
||||
followName: {
|
||||
type: Array<string>,
|
||||
default: [],
|
||||
},
|
||||
});
|
||||
// 默认值
|
||||
const state = reactive({
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
<template>
|
||||
<div class="w h bg-f">
|
||||
<el-form :model="form" label-width="70">
|
||||
<custom-location v-model="diy_data.location" v-model:follow="form.data_follow" :component-options="componentOptions" @operation_end="operation_end"></custom-location>
|
||||
<custom-location v-model="diy_data.location" v-model:follow="form.data_follow" :is-follow="!followName.includes(diy_data.id)" :component-options="componentOptions" @operation_end="operation_end"></custom-location>
|
||||
<div class="bg-f5 divider-line" />
|
||||
<card-container class="">
|
||||
<div class="mb-12">线条设置</div>
|
||||
|
|
@ -60,7 +60,11 @@ const props = defineProps({
|
|||
componentOptions: {
|
||||
type: Array<any>,
|
||||
default: () => [],
|
||||
}
|
||||
},
|
||||
followName: {
|
||||
type: Array<string>,
|
||||
default: [],
|
||||
},
|
||||
});
|
||||
// 默认值
|
||||
const state = reactive({
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
<template>
|
||||
<div class="w h bg-f">
|
||||
<el-form :model="form" label-width="70">
|
||||
<custom-location v-model="diy_data.location" v-model:follow="form.data_follow" :component-options="componentOptions" @operation_end="operation_end"></custom-location>
|
||||
<custom-location v-model="diy_data.location" v-model:follow="form.data_follow" :is-follow="!followName.includes(diy_data.id)" :component-options="componentOptions" @operation_end="operation_end"></custom-location>
|
||||
<div class="bg-f5 divider-line" />
|
||||
<card-container>
|
||||
<div class="mb-12">容器设置</div>
|
||||
|
|
@ -82,7 +82,11 @@ const props = defineProps({
|
|||
componentOptions: {
|
||||
type: Array<any>,
|
||||
default: () => [],
|
||||
}
|
||||
},
|
||||
followName: {
|
||||
type: Array<string>,
|
||||
default: [],
|
||||
},
|
||||
});
|
||||
// 默认值
|
||||
const state = reactive({
|
||||
|
|
|
|||
|
|
@ -205,7 +205,7 @@ const set_count = () => {
|
|||
if (props.isDisplayPanel) {
|
||||
return '';
|
||||
} else {
|
||||
const { com_width = 0, com_height = 0, is_width_auto = '0', is_height_auto = '0', max_width = 0, max_height = 0} = form.value;
|
||||
const { com_width = 0, com_height = 0, is_width_auto = '0', is_height_auto = '0', max_width = 0, max_height = 0 } = form.value;
|
||||
const new_max_width = max_width > 0 ? `max-width: ${ max_width }px;` : 'white-space: nowrap;';
|
||||
const new_max_height = max_height > 0 ? `max-height: ${ max_height }px;` : '';
|
||||
return `${ is_width_auto == '1' ? `width:100%;${ new_max_width }` : `width:${ com_width }px;`}${ is_height_auto == '1' ? `height:100%;${ new_max_height }` : `height: ${ com_height }px;` }`;
|
||||
|
|
@ -214,8 +214,9 @@ const set_count = () => {
|
|||
const emits = defineEmits(['container_change']);
|
||||
// 开启自定义的时候重新计算高度和宽度
|
||||
const modelText = ref<HTMLElement | null>(null);
|
||||
watch(() => form.value, (value) => {
|
||||
watch(() => form.value, async (value) => {
|
||||
const { is_width_auto = '0', is_height_auto = '0', max_width = 0, max_height = 0 , com_width = 0, com_height = 0} = form.value;
|
||||
await nextTick();
|
||||
let new_width = com_width;
|
||||
let new_height = com_height;
|
||||
// 宽度自适应时 获取当前容器的宽度
|
||||
|
|
@ -227,10 +228,10 @@ watch(() => form.value, (value) => {
|
|||
new_height = modelText.value?.clientHeight || 0;
|
||||
}
|
||||
// 如果跟历史的宽度或者高度不同,则更新
|
||||
if (new_width !== com_width && new_height !== com_height) {
|
||||
if (new_width !== com_width || new_height !== com_height) {
|
||||
emits('container_change', new_width, new_height)
|
||||
}
|
||||
}, { deep: true });
|
||||
}, { immediate: true, deep: true });
|
||||
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
<template>
|
||||
<div class="w h bg-f">
|
||||
<el-form :model="form" label-width="80">
|
||||
<custom-location v-model="diy_data.location" v-model:follow="form.data_follow" :component-options="componentOptions" @operation_end="operation_end"></custom-location>
|
||||
<custom-location v-model="diy_data.location" v-model:follow="form.data_follow" :is-follow="!followName.includes(diy_data.id)" :component-options="componentOptions" @operation_end="operation_end"></custom-location>
|
||||
<div class="bg-f5 divider-line" />
|
||||
<card-container>
|
||||
<div class="mb-12">文本设置</div>
|
||||
|
|
@ -156,7 +156,11 @@ const props = defineProps({
|
|||
componentOptions: {
|
||||
type: Array<any>,
|
||||
default: () => [],
|
||||
}
|
||||
},
|
||||
followName: {
|
||||
type: Array<string>,
|
||||
default: [],
|
||||
},
|
||||
});
|
||||
// 默认值
|
||||
const state = reactive({
|
||||
|
|
@ -237,11 +241,11 @@ const is_height_auto_change = (val: string | number | boolean) => {
|
|||
watch(
|
||||
diy_data,
|
||||
(val) => {
|
||||
// diy_data.value.location.x = location_compute(form.value.com_width, val.location.x, 390);
|
||||
// diy_data.value.location.y = location_compute(form.value.com_height, val.location.y, center_height.value);
|
||||
// diy_data.value.location.record_x = location_compute(form.value.com_width, val.location.record_x, 390);
|
||||
// diy_data.value.location.record_y = location_compute(form.value.com_height, val.location.record_y, center_height.value);
|
||||
// diy_data.value.location.staging_y = location_compute(form.value.com_height, val.location.staging_y, center_height.value);
|
||||
diy_data.value.location.x = location_compute(form.value.com_width, val.location.x, 390);
|
||||
diy_data.value.location.y = location_compute(form.value.com_height, val.location.y, center_height.value);
|
||||
diy_data.value.location.record_x = location_compute(form.value.com_width, val.location.record_x, 390);
|
||||
diy_data.value.location.record_y = location_compute(form.value.com_height, val.location.record_y, center_height.value);
|
||||
diy_data.value.location.staging_y = location_compute(form.value.com_height, val.location.staging_y, center_height.value);
|
||||
form.value.staging_height = form.value.com_height;
|
||||
},
|
||||
{ immediate: true, deep: true }
|
||||
|
|
|
|||
|
|
@ -6,22 +6,22 @@
|
|||
<!-- 右侧配置区域 -->
|
||||
<div class="settings">
|
||||
<template v-if="diy_data.key === 'img'">
|
||||
<model-image-style :key="key" v-model:height="center_height" :options="configLoop == '1' ? options : []" :value="diy_data" :component-options='all_diy_data' @operation_end="operation_end"></model-image-style>
|
||||
<model-image-style :key="key" v-model:height="center_height" :options="configLoop == '1' ? options : []" :value="diy_data" :follow-name="follow_name" :component-options='all_diy_data' @operation_end="operation_end"></model-image-style>
|
||||
</template>
|
||||
<template v-else-if="diy_data.key == 'text'">
|
||||
<model-text-style :key="key" v-model:height="center_height" :options="configLoop == '1' ? options : []" :value="diy_data" :component-options='all_diy_data' @operation_end="operation_end"></model-text-style>
|
||||
<model-text-style :key="key" v-model:height="center_height" :options="configLoop == '1' ? options : []" :value="diy_data" :follow-name="follow_name" :component-options='all_diy_data' @operation_end="operation_end"></model-text-style>
|
||||
</template>
|
||||
<template v-else-if="diy_data.key == 'auxiliary-line'">
|
||||
<model-lines-style :key="key" v-model:height="center_height" :options="configLoop == '1' ? options : []" :value="diy_data" :component-options='all_diy_data' @operation_end="operation_end"></model-lines-style>
|
||||
<model-lines-style :key="key" v-model:height="center_height" :options="configLoop == '1' ? options : []" :value="diy_data" :follow-name="follow_name" :component-options='all_diy_data' @operation_end="operation_end"></model-lines-style>
|
||||
</template>
|
||||
<template v-else-if="diy_data.key == 'icon'">
|
||||
<model-icon-style :key="key" v-model:height="center_height" :options="configLoop == '1' ? options : []" :value="diy_data" :component-options='all_diy_data' @operation_end="operation_end"></model-icon-style>
|
||||
<model-icon-style :key="key" v-model:height="center_height" :options="configLoop == '1' ? options : []" :value="diy_data" :follow-name="follow_name" :component-options='all_diy_data' @operation_end="operation_end"></model-icon-style>
|
||||
</template>
|
||||
<template v-else-if="diy_data.key == 'panel'">
|
||||
<model-panel-style :key="key" v-model:height="center_height" :options="configLoop == '1' ? options : []" :value="diy_data" :component-options='all_diy_data' @operation_end="operation_end"></model-panel-style>
|
||||
<model-panel-style :key="key" v-model:height="center_height" :options="configLoop == '1' ? options : []" :value="diy_data" :follow-name="follow_name" :component-options='all_diy_data' @operation_end="operation_end"></model-panel-style>
|
||||
</template>
|
||||
<template v-else-if="diy_data.key == 'custom-group' && configType == 'custom'">
|
||||
<model-custom-group-style :key="key" v-model:height="center_height" :config-loop="configLoop" :options="configLoop == '1' ? options : []" :value="diy_data" :component-options='all_diy_data' @custom_edit="custom_edit" @operation_end="operation_end"></model-custom-group-style>
|
||||
<model-custom-group-style :key="key" v-model:height="center_height" :config-loop="configLoop" :options="configLoop == '1' ? options : []" :value="diy_data" :follow-name="follow_name" :component-options='all_diy_data' @custom_edit="custom_edit" @operation_end="operation_end"></model-custom-group-style>
|
||||
</template>
|
||||
<template v-else>
|
||||
<div class="w h flex align-c bg-f">
|
||||
|
|
@ -126,12 +126,20 @@ const diy_data = ref<diy>({
|
|||
// 唯一标识
|
||||
const key = ref('');
|
||||
const all_diy_data = ref<Array<any>>([]);
|
||||
const follow_name = ref<Array<string>>([]);
|
||||
const right_update = (item: any, all_diy: Array<any>) => {
|
||||
diy_data.value = item;
|
||||
// 生成随机id
|
||||
key.value = Math.random().toString(36).substring(2);
|
||||
// 筛选出所有已经被跟随过的组件
|
||||
all_diy.forEach(item1 => {
|
||||
if (item1.com_data?.data_follow?.id && item1.com_data.data_follow.id !== '' && !follow_name.value.includes(item1.com_data.data_follow.id)) {
|
||||
follow_name.value.push(item1.com_data.data_follow.id);
|
||||
}
|
||||
});
|
||||
// 不是当前组件,并且没有跟随过其他组件的可以被跟随
|
||||
all_diy_data.value = all_diy.filter(item1 => item.id !== item1.id && item1.com_data.data_follow.id == '');
|
||||
all_diy_data.value = all_diy.filter(item1 => item.id !== item1.id && item1.com_data?.data_follow?.id == '');
|
||||
console.log(all_diy_data.value);
|
||||
};
|
||||
const draglist = ref<diy_data | null>(null);
|
||||
const emits = defineEmits(['accomplish', 'custom_edit']);
|
||||
|
|
|
|||
|
|
@ -25,7 +25,8 @@ const text_com_data = {
|
|||
is_height_auto: '0',
|
||||
max_width: 150,
|
||||
max_height: 17,
|
||||
data_follow: { type: 'left', id: '', spacing: 0, is_disable_x: false, is_disable_y: false },
|
||||
data_follow: { type: 'left', id: '', spacing: 0 },
|
||||
is_data_update: false,
|
||||
is_rich_text: '0',
|
||||
is_up_down: '1',
|
||||
text_color: '#000',
|
||||
|
|
@ -82,7 +83,8 @@ const img_com_data = {
|
|||
id: '',
|
||||
option: {}
|
||||
},
|
||||
data_follow: { type: 'left', id: '', spacing: 0, is_disable_x: false, is_disable_y: false },
|
||||
data_follow: { type: 'left', id: '', spacing: 0 },
|
||||
is_data_update: false,
|
||||
img_radius: {
|
||||
radius: 0,
|
||||
radius_top_left: 0,
|
||||
|
|
@ -131,7 +133,8 @@ const line_com_data = {
|
|||
type: '', // 条件类型
|
||||
value: '', // 值
|
||||
},
|
||||
data_follow: { type: 'left', id: '', spacing: 0, is_disable_x: false, is_disable_y: false },
|
||||
data_follow: { type: 'left', id: '', spacing: 0 },
|
||||
is_data_update: false,
|
||||
animation_style: {
|
||||
type: 'none',
|
||||
number: 'infinite',
|
||||
|
|
@ -154,7 +157,8 @@ const icon_com_data = {
|
|||
id: '',
|
||||
option: {}
|
||||
},
|
||||
data_follow: { type: 'left', id: '', spacing: 0, is_disable_x: false, is_disable_y: false },
|
||||
data_follow: { type: 'left', id: '', spacing: 0 },
|
||||
is_data_update: false,
|
||||
is_rich_icon: '0',
|
||||
is_up_down: '1',
|
||||
icon_color: '#000',
|
||||
|
|
@ -205,7 +209,8 @@ const panel_com_data = {
|
|||
id: '',
|
||||
option: {}
|
||||
},
|
||||
data_follow: { type: 'left', id: '', spacing: 0, is_disable_x: false, is_disable_y: false },
|
||||
data_follow: { type: 'left', id: '', spacing: 0 },
|
||||
is_data_update: false,
|
||||
icon_rotate: 0,
|
||||
background_img_style: '2',
|
||||
background_img: [],
|
||||
|
|
@ -233,7 +238,7 @@ const panel_com_data = {
|
|||
number: 'infinite',
|
||||
}
|
||||
}
|
||||
|
||||
// 自定义组件的默认值
|
||||
const custom_group_com_data = {
|
||||
// 容器高度
|
||||
com_width: 100,
|
||||
|
|
@ -243,7 +248,8 @@ const custom_group_com_data = {
|
|||
id: '',
|
||||
option: []
|
||||
},
|
||||
data_follow: { type: 'left', id: '', spacing: 0, is_disable_x: false, is_disable_y: false },
|
||||
data_follow: { type: 'left', id: '', spacing: 0 },
|
||||
is_data_update: false,
|
||||
// 条件判断
|
||||
condition: {
|
||||
field: '', // 字段id
|
||||
|
|
|
|||
|
|
@ -68,7 +68,7 @@
|
|||
<div class="w h" @mousedown.prevent="start_drag" @mousemove.prevent="move_drag" @mouseup.prevent="end_drag">
|
||||
<DraggableContainer v-if="draggable_container" style="z-index:0" :reference-line-visible="true" :disabled="false" reference-line-color="#f00f00" @selectstart.prevent @contextmenu.prevent @dragstart.prevent>
|
||||
<!-- @mouseover="on_choose(index)" -->
|
||||
<Vue3DraggableResizable v-for="(item, index) in diy_data" :key="item.id + item.location.x + item.location.y" v-model:w="item.com_data.com_width" v-model:h="item.com_data.com_height" :min-w="0" :min-h="0" :class="[`${ animation_class(item.com_data) } `, {'plug-in-show-component-line': is_show_component_line, 'plug-in-show-tabs': item.show_tabs == '1', 'vdr-handle-z-index': item.com_data.bottom_up == '1' }]" :style="[`${ item.com_data.is_width_auto == '1' ? 'width: auto;' : '' }${ item.com_data.is_height_auto == '1' ? 'height: auto;' : '' }`, { 'z-index': (diy_data.length - 1) - index }]" :init-w="item.com_data.com_width" :init-h="item.com_data.com_height" :x="item.location.x" :y="item.location.y" :parent="true" :draggable="is_draggable" @mousedown.stop="on_choose(index, item.show_tabs)" @click.stop="on_choose(index, item.show_tabs)" @drag-end="dragEndHandle($event, index)" @resizing="resizingHandle($event, item.key, index, 'resizing')" @resize-end="resizingHandle($event, item.key, index, 'resizeEnd')">
|
||||
<Vue3DraggableResizable v-for="(item, index) in diy_data" :key="item.id + item.com_data.is_data_update" v-model:w="item.com_data.com_width" v-model:h="item.com_data.com_height" :min-w="0" :min-h="0" :class="[`${ animation_class(item.com_data) } `, {'plug-in-show-component-line': is_show_component_line, 'plug-in-show-tabs': item.show_tabs == '1', 'vdr-handle-z-index': item.com_data.bottom_up == '1' }]" :style="[`${ item.com_data.is_width_auto == '1' ? 'width: auto;' : '' }${ item.com_data.is_height_auto == '1' ? 'height: auto;' : '' }`, { 'z-index': (diy_data.length - 1) - index }]" :init-w="item.com_data.com_width" :init-h="item.com_data.com_height" :x="item.location.x" :y="item.location.y" :parent="true" :draggable="is_draggable" @mousedown.stop="on_choose(index, item.show_tabs)" @click.stop="on_choose(index, item.show_tabs)" @drag-end="dragEndHandle($event, index)" @resizing="resizingHandle($event, item.key, index, 'resizing')" @resize-end="resizingHandle($event, item.key, index, 'resizeEnd')">
|
||||
<div :class="['main-content flex-row', { 'plug-in-border': item.show_tabs == '1' }]">
|
||||
<template v-if="item.key == 'text'">
|
||||
<model-text :key="item.id" :value="item.com_data" :source-list="props.sourceList" :config-loop="configLoop" :is-custom="isCustom" :is-custom-group="isCustomGroup" :custom-group-field-id="customGroupFieldId" :title-params="showData?.data_name || 'name'" @container_change="(...value: [number, number]) => container_change(...value, index)"></model-text>
|
||||
|
|
@ -112,11 +112,10 @@
|
|||
</template>
|
||||
<script setup lang="ts">
|
||||
import { cloneDeep, isEmpty, property, isEqual } from 'lodash';
|
||||
import { get_math, adjustPosition, getPlatform, get_history_name } from '@/utils';
|
||||
import { get_math, adjustPosition, getPlatform, get_history_name, diy_data_handle, new_location_handle } from '@/utils';
|
||||
import { defaultComData, isRectangleIntersecting } from "./index-default";
|
||||
import { SortableEvent, VueDraggable } from 'vue-draggable-plus';
|
||||
import { commonStore, DataSourceStore } from '@/store';
|
||||
import { ItemProps } from 'element-plus';
|
||||
const common_store = commonStore();
|
||||
// 删除
|
||||
const app = getCurrentInstance();
|
||||
|
|
@ -311,6 +310,13 @@ const del = (index: null | number) => {
|
|||
});
|
||||
const show_tabs_index = diy_data.value.findIndex((item: any) => item.show_tabs == '1');
|
||||
const new_name = get_history_name(cloneDeep(diy_data.value[show_tabs_index == -1 ? 0 : show_tabs_index]));
|
||||
// 删除的时候修改跟随组件的内容显示内容
|
||||
const old_id = diy_data.value[index].id;
|
||||
diy_data.value.forEach(item => {
|
||||
if (item.com_data?.data_follow?.id === old_id) {
|
||||
item.com_data.data_follow.id = '';
|
||||
}
|
||||
});
|
||||
// 删除的是当前的这个数据
|
||||
if (show_tabs_index == index) {
|
||||
// 调用删除接口,然后,更新数据
|
||||
|
|
@ -431,13 +437,15 @@ const cancel = () => {
|
|||
};
|
||||
//#endregion
|
||||
//#region 文本开启自适应时的处理
|
||||
const container_change = (width: number, height: number, index: number,) => {
|
||||
const container_change = (width: number, height: number, index: number) => {
|
||||
console.log('1454545');
|
||||
diy_data.value.forEach((item, index1) => {
|
||||
if (index == index1) {
|
||||
item.com_data.com_width = width;
|
||||
item.com_data.com_height = height;
|
||||
}
|
||||
});
|
||||
console.log(diy_data.value, '12145');
|
||||
}
|
||||
//#endregion
|
||||
//#region 容器高度发生变化时的处理,拖拽组件高度变化时数据需要重新赋值,避免拖拽不到新高度的区域
|
||||
|
|
@ -470,7 +478,7 @@ watch(() => center_height.value, () => {
|
|||
},
|
||||
com_data: {
|
||||
// 规整历史数据,避免有新增字段不存在导致报错
|
||||
...Object.assign({}, cloneDeep((defaultComData as any)[`${item.key}_com_data`]), item.com_data),
|
||||
...Object.assign({}, cloneDeep((defaultComData as any)[`${ ['custom-group', 'auxiliary-line'].includes(item.key) ? (item.key == 'custom-group'? 'custom_group' : 'line'): item.key }_com_data`]), item.com_data),
|
||||
com_height: item.com_data.staging_height,
|
||||
...(item.key == 'text' ? { max_height:item.com_data.staging_height } : {}),
|
||||
data_source_field: {
|
||||
|
|
@ -551,50 +559,46 @@ const drop = (event: any) => {
|
|||
};
|
||||
//#endregion
|
||||
//#region 区域内拖拽显示
|
||||
const dragEndHandle = (item: any, index: number) => {
|
||||
const old_location = cloneDeep(diy_data.value[index].location);
|
||||
const { data_follow, com_width, com_height} = diy_data.value[index].com_data;
|
||||
let new_x = old_location.x;
|
||||
let new_y = old_location.y;
|
||||
// 如果是跟随的模版,根据选中的内容 x或者y不变
|
||||
if (data_follow.id != '') {
|
||||
if (data_follow.type == 'left') {
|
||||
new_y = item.y;
|
||||
} else if (data_follow.type == 'top') {
|
||||
new_x = item.x;
|
||||
const dragEndHandle = (new_val: any, index: number) => {
|
||||
const { location: old_location, com_data, id: old_id } = cloneDeep(diy_data.value[index])
|
||||
const { data_follow = {}, com_width, com_height, is_data_update } = com_data;
|
||||
// 处理后的x、y坐标
|
||||
const { new_x, new_y } = new_location_handle(old_location, data_follow, new_val);
|
||||
if (data_follow?.id == '') {
|
||||
// 如果有跟随的模版,则需要更新跟随的模版的位置
|
||||
const index = diy_data.value.findIndex(item => old_id == item.com_data?.data_follow?.id);
|
||||
if (index != -1) {
|
||||
diy_data.value = diy_data_handle(diy_data.value, old_id, new_val, com_width, com_height);
|
||||
}
|
||||
} else {
|
||||
diy_data.value.forEach((item1: any) => {
|
||||
const { id = '', type = 'left', spacing = 0 } = item1.com_data.data_follow;
|
||||
// 判断当前组件是否被其他组件跟随
|
||||
if (item.id == id) {
|
||||
const new_location_x = old_location.x + com_width + spacing;
|
||||
const new_location_y = old_location.y + com_height + spacing;
|
||||
if (type =='left') {
|
||||
item1.location.x = new_location_x;
|
||||
item1.location.record_x = new_location_x;
|
||||
} else if (type =='top') {
|
||||
item1.location.y = new_location_y;
|
||||
item1.location.record_y = new_location_y;
|
||||
item1.location.staging_y = new_location_y;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
const new_location = { x: new_x, y: new_y, record_x: new_x, record_y: new_y, staging_y: new_y };
|
||||
diy_data.value[index].location = new_location;
|
||||
// 拖拽结束的时候组件不会更新xy,需要添加一个唯一key值,避免出现没更新的问题
|
||||
diy_data.value[index].com_data.is_data_update = !is_data_update;
|
||||
// 对数组进行比较,确定跟之前的是否有变化
|
||||
if (!isEqual(old_location, new_location)) {
|
||||
operation_end(get_history_name(diy_data.value[index]));
|
||||
}
|
||||
};
|
||||
// 拖拽结束时触发的事件 {x: number, y: number, w: number, h: number}
|
||||
// 拖拽放大缩小结束时触发的事件 {x: number, y: number, w: number, h: number}
|
||||
const resizingHandle = (new_location: any, key: string, index: number, type: string) => {
|
||||
const { x, y, w, h } = new_location;
|
||||
// 对应位置的定位修改为当前更新的位置
|
||||
diy_data.value[index].location = { x, y, record_x: x, record_y: y, staging_y: y };
|
||||
const { location: old_location, id: old_id } = cloneDeep(diy_data.value[index]);
|
||||
// 获取到当前更新的内容
|
||||
const com_data = diy_data.value[index].com_data;
|
||||
const { data_follow } = com_data;
|
||||
const { w, h } = new_location;
|
||||
// 处理后的x、y坐标
|
||||
const { new_x, new_y } = new_location_handle(old_location, data_follow, new_location);
|
||||
if (data_follow.id == '') {
|
||||
// 如果有跟随的模版,则需要更新跟随的模版的位置
|
||||
const index = diy_data.value.findIndex(item => old_id == item.com_data.data_follow.id);
|
||||
if (index != -1) {
|
||||
diy_data.value = diy_data_handle(diy_data.value, old_id, new_location, w, h);
|
||||
}
|
||||
}
|
||||
// 对应位置的定位修改为当前更新的位置
|
||||
diy_data.value[index].location = { x: new_x, y: new_y, record_x: new_x, record_y: new_y, staging_y: new_y };
|
||||
// const com_data = diy_data.value[index].com_data;
|
||||
// 更新组件的宽高
|
||||
com_data.com_width = w;
|
||||
com_data.com_height = h;
|
||||
|
|
|
|||
|
|
@ -169,8 +169,8 @@ const change_style = (val: string | number | boolean | undefined): void => {
|
|||
const list = base_list.product_style_list.filter(item => item.value == form.value.theme);
|
||||
if (list.length > 0) {
|
||||
// emits('theme_change', list[0].width, list[0].height);
|
||||
data.value.shop_img_width = list[0].width;
|
||||
data.value.shop_img_height = list[0].height;
|
||||
data.value.content_img_width = list[0].width;
|
||||
data.value.content_img_height = list[0].height;
|
||||
}
|
||||
};
|
||||
const is_revise = ref(false);
|
||||
|
|
|
|||
|
|
@ -200,8 +200,8 @@ const defaultArticleList: DefaultArticleList = {
|
|||
content_spacing: 10, // 内容间距
|
||||
article_spacing: 10, // 文章间距
|
||||
article_height: 155, // 文章高度
|
||||
content_img_width: undefined,
|
||||
content_img_height: undefined,
|
||||
content_img_width: 110,
|
||||
content_img_height: 83,
|
||||
interval_time: 3, //滚动时间
|
||||
is_roll: 1, // 是否轮播
|
||||
rolling_fashion: 'translation', // 滚动方式 translation 平移 cut-screen 切屏
|
||||
|
|
|
|||
|
|
@ -389,8 +389,8 @@ const defaultArticleTabs: DefaultArticleTabs = {
|
|||
content_spacing: 10, // 内容间距
|
||||
article_spacing: 10, // 文章间距
|
||||
article_height: 155, // 文章高度
|
||||
content_img_width: undefined,
|
||||
content_img_height: undefined,
|
||||
content_img_width: 110,
|
||||
content_img_height: 83,
|
||||
interval_time: 3, //滚动时间
|
||||
is_roll: 1, // 是否轮播
|
||||
rolling_fashion: 'translation', // 滚动方式 translation 平移 cut-screen 切屏
|
||||
|
|
|
|||
|
|
@ -200,8 +200,8 @@ const defaultProductList: DefaultProductList = {
|
|||
content_spacing: 10,
|
||||
// 商品高度
|
||||
content_outer_height: 232,
|
||||
content_img_width: undefined,
|
||||
content_img_height: undefined,
|
||||
content_img_width: 110,
|
||||
content_img_height: 120,
|
||||
// 是否滚动
|
||||
is_roll: '1',
|
||||
interval_time: 3,
|
||||
|
|
|
|||
|
|
@ -398,8 +398,8 @@ const defaultProductList: DefaultProductList = {
|
|||
// 商品高度
|
||||
content_outer_height: 232,
|
||||
// 商品图片宽度和高度, 为了确保历史数据显示正常,这里设置为undefined
|
||||
content_img_width: undefined,
|
||||
content_img_height: undefined,
|
||||
content_img_width: 110,
|
||||
content_img_height: 120,
|
||||
// 轮播处理
|
||||
is_roll: '1',
|
||||
interval_time: 3,
|
||||
|
|
|
|||
|
|
@ -879,4 +879,73 @@ export function formatDate(format: string = 'YYYY-MM-DD HH:mm:ss'): string {
|
|||
.replace('HH', hours)
|
||||
.replace('mm', minutes)
|
||||
.replace('ss', seconds);
|
||||
}
|
||||
|
||||
type Location = {
|
||||
x: number;
|
||||
y: number;
|
||||
}
|
||||
type DataFollow = {
|
||||
id: string;
|
||||
type: string;
|
||||
}
|
||||
export const new_location_handle = (old_location: Location, data_follow: DataFollow, location: Location) => {
|
||||
let new_x = old_location.x;
|
||||
let new_y = old_location.y;
|
||||
const { x, y } = location;
|
||||
// 如果是跟随的模版,根据选中的内容 x或者y不变
|
||||
if (data_follow.id != '') {
|
||||
if (data_follow.type == 'left') {
|
||||
if (old_location.x !== x) {
|
||||
ElMessage.info('当前组件已经左跟随其他组件,x轴不允许修改');
|
||||
}
|
||||
new_y = y;
|
||||
} else if (data_follow.type == 'top') {
|
||||
if (old_location.y !== y) {
|
||||
ElMessage.info('当前组件已经上跟随其他组件,y轴不允许修改');
|
||||
}
|
||||
new_x = x;
|
||||
}
|
||||
} else {
|
||||
new_x = x;
|
||||
new_y = y;
|
||||
}
|
||||
return { new_x, new_y }
|
||||
}
|
||||
|
||||
/**
|
||||
* 自定义数据处理函数
|
||||
* 该函数用于处理组件数据,根据旧组件的ID更新新组件的位置
|
||||
* @param data 组件数据数组
|
||||
* @param old_id 旧组件的ID
|
||||
* @param new_val 新组件的值,包含位置信息
|
||||
* @param com_width 组件宽度
|
||||
* @param com_height 组件高度
|
||||
* @returns 返回更新后的新组件数据数组
|
||||
*/
|
||||
export const diy_data_handle = (data: any, old_id: string, new_val: any, com_width: number, com_height: number): any => {
|
||||
// 遍历每个组件项
|
||||
data.forEach((item: any) => {
|
||||
// 解构获取组件跟随的配置信息,如果没有则使用默认值
|
||||
const { id = '', type = 'left', spacing = 0 } = item?.com_data?.data_follow || { id: '', type: 'left', spacing: 0 };
|
||||
// 判断当前组件是否被其他组件跟随
|
||||
if (old_id == id && id !== '') {
|
||||
// 根据新组件的位置和尺寸计算新的跟随位置
|
||||
const new_location_x = new_val.x + com_width + spacing;
|
||||
const new_location_y = new_val.y + com_height + spacing;
|
||||
// 根据跟随类型更新组件位置
|
||||
if (type =='left') {
|
||||
// 更新组件的横向位置
|
||||
item.location.x = new_location_x;
|
||||
item.location.record_x = new_location_x;
|
||||
} else if (type =='top') {
|
||||
// 更新组件的纵向位置
|
||||
item.location.y = new_location_y;
|
||||
item.location.record_y = new_location_y;
|
||||
item.location.staging_y = new_location_y;
|
||||
}
|
||||
}
|
||||
});
|
||||
// 返回更新后的组件数据数组
|
||||
return data;
|
||||
}
|
||||
Loading…
Reference in New Issue