feat:【mall】diy editor 的 product-list 优化

This commit is contained in:
YunaiV
2025-11-01 12:02:08 +08:00
parent 43e758023a
commit 0741ae4b63
4 changed files with 42 additions and 60 deletions

View File

@@ -18,9 +18,8 @@ import {
} from 'element-plus'; } from 'element-plus';
import UploadImg from '#/components/upload/image-upload.vue'; import UploadImg from '#/components/upload/image-upload.vue';
import { SpuShowcase } from '#/views/mall/product/spu/components';
import { ColorInput } from '#/views/mall/promotion/components'; import { ColorInput } from '#/views/mall/promotion/components';
// TODO: 添加组件
// import SpuShowcase from '#/views/mall/product/spu/components/spu-showcase.vue';
import ComponentContainerProperty from '../../component-container-property.vue'; import ComponentContainerProperty from '../../component-container-property.vue';
@@ -38,7 +37,7 @@ const formData = useVModel(props, 'modelValue', emit);
<ComponentContainerProperty v-model="formData.style"> <ComponentContainerProperty v-model="formData.style">
<ElForm label-width="80px" :model="formData"> <ElForm label-width="80px" :model="formData">
<ElCard header="商品列表" class="property-group" shadow="never"> <ElCard header="商品列表" class="property-group" shadow="never">
<!-- <SpuShowcase v-model="formData.spuIds" /> --> <SpuShowcase v-model="formData.spuIds" />
</ElCard> </ElCard>
<ElCard header="商品样式" class="property-group" shadow="never"> <ElCard header="商品样式" class="property-group" shadow="never">
<ElFormItem label="布局" prop="type"> <ElFormItem label="布局" prop="type">

View File

@@ -2,42 +2,29 @@ import type { ComponentStyle, DiyComponent } from '../../../util';
/** 商品栏属性 */ /** 商品栏属性 */
export interface ProductListProperty { export interface ProductListProperty {
// 布局类型:双列 | 三列 | 水平滑动 layoutType: 'horizSwiper' | 'threeCol' | 'twoCol'; // 布局类型:双列 | 三列 | 水平滑动
layoutType: 'horizSwiper' | 'threeCol' | 'twoCol';
// 商品字段
fields: { fields: {
// 商品名称 name: ProductListFieldProperty; // 商品名称
name: ProductListFieldProperty; price: ProductListFieldProperty; // 商品价格
// 商品价格 }; // 商品字段
price: ProductListFieldProperty;
};
// 角标
badge: { badge: {
// 角标图片 imgUrl: string; // 角标图片
imgUrl: string; show: boolean; // 是否显示
// 是否显示 }; // 角标
show: boolean; borderRadiusTop: number; // 上圆角
}; borderRadiusBottom: number; // 下圆角
// 上圆角 space: number; // 间距
borderRadiusTop: number; spuIds: number[]; // 商品编号列表
// 下圆角 style: ComponentStyle; // 组件样式
borderRadiusBottom: number;
// 间距
space: number;
// 商品编号列表
spuIds: number[];
// 组件样式
style: ComponentStyle;
}
// 商品字段
export interface ProductListFieldProperty {
// 是否显示
show: boolean;
// 颜色
color: string;
} }
// 定义组件 /** 商品字段属性 */
export interface ProductListFieldProperty {
show: boolean; // 是否显示
color: string; // 颜色
}
/** 定义组件 */
export const component = { export const component = {
id: 'ProductList', id: 'ProductList',
name: '商品栏', name: '商品栏',

View File

@@ -13,10 +13,11 @@ import * as ProductSpuApi from '#/api/mall/product/spu';
/** 商品栏 */ /** 商品栏 */
defineOptions({ name: 'ProductList' }); defineOptions({ name: 'ProductList' });
// 定义属性
const props = defineProps<{ property: ProductListProperty }>(); const props = defineProps<{ property: ProductListProperty }>();
// 商品列表
const spuList = ref<MallSpuApi.Spu[]>([]); const spuList = ref<MallSpuApi.Spu[]>([]);
watch( watch(
() => props.property.spuIds, () => props.property.spuIds,
async () => { async () => {
@@ -27,19 +28,15 @@ watch(
deep: true, deep: true,
}, },
); );
// 手机宽度
const phoneWidth = ref(375); const phoneWidth = ref(375); // 手机宽度
// 容器 const containerRef = ref(); // 容器
const containerRef = ref(); const columns = ref(2); // 商品的列数
// 商品的列数 const scrollbarWidth = ref('100%'); // 滚动条宽度
const columns = ref(2); const imageSize = ref('0'); // 商品图大小
// 滚动条宽度 const gridTemplateColumns = ref(''); // 商品网络列数
const scrollbarWidth = ref('100%');
// 商品图大小 /** 计算布局参数 */
const imageSize = ref('0');
// 商品网络列数
const gridTemplateColumns = ref('');
// 计算布局参数
watch( watch(
() => [props.property, phoneWidth, spuList.value.length], () => [props.property, phoneWidth, spuList.value.length],
() => { () => {
@@ -69,8 +66,9 @@ watch(
}, },
{ immediate: true, deep: true }, { immediate: true, deep: true },
); );
/** 初始化 */
onMounted(() => { onMounted(() => {
// 提取手机宽度
phoneWidth.value = containerRef.value?.wrapRef?.offsetWidth || 375; phoneWidth.value = containerRef.value?.wrapRef?.offsetWidth || 375;
}); });
</script> </script>
@@ -146,5 +144,3 @@ onMounted(() => {
</div> </div>
</ElScrollbar> </ElScrollbar>
</template> </template>
<style scoped lang="scss"></style>

View File

@@ -6,6 +6,7 @@ import { IconifyIcon } from '@vben/icons';
import { useVModel } from '@vueuse/core'; import { useVModel } from '@vueuse/core';
import { import {
ElCard, ElCard,
ElCheckbox,
ElForm, ElForm,
ElFormItem, ElFormItem,
ElRadioButton, ElRadioButton,
@@ -16,17 +17,18 @@ import {
} from 'element-plus'; } from 'element-plus';
import UploadImg from '#/components/upload/image-upload.vue'; import UploadImg from '#/components/upload/image-upload.vue';
import { InputWithColor as ColorInput } from '#/views/mall/promotion/components'; import { SpuShowcase } from '#/views/mall/product/spu/components';
import { ColorInput } from '#/views/mall/promotion/components';
import ComponentContainerProperty from '../../component-container-property.vue'; import ComponentContainerProperty from '../../component-container-property.vue';
// TODO: 添加组件
// import SpuShowcase from '#/views/mall/product/spu/components/spu-showcase.vue';
// 商品栏属性面板 /** 商品栏属性面板 */
defineOptions({ name: 'ProductListProperty' }); defineOptions({ name: 'ProductListProperty' });
const props = defineProps<{ modelValue: ProductListProperty }>(); const props = defineProps<{ modelValue: ProductListProperty }>();
const emit = defineEmits(['update:modelValue']); const emit = defineEmits(['update:modelValue']);
const formData = useVModel(props, 'modelValue', emit); const formData = useVModel(props, 'modelValue', emit);
</script> </script>
@@ -34,7 +36,7 @@ const formData = useVModel(props, 'modelValue', emit);
<ComponentContainerProperty v-model="formData.style"> <ComponentContainerProperty v-model="formData.style">
<ElForm label-width="80px" :model="formData"> <ElForm label-width="80px" :model="formData">
<ElCard header="商品列表" class="property-group" shadow="never"> <ElCard header="商品列表" class="property-group" shadow="never">
<!-- <SpuShowcase v-model="formData.spuIds" /> --> <SpuShowcase v-model="formData.spuIds" />
</ElCard> </ElCard>
<ElCard header="商品样式" class="property-group" shadow="never"> <ElCard header="商品样式" class="property-group" shadow="never">
<ElFormItem label="布局" prop="type"> <ElFormItem label="布局" prop="type">
@@ -119,5 +121,3 @@ const formData = useVModel(props, 'modelValue', emit);
</ElForm> </ElForm>
</ComponentContainerProperty> </ComponentContainerProperty>
</template> </template>
<style scoped lang="scss"></style>