新增选项卡轮播设置

v1.0.0
于肖磊 2024-09-24 14:10:45 +08:00
parent 65303f836d
commit 901b50cdfc
14 changed files with 405 additions and 22 deletions

View File

@ -1,6 +1,6 @@
<template>
<div class="img-outer re oh flex-row" :style="com_style">
<icon :name="form.icon_class" :color="form.icon_color" :size="form.icon_size"></icon>
<icon :name="form.icon_class" :color="form.icon_color" :size="form.icon_size + ''"></icon>
</div>
</template>
<script setup lang="ts">

View File

@ -46,6 +46,10 @@
<template v-else-if="item.key == 'tabs'">
<model-tabs :key="item.com_data" :value="item.com_data"></model-tabs>
</template>
<!-- 选项卡 -->
<template v-else-if="item.key == 'tabs-carousel'">
<model-tabs-carousel :key="item.com_data" :value="item.com_data"></model-tabs-carousel>
</template>
<!-- 商品列表 -->
<template v-else-if="item.key == 'goods-list'">
<model-goods-list :key="item.com_data" :value="item.com_data"></model-goods-list>

View File

@ -79,18 +79,17 @@ const props = defineProps({
type: Object,
default: () => {
return {};
},
},
},
isCommon: {
type: Boolean,
default: true,
},
});
//
const state = reactive({
form: props.value.content,
new_style: props.value.style,
});
// 使toRefs
const { form, new_style } = toRefs(state);
const form = computed(() => props.value.content);
const new_style = computed(() => props.value.style);
//
const style_container = computed(() => common_styles_computer(new_style.value.common_style));
const style_container = computed(() => props.isCommon ? common_styles_computer(new_style.value.common_style) : '');
const autoplay = ref<boolean | object>(false)
//
const img_style = computed(() => radius_computer(new_style.value) );

View File

@ -1,6 +1,6 @@
<template>
<div class="auxiliary-line common-content-height">
<el-form :model="form" label-width="70">
<el-form :model="form" label-width="60">
<card-container>
<div class="mb-12">展示设置</div>
<el-form-item label="样式设置">

View File

@ -76,8 +76,10 @@
</card-container>
</template>
</el-form>
<div class="divider-line"></div>
<common-styles :value="form.common_style" @update:value="common_styles_update" />
<template v-if="isCommon">
<div class="divider-line"></div>
<common-styles :value="form.common_style" @update:value="common_styles_update" />
</template>
</div>
</template>
<script setup lang="ts">
@ -91,6 +93,10 @@ const props = defineProps({
content: {
type: Object,
default: () => {},
},
isCommon: {
type: Boolean,
default: true
}
});

View File

@ -0,0 +1,29 @@
<template>
<div class="flex-col oh" :style="style">
<tabs-view ref="tabs" :value="tabs_list" :is-tabs="true"></tabs-view>
<model-carousel :value="value" :is-common="false"></model-carousel>
</div>
</template>
<script setup lang="ts">
import { common_styles_computer } from '@/utils';
import { cloneDeep } from 'lodash';
const props = defineProps({
value: {
type: Object,
default: () => {
return {};
},
},
});
const tabs_list = ref(props.value);
watch(props.value, (val) => {
let new_data = cloneDeep(val);
const { home_data } = new_data.content;
new_data.content.tabs_list = [home_data, ...new_data.content.tabs_list];
tabs_list.value = new_data;
}, { immediate: true, deep: true });
const style = computed(() => `${common_styles_computer(props.value.style.common_style)};gap:${props.value.style.data_spacing}px`);
</script>
<style lang="scss" scoped></style>

View File

@ -0,0 +1,50 @@
<template>
<div class="common-content-height">
<el-tabs v-model="tabs_name" class="content-tabs">
<el-tab-pane label="选项卡" name="tabs">
<model-tabs-content :value="form" :tab-style="styles"></model-tabs-content>
</el-tab-pane>
<el-tab-pane label="轮播" name="carousel">
<model-carousel-content :value="form"></model-carousel-content>
</el-tab-pane>
</el-tabs>
</div>
</template>
<script setup lang="ts">
const props = defineProps({
value: {
type: Object,
default: () => {},
},
tabCarouselStyle: {
type: Object,
default: () => ({}),
},
});
const state = reactive({
form: props.value,
styles: props.tabCarouselStyle,
});
const { form, styles } = toRefs(state);
const tabs_name = ref('tabs');
</script>
<style lang="scss" scoped>
:deep(.el-tabs.content-tabs) {
.el-tabs__header.is-top {
background: #fff;
margin: 0;
padding-top: 2rem;
}
.el-tabs__item.is-top {
padding: 0;
align-items: center;
width: 10rem;
font-size: 1.4rem;
}
.el-tabs__active-bar{
width: 100%;
}
}
</style>

View File

@ -0,0 +1,24 @@
<template>
<div class="setting-content">
<template v-if="type == '1'">
<model-tabs-carousel-content :value="value.content" :tab-style="value.style"></model-tabs-carousel-content>
</template>
<template v-if="type == '2'">
<model-tabs-carousel-styles :value="value.style" :content="value.content"></model-tabs-carousel-styles>
</template>
</div>
</template>
<script setup lang="ts">
const props = defineProps({
type: {
type: String,
default: '1',
},
value: {
type: Object,
default: () => ({}),
},
});
</script>
<style lang="scss" scoped>
</style>

View File

@ -0,0 +1,66 @@
<template>
<div class="w">
<el-tabs v-model="tabs_name" class="content-tabs">
<el-tab-pane label="选项卡" name="tabs">
<model-tabs-styles :value="form" :is-common="false"></model-tabs-styles>
</el-tab-pane>
<el-tab-pane label="轮播" name="carousel">
<model-carousel-styles :value="form" :content="new_content" :is-common="false"></model-carousel-styles>
</el-tab-pane>
<el-tab-pane label="公共" name="common">
<card-container>
<div class="mb-12">基础样式</div>
<el-form :model="form" label-width="74">
<el-form-item label="数据间距">
<slider v-model="form.data_spacing" :max="100"></slider>
</el-form-item>
</el-form>
</card-container>
<div class="divider-line"></div>
<common-styles :value="form.common_style" :is-floating-up="false" @update:value="common_styles_update" />
</el-tab-pane>
</el-tabs>
</div>
</template>
<script setup lang="ts">
const props = defineProps({
value: {
type: Object,
default: () => {},
},
content: {
type: Object,
default: () => {},
}
});
const state = reactive({
form: props.value,
new_content: props.content,
});
const tabs_name = ref('tabs');
// 使toRefs
const { form, new_content } = toRefs(state);
const common_styles_update = (val: Object) => {
form.value.common_style = val;
};
</script>
<style lang="scss" scoped>
:deep(.el-tabs.content-tabs) {
.el-tabs__header.is-top {
background: #fff;
margin: 0;
padding-top: 2rem;
}
.el-tabs__item.is-top {
padding: 0;
align-items: center;
width: 10rem;
font-size: 1.4rem;
}
.el-tabs__active-bar{
width: 100%;
}
}
</style>

View File

@ -30,8 +30,10 @@
</el-form-item>
</card-container>
</el-form>
<div class="divider-line"></div>
<common-styles :value="form.common_style" :is-floating-up="false" @update:value="common_styles_update" />
<template v-if="isCommon">
<div class="divider-line"></div>
<common-styles :value="form.common_style" :is-floating-up="false" @update:value="common_styles_update" />
</template>
</div>
</template>
<script setup lang="ts">
@ -39,6 +41,10 @@ const props = defineProps({
value: {
type: Object,
default: () => {},
},
isCommon: {
type: Boolean,
default: true
}
});

View File

@ -0,0 +1,185 @@
import { get_math } from '@/utils';
import defaultCommon from './index';
interface tabs_page {
id: string;
title: string;
desc: string;
data_type: string;
classify: object;
micro_page: string;
micro_page_list: object;
category_list: object;
}
interface carousel_list {
carousel_img: uploadList[];
carousel_video: uploadList[];
carousel_link: object;
video_title: string;
}
interface defaultTabs {
content: {
tabs_theme: string;
tabs_top_up: string;
home_data: tabs_page;
tabs_list: tabs_page[];
carousel_type: string;
carousel_list: carousel_list[];
img_fit: string,
is_roll: string;
interval_time: number;
};
style: {
tabs_checked: color_list[];
tabs_direction: string;
tabs_weight_checked: string;
tabs_size_checked: number;
tabs_color_checked: string;
tabs_weight: string;
tabs_size: number;
tabs_color: string;
tabs_spacing: number;
more_icon_class: string;
more_icon_color: string;
more_icon_size: number;
data_spacing: number;
radius: number;
radius_top_left: number;
radius_top_right: number;
radius_bottom_left: number;
radius_bottom_right: number;
is_show: string;
height: number,
image_spacing: number,
indicator_style: string;
indicator_location: string;
indicator_size: number;
indicator_bottom: number;
indicator_radius: radiusStyle;
video_is_show: string;
video_type: string;
video_radius: radiusStyle;
video_padding: paddingStyle;
video_img: uploadList[];
video_icon_class: string;
video_icon_color: string;
video_location: string;
video_bottom: number;
video_title_color: string;
video_title_size: number;
video_color_list: color_list[];
video_direction: string;
actived_color: string;
color: string;
common_style: object;
};
}
const defaultTabs: defaultTabs = {
content: {
tabs_theme: '0',
tabs_top_up: '1',
home_data: { id: get_math(), title: '首页', desc: '简介', data_type: '0', classify: {}, micro_page: '', micro_page_list: {}, category_list: {} },
tabs_list: [
{ id: get_math(), title: '热门推荐', desc: '简介', data_type: '0', classify: {}, micro_page: '', micro_page_list: {}, category_list: {} },
{ id: get_math(), title: '测试一', desc: '简介', data_type: '0', classify: {}, micro_page: '', micro_page_list: {}, category_list: {} },
{ id: get_math(), title: '测试二', desc: '简介', data_type: '0', classify: {}, micro_page: '', micro_page_list: {}, category_list: {} },
],
carousel_type: 'inherit',
img_fit: 'contain',
is_roll: '1',
interval_time: 2,
carousel_list: [
{
carousel_img: [],
carousel_video: [],
carousel_link: {},
video_title: '视频名称'
},
{
carousel_img: [],
carousel_video: [],
carousel_link: {},
video_title: '视频名称'
},
{
carousel_img: [],
carousel_video: [],
carousel_link: {},
video_title: '视频名称'
}
]
},
style: {
tabs_checked: [
{ color: '#FF2222', color_percentage: undefined },
{ color: '#FF9898', color_percentage: undefined },
],
tabs_direction: '90deg',
tabs_weight_checked: '500',
tabs_size_checked: 14,
tabs_color_checked: 'rgba(51,51,51,1)',
tabs_weight: '500',
tabs_size: 14,
tabs_color: 'rgba(51,51,51,1)',
tabs_spacing: 20,
more_icon_class: 'fenlei-more',
more_icon_color: '#000',
more_icon_size: 14,
data_spacing: 10,
radius: 0,
radius_top_left: 0,
radius_top_right: 0,
radius_bottom_left: 0,
radius_bottom_right: 0,
is_show: '1',
height: 300,
image_spacing: 10,
indicator_style: 'dot',
indicator_location: 'center',
indicator_size: 5,
indicator_bottom: 6,
indicator_radius: {
radius: 4,
radius_top_left: 4,
radius_top_right: 4,
radius_bottom_left: 4,
radius_bottom_right: 4,
},
video_is_show: '1',
video_type: 'icon',
video_radius: {
radius: 20,
radius_top_left: 20,
radius_top_right: 20,
radius_bottom_left: 20,
radius_bottom_right: 20,
},
video_padding: {
padding: 0,
padding_top: 3,
padding_bottom: 3,
padding_left: 6,
padding_right: 12,
},
video_img: [],
video_icon_class: '',
video_icon_color: '#ff6868',
video_location: 'center',
video_bottom: 20,
video_title_color: '#666',
video_title_size: 12,
video_color_list: [{ color: '#F0F0F0', color_percentage: undefined }],
video_direction: '180deg',
actived_color: '#2A94FF',
color: '#DDDDDD',
common_style: {
...defaultCommon,
padding: 10,
padding_top: 10,
padding_bottom: 10,
padding_left: 10,
padding_right: 10,
},
},
};
export default defaultTabs;

View File

@ -21,7 +21,8 @@ import defaultHotZone from './default/hot-zone';
import defaultCustom from './default/custom';
import defaultDataMagic from './default/data-magic';
import defaultCoupon from './default/coupon';
import defaultSeckill from './default/seckill'
import defaultSeckill from './default/seckill';
import defaultTabsCarousel from './default/tabs-carousel';
// 系统设置
interface DefaultSettings {
@ -49,6 +50,7 @@ interface DefaultSettings {
custom: object;
coupon: object;
seckill: object;
tabs_carousel: object;
}
const defaultSettings: DefaultSettings = {
@ -76,6 +78,7 @@ const defaultSettings: DefaultSettings = {
custom: defaultCustom,
coupon: defaultCoupon,
seckill: defaultSeckill,
tabs_carousel: defaultTabsCarousel,
};
export default defaultSettings;

View File

@ -6,8 +6,8 @@
<el-collapse-item v-if="com.data.length > 0" :key="i" :title="com.name" :name="com.key">
<VueDraggable v-model="com.data" :animation="500" ghost-class="ghost" handle=".is-drag" :group="{ name: 'people', pull: 'clone', put: false }" class="component flex-row flex-wrap" :clone="clone_item_com_data" :sort="false" :force-fallback="true">
<template v-for="item in com.data" :key="item.key">
<el-tooltip effect="dark" :show-after="200" :hide-after="200" content="该组件只可以点击添加, 并且只能添加一次" placement="top" :disabled="item.key != 'tabs'">
<div :class="['item', {'is-drag': item.key != 'tabs' }]" @click.stop="draggable_click(item)">
<el-tooltip effect="dark" :show-after="200" :hide-after="200" content="该组件只可以点击添加, 并且只能添加一次" placement="top" :disabled="!['tabs', 'tabs-carousel'].includes(item.key)">
<div :class="['item', {'is-drag': !['tabs', 'tabs-carousel'].includes(item.key) }]" @click.stop="draggable_click(item)">
<div class="main-border siderbar-hidden main-show tc">释放鼠标将组件添加到此处</div>
<div class="siderbar-show main-hidden flex-col jc-c align-c gap-4">
<img class="img radius-xs" :src="url_computer(item.key)" />
@ -207,7 +207,8 @@ const url_computer = (name: string) => {
const show_model_border = ref(true);
// tabs
const draggable_click = (item: componentsData) => {
if (item.key == 'tabs' && isEmpty(tabs_data.value)) {
const type_data = ['tabs', 'tabs-carousel'];
if (type_data.includes(item.key) && isEmpty(tabs_data.value)) {
// tabs
tabs_data.value.push({
name: item.name,
@ -215,10 +216,16 @@ const draggable_click = (item: componentsData) => {
is_enable: '1',
src: '',
id: get_math(),
key: 'tabs',
com_data: cloneDeep(defaultSettings.tabs),
key: item.key,
com_data: cloneDeep((defaultSettings as any)[item.key.replace(/-/g, '_')]),
});
set_tabs_event(true);
} else if (type_data.includes(item.key) && !isEmpty(tabs_data.value)) {
if (tabs_data.value[0].key == item.key) {
ElMessage.error('该组件只可以添加一次');
} else if (tabs_data.value[0].key != item.key) {
ElMessage.error('选项卡轮播不能与选项卡同时存在');
}
}
}
//
@ -388,7 +395,7 @@ const scroll = () => {
const scrollY = activeCard.value.offsetTop;
if (scrollTop.value) {
//
scrollTop.value.scrollTo({ top: scrollY - 200, behavior: 'smooth' });
scrollTop.value.scrollTo({ top: scrollY - 100, behavior: 'smooth' });
}
}
//

View File

@ -50,6 +50,10 @@
<template v-else-if="value.key == 'tabs'">
<model-tabs-setting :type="radio" :value="value.com_data"></model-tabs-setting>
</template>
<!-- 选项卡轮播 -->
<template v-else-if="value.key == 'tabs-carousel'">
<model-tabs-carousel-setting :type="radio" :value="value.com_data"></model-tabs-carousel-setting>
</template>
<!-- 商品列表 -->
<template v-else-if="value.key == 'goods-list'">
<model-goods-list-setting :type="radio" :value="value.com_data"></model-goods-list-setting>