|
|
@@ -1,809 +0,0 @@
|
|
|
-<template>
|
|
|
- <el-scrollbar height="calc(100vh - 130px)">
|
|
|
- <el-form label-position="top" class="h-full">
|
|
|
- <SplitterCollapse>
|
|
|
- <SplitterCollapseItem title="组件属性" class="flex-none">
|
|
|
- <el-collapse v-model="activeNames" class="p-10px">
|
|
|
- <el-scrollbar
|
|
|
- :height="
|
|
|
- data.type && LvglWidgets[data.type].config.props && data.type != 'page'
|
|
|
- ? 'calc(100vh - 280px)'
|
|
|
- : ''
|
|
|
- "
|
|
|
- >
|
|
|
- <template
|
|
|
- v-for="prop in data.type && LvglWidgets[data.type].config.props"
|
|
|
- :key="prop.field"
|
|
|
- >
|
|
|
- <!-- 判断是否为 group 类型 -->
|
|
|
- <template v-if="prop.valueType === 'group'">
|
|
|
- <el-collapse-item :title="prop.label" :name="prop.label">
|
|
|
- <div
|
|
|
- v-for="child in prop.children"
|
|
|
- :key="child.field"
|
|
|
- style="flex: 0 0 calc(50% - 5px)"
|
|
|
- >
|
|
|
- <el-form-item :label="child.label" class="flex w-full">
|
|
|
- <input-number
|
|
|
- v-if="child.valueType === 'number'"
|
|
|
- v-model="data.props[child.field]"
|
|
|
- :min="0"
|
|
|
- :placeholder="child.componentProps.placeholder"
|
|
|
- :readonly="child.componentProps.readOnly"
|
|
|
- :disabled="child.componentProps.disabled"
|
|
|
- style="width: 100%"
|
|
|
- :step="0.1"
|
|
|
- />
|
|
|
- <el-input
|
|
|
- v-if="child.valueType === 'text' && child.field === 'name'"
|
|
|
- v-model="data[child.field]"
|
|
|
- :placeholder="child.componentProps.placeholder"
|
|
|
- :readonly="child.componentProps.readOnly"
|
|
|
- :disabled="child.componentProps.disabled"
|
|
|
- />
|
|
|
- <el-input
|
|
|
- v-if="child.valueType === 'text' && child.field !== 'name'"
|
|
|
- v-model="data.props[child.field]"
|
|
|
- :placeholder="child.componentProps.placeholder"
|
|
|
- :readonly="child.componentProps.readOnly"
|
|
|
- :disabled="child.componentProps.disabled"
|
|
|
- />
|
|
|
- <el-select
|
|
|
- v-if="child.valueType === 'select'"
|
|
|
- v-model="data.props[child.field]"
|
|
|
- :placeholder="child.componentProps.placeholder"
|
|
|
- :readonly="child.componentProps.readOnly"
|
|
|
- :disabled="child.componentProps.disabled"
|
|
|
- >
|
|
|
- <el-option
|
|
|
- v-for="select in child.componentProps.options"
|
|
|
- :key="select.value"
|
|
|
- :label="select.label"
|
|
|
- :value="select.value"
|
|
|
- />
|
|
|
- </el-select>
|
|
|
- <!-- <div class="chart-container">
|
|
|
- <div class="chart-placeholder">xxx</div>
|
|
|
- </div> -->
|
|
|
- </el-form-item>
|
|
|
- </div>
|
|
|
- </el-collapse-item>
|
|
|
- </template>
|
|
|
-
|
|
|
- <!-- 多选平铺 -->
|
|
|
- <template
|
|
|
- v-else-if="
|
|
|
- prop.valueType === 'checkbox' &&
|
|
|
- ['addFlags', 'removeFlags'].includes(prop.field)
|
|
|
- "
|
|
|
- >
|
|
|
- <el-collapse-item :title="prop.label" :name="prop.label">
|
|
|
- <div class="flex flex-wrap gap-10px mb-10px">
|
|
|
- <div
|
|
|
- v-for="addFlags in prop.componentProps?.options"
|
|
|
- :key="addFlags.value"
|
|
|
- :class="[
|
|
|
- 'bg-#333333',
|
|
|
- 'h-[30px]',
|
|
|
- 'rounded-[5px]',
|
|
|
- 'line-height-[30px]',
|
|
|
- 'text-center',
|
|
|
- 'cursor-pointer',
|
|
|
- { 'bg-[var(--accent-blue)]': isActive(prop, addFlags) }
|
|
|
- ]"
|
|
|
- style="flex: 0 0 calc(50% - 5px)"
|
|
|
- @click="handleClick(prop, addFlags)"
|
|
|
- >
|
|
|
- {{ addFlags.label }}
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- </el-collapse-item>
|
|
|
- </template>
|
|
|
-
|
|
|
- <!-- 非 group 类型的字段 -->
|
|
|
- <template v-else>
|
|
|
- <el-form-item :label="prop.label">
|
|
|
- <!-- 文本类型字段 -->
|
|
|
- <el-input
|
|
|
- v-if="prop.valueType === 'text' && prop.field === 'name'"
|
|
|
- v-model="data[prop.field]"
|
|
|
- :placeholder="prop.componentProps?.placeholder"
|
|
|
- />
|
|
|
- <el-input
|
|
|
- v-if="prop.valueType === 'text' && prop.field !== 'name'"
|
|
|
- v-model="data.props[prop.field]"
|
|
|
- :placeholder="prop.componentProps?.placeholder"
|
|
|
- />
|
|
|
- <!-- 数字类型字段 -->
|
|
|
- <input-number
|
|
|
- v-if="prop.valueType === 'number'"
|
|
|
- v-model="data.props[prop.field]"
|
|
|
- style="width: 100%"
|
|
|
- :min="0"
|
|
|
- :step="0.1"
|
|
|
- />
|
|
|
- <!-- 下拉类型字段 -->
|
|
|
- <el-select
|
|
|
- v-if="prop.valueType === 'select'"
|
|
|
- v-model="data.props[prop.field]"
|
|
|
- :placeholder="prop.componentProps?.placeholder"
|
|
|
- :readonly="prop.componentProps?.readOnly"
|
|
|
- :disabled="prop.componentProps?.disabled"
|
|
|
- >
|
|
|
- <el-option
|
|
|
- v-for="select in prop.componentProps?.options"
|
|
|
- :key="select.value"
|
|
|
- :label="select.label"
|
|
|
- :value="select.value"
|
|
|
- />
|
|
|
- </el-select>
|
|
|
- <!-- <div class="chart-container">
|
|
|
- <div class="chart-placeholder"></div>
|
|
|
- </div> -->
|
|
|
- </el-form-item>
|
|
|
- </template>
|
|
|
- </template>
|
|
|
- </el-scrollbar>
|
|
|
- </el-collapse>
|
|
|
- </SplitterCollapseItem>
|
|
|
-
|
|
|
- <!-- -->
|
|
|
-
|
|
|
- <SplitterCollapseItem title="样式配置" class="flex-none">
|
|
|
- <el-collapse v-model="activeNames" class="p-10px">
|
|
|
- <el-scrollbar
|
|
|
- :height="
|
|
|
- data.type && LvglWidgets[data.type].config.styles && data.type != 'page'
|
|
|
- ? 'calc(100vh - 280px)'
|
|
|
- : ''
|
|
|
- "
|
|
|
- >
|
|
|
- <template
|
|
|
- v-for="prop in data.type && LvglWidgets[data.type].config.styles"
|
|
|
- :key="prop.field"
|
|
|
- >
|
|
|
- <el-form-item v-if="prop.field === 'part'" :label="prop.label" class="flex w-full">
|
|
|
- <div class="flex flex-1 justify-between items-center gap-10px">
|
|
|
- <!-- 模块 -->
|
|
|
- <el-select v-model="moduleValue" @change="handlePartChange">
|
|
|
- <el-option
|
|
|
- v-for="part in LvglWidgets[data.type].parts"
|
|
|
- :key="part.name"
|
|
|
- :label="part.name"
|
|
|
- :value="part.name"
|
|
|
- />
|
|
|
- </el-select>
|
|
|
-
|
|
|
- <!-- 状态 -->
|
|
|
- <el-select v-model="stateValue" @change="handleStateChange">
|
|
|
- <el-option
|
|
|
- v-for="state in getStateList(moduleValue)"
|
|
|
- :key="state"
|
|
|
- :label="state"
|
|
|
- :value="state"
|
|
|
- />
|
|
|
- </el-select>
|
|
|
- <!-- 控制区域 -->
|
|
|
- <el-icon style="width: 60px" class="cursor-pointer" @click="handleVisibleStyle"
|
|
|
- ><View
|
|
|
- /></el-icon>
|
|
|
- </div>
|
|
|
- </el-form-item>
|
|
|
- </template>
|
|
|
- <!-- 样式配置区域 -->
|
|
|
- <template v-if="visibleStyle">
|
|
|
- <template
|
|
|
- v-for="prop in data.type && LvglWidgets[data.type].config.styles"
|
|
|
- :key="prop.field"
|
|
|
- >
|
|
|
- <!-- 固定依赖 -->
|
|
|
- <el-form-item
|
|
|
- v-if="prop.field !== 'part'"
|
|
|
- :label="prop.label"
|
|
|
- class="flex w-full"
|
|
|
- >
|
|
|
- <!-- 背景颜色 -->
|
|
|
- <template v-if="prop.field === 'background'">
|
|
|
- <template
|
|
|
- v-if="data.style?.[styleIndex]?.[prop.field]?.hasOwnProperty('color')"
|
|
|
- >
|
|
|
- <div class="flex [flex-direction:column] flex-1">
|
|
|
- <div class="flex flex-1">
|
|
|
- <el-color-picker
|
|
|
- v-model="data.style[styleIndex][prop.field].color"
|
|
|
- :show-alpha="true"
|
|
|
- :predefine="predefineColors"
|
|
|
- />
|
|
|
- <div class="ml-10px">
|
|
|
- {{ data.style[styleIndex][prop.field].color }}
|
|
|
- </div>
|
|
|
- </div>
|
|
|
-
|
|
|
- <template
|
|
|
- v-if="data.style?.[styleIndex]?.[prop.field]?.hasOwnProperty('image')"
|
|
|
- >
|
|
|
- <div class="flex flex-1 mt-10px">
|
|
|
- <div class="w-32px h-32px bg-#cccc mr-10px"></div>
|
|
|
- <el-color-picker
|
|
|
- v-model="data.style[styleIndex][prop.field].image.color"
|
|
|
- :show-alpha="true"
|
|
|
- :predefine="predefineColors"
|
|
|
- />
|
|
|
- <div class="ml-10px">
|
|
|
- {{ data.style[styleIndex][prop.field].image.color }}
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- </template>
|
|
|
- </div>
|
|
|
- </template>
|
|
|
- </template>
|
|
|
-
|
|
|
- <!-- 字体 -->
|
|
|
- <div v-if="prop.field === 'text'" class="w-full">
|
|
|
- <div class="flex flex-1 gap-10px mb-10px">
|
|
|
- <el-color-picker
|
|
|
- v-model="data.style[styleIndex][prop.field].color"
|
|
|
- :show-alpha="true"
|
|
|
- :predefine="predefineColors"
|
|
|
- />
|
|
|
- <input-number
|
|
|
- v-model="data.style[styleIndex][prop.field].size"
|
|
|
- :min="0"
|
|
|
- placeholder="字体大小"
|
|
|
- class="flex-1"
|
|
|
- />
|
|
|
- </div>
|
|
|
- <div class="flex flex-1 gap-10px mb-10px">
|
|
|
- <el-select
|
|
|
- v-model="data.style[styleIndex][prop.field].weight"
|
|
|
- placeholder="字体加粗"
|
|
|
- >
|
|
|
- <el-option
|
|
|
- v-for="weight in textWeight"
|
|
|
- :key="weight.value"
|
|
|
- :label="weight.label"
|
|
|
- :value="weight.value"
|
|
|
- />
|
|
|
- </el-select>
|
|
|
- <el-select v-model="data.style[styleIndex][prop.field].family"></el-select>
|
|
|
- </div>
|
|
|
- <el-select
|
|
|
- v-model="data.style[styleIndex][prop.field].align"
|
|
|
- placeholder="对齐方式"
|
|
|
- >
|
|
|
- <el-option
|
|
|
- v-for="align in textAlign"
|
|
|
- :key="align.value"
|
|
|
- :label="align.label"
|
|
|
- :value="align.value"
|
|
|
- />
|
|
|
- </el-select>
|
|
|
- </div>
|
|
|
-
|
|
|
- <!-- 边框 -->
|
|
|
- <div v-if="prop.field === 'border'" class="w-full">
|
|
|
- <div class="flex flex-1 gap-10px mb-10px">
|
|
|
- <input-number
|
|
|
- v-model="data.style[styleIndex][prop.field].width"
|
|
|
- placeholder="边框大小"
|
|
|
- class="flex-1"
|
|
|
- :min="0"
|
|
|
- />
|
|
|
- <el-color-picker
|
|
|
- v-model="data.style[styleIndex][prop.field].color"
|
|
|
- :show-alpha="true"
|
|
|
- :predefine="predefineColors"
|
|
|
- />
|
|
|
- </div>
|
|
|
- <div class="flex flex-1 gap-10px">
|
|
|
- <el-select
|
|
|
- v-model="data.style[styleIndex][prop.field].side"
|
|
|
- multiple
|
|
|
- collapse-tags
|
|
|
- class="flex-1"
|
|
|
- >
|
|
|
- <el-option
|
|
|
- v-for="sides in borderSides"
|
|
|
- :key="sides.value"
|
|
|
- :label="sides.label"
|
|
|
- :value="sides.value"
|
|
|
- />
|
|
|
- </el-select>
|
|
|
- <input-number
|
|
|
- v-model="data.style[styleIndex][prop.field].radius"
|
|
|
- placeholder="圆角大小"
|
|
|
- class="flex-1"
|
|
|
- :min="0"
|
|
|
- />
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- <!-- 阴影 -->
|
|
|
- <div v-if="prop.field === 'shadow'" class="w-full">
|
|
|
- <el-color-picker
|
|
|
- v-model="data.style[styleIndex][prop.field].color"
|
|
|
- :show-alpha="true"
|
|
|
- :predefine="predefineColors"
|
|
|
- class="mb-10px"
|
|
|
- />
|
|
|
- <div class="flex flex-1 gap-10px mb-10px">
|
|
|
- <input-number
|
|
|
- v-model="data.style[styleIndex][prop.field].x"
|
|
|
- placeholder="水平偏移"
|
|
|
- class="flex-1"
|
|
|
- :min="0"
|
|
|
- />
|
|
|
- <input-number
|
|
|
- v-model="data.style[styleIndex][prop.field].y"
|
|
|
- placeholder="垂直偏移"
|
|
|
- class="flex-1"
|
|
|
- :min="0"
|
|
|
- />
|
|
|
- </div>
|
|
|
- <div class="flex flex-1 gap-10px">
|
|
|
- <input-number
|
|
|
- v-model="data.style[styleIndex][prop.field].width"
|
|
|
- placeholder="模糊半径"
|
|
|
- class="flex-1"
|
|
|
- :min="0"
|
|
|
- />
|
|
|
-
|
|
|
- <input-number
|
|
|
- v-model="data.style[styleIndex][prop.field].spread"
|
|
|
- placeholder="阴影扩展半径"
|
|
|
- class="flex-1"
|
|
|
- :min="0"
|
|
|
- />
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- <!-- 内边距 -->
|
|
|
- <div v-if="prop.field === 'padding'" class="w-full">
|
|
|
- <div class="flex flex-1 gap-10px mb-10px">
|
|
|
- <input-number
|
|
|
- v-model="data.style[styleIndex][prop.field].top"
|
|
|
- placeholder="内部上边距"
|
|
|
- class="flex-1"
|
|
|
- :min="0"
|
|
|
- />
|
|
|
- <input-number
|
|
|
- v-model="data.style[styleIndex][prop.field].right"
|
|
|
- placeholder="内部右边距"
|
|
|
- class="flex-1"
|
|
|
- :min="0"
|
|
|
- />
|
|
|
- </div>
|
|
|
- <div class="flex flex-1 gap-10px">
|
|
|
- <input-number
|
|
|
- v-model="data.style[styleIndex][prop.field].bottom"
|
|
|
- placeholder="内部下边距"
|
|
|
- class="flex-1"
|
|
|
- :min="0"
|
|
|
- />
|
|
|
-
|
|
|
- <input-number
|
|
|
- v-model="data.style[styleIndex][prop.field].left"
|
|
|
- placeholder="内部左边距"
|
|
|
- class="flex-1"
|
|
|
- :min="0"
|
|
|
- />
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- <!-- 间距 -->
|
|
|
- <div v-if="prop.field === 'gap'" class="w-full flex flex-1 gap-10px">
|
|
|
- <input-number
|
|
|
- v-model="data.style[styleIndex][prop.field].row"
|
|
|
- placeholder="横向"
|
|
|
- class="flex-1"
|
|
|
- :min="0"
|
|
|
- />
|
|
|
-
|
|
|
- <input-number
|
|
|
- v-model="data.style[styleIndex][prop.field].column"
|
|
|
- placeholder="纵向"
|
|
|
- class="flex-1"
|
|
|
- :min="0"
|
|
|
- />
|
|
|
- </div>
|
|
|
- </el-form-item>
|
|
|
-
|
|
|
- <!-- 动态显示依赖项 -->
|
|
|
- <template v-if="prop.valueType === 'dependency'">
|
|
|
- <el-form-item
|
|
|
- v-for="dependency in getDynamicFields(prop)"
|
|
|
- :key="dependency.field"
|
|
|
- :label="dependency.label"
|
|
|
- >
|
|
|
- <!-- 背景颜色 -->
|
|
|
- <template v-if="dependency.field === 'background'">
|
|
|
- <template
|
|
|
- v-if="
|
|
|
- data.style?.[styleIndex]?.[dependency.field]?.hasOwnProperty('color')
|
|
|
- "
|
|
|
- >
|
|
|
- <div class="flex [flex-direction:column] flex-1">
|
|
|
- <div class="flex flex-1">
|
|
|
- <el-color-picker
|
|
|
- v-model="data.style[styleIndex][dependency.field].color"
|
|
|
- :show-alpha="true"
|
|
|
- :predefine="predefineColors"
|
|
|
- />
|
|
|
- <div class="ml-10px">
|
|
|
- {{ data.style[styleIndex][dependency.field].color }}
|
|
|
- </div>
|
|
|
- </div>
|
|
|
-
|
|
|
- <template
|
|
|
- v-if="
|
|
|
- data.style?.[styleIndex]?.[dependency.field]?.hasOwnProperty(
|
|
|
- 'image'
|
|
|
- )
|
|
|
- "
|
|
|
- >
|
|
|
- <div class="flex flex-1 mt-10px">
|
|
|
- <div class="w-32px h-32px bg-#cccc mr-10px"></div>
|
|
|
- <el-color-picker
|
|
|
- v-model="data.style[styleIndex][dependency.field].image.color"
|
|
|
- :show-alpha="true"
|
|
|
- :predefine="predefineColors"
|
|
|
- />
|
|
|
- <div class="ml-10px">
|
|
|
- {{ data.style[styleIndex][dependency.field].image.color }}
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- </template>
|
|
|
- </div>
|
|
|
- </template>
|
|
|
- </template>
|
|
|
-
|
|
|
- <!-- 字体 -->
|
|
|
- <div v-if="dependency.field === 'text'" class="w-full">
|
|
|
- <div class="flex flex-1 gap-10px mb-10px">
|
|
|
- <el-color-picker
|
|
|
- v-model="data.style[styleIndex][dependency.field].color"
|
|
|
- :show-alpha="true"
|
|
|
- :predefine="predefineColors"
|
|
|
- />
|
|
|
- <input-number
|
|
|
- v-model="data.style[styleIndex][dependency.field].size"
|
|
|
- :min="0"
|
|
|
- placeholder="字体大小"
|
|
|
- class="flex-1"
|
|
|
- />
|
|
|
- </div>
|
|
|
- <div class="flex flex-1 gap-10px mb-10px">
|
|
|
- <el-select
|
|
|
- v-model="data.style[styleIndex][dependency.field].weight"
|
|
|
- placeholder="字体加粗"
|
|
|
- >
|
|
|
- <el-option
|
|
|
- v-for="weight in textWeight"
|
|
|
- :key="weight.value"
|
|
|
- :label="weight.label"
|
|
|
- :value="weight.value"
|
|
|
- />
|
|
|
- </el-select>
|
|
|
- <el-select
|
|
|
- v-model="data.style[styleIndex][dependency.field].family"
|
|
|
- ></el-select>
|
|
|
- </div>
|
|
|
- <el-select
|
|
|
- v-model="data.style[styleIndex][dependency.field].align"
|
|
|
- placeholder="对齐方式"
|
|
|
- >
|
|
|
- <el-option
|
|
|
- v-for="align in textAlign"
|
|
|
- :key="align.value"
|
|
|
- :label="align.label"
|
|
|
- :value="align.value"
|
|
|
- />
|
|
|
- </el-select>
|
|
|
- </div>
|
|
|
-
|
|
|
- <!-- 边框 -->
|
|
|
- <div v-if="dependency.field === 'border'" class="w-full">
|
|
|
- <div class="flex flex-1 gap-10px mb-10px">
|
|
|
- <input-number
|
|
|
- v-model="data.style[styleIndex][dependency.field].width"
|
|
|
- placeholder="边框大小"
|
|
|
- class="flex-1"
|
|
|
- :min="0"
|
|
|
- />
|
|
|
- <el-color-picker
|
|
|
- v-model="data.style[styleIndex][dependency.field].color"
|
|
|
- :show-alpha="true"
|
|
|
- :predefine="predefineColors"
|
|
|
- />
|
|
|
- </div>
|
|
|
- <div class="flex flex-1 gap-10px">
|
|
|
- <el-select
|
|
|
- v-model="data.style[styleIndex][dependency.field].side"
|
|
|
- multiple
|
|
|
- collapse-tags
|
|
|
- class="flex-1"
|
|
|
- >
|
|
|
- <el-option
|
|
|
- v-for="sides in borderSides"
|
|
|
- :key="sides.value"
|
|
|
- :label="sides.label"
|
|
|
- :value="sides.value"
|
|
|
- />
|
|
|
- </el-select>
|
|
|
- <input-number
|
|
|
- v-model="data.style[styleIndex][dependency.field].radius"
|
|
|
- placeholder="圆角大小"
|
|
|
- class="flex-1"
|
|
|
- :min="0"
|
|
|
- />
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- <!-- 阴影 -->
|
|
|
- <div v-if="dependency.field === 'shadow'" class="w-full">
|
|
|
- <el-color-picker
|
|
|
- v-model="data.style[styleIndex][dependency.field].color"
|
|
|
- :show-alpha="true"
|
|
|
- :predefine="predefineColors"
|
|
|
- class="mb-10px"
|
|
|
- />
|
|
|
- <div class="flex flex-1 gap-10px mb-10px">
|
|
|
- <input-number
|
|
|
- v-model="data.style[styleIndex][dependency.field].x"
|
|
|
- placeholder="水平偏移"
|
|
|
- class="flex-1"
|
|
|
- :min="0"
|
|
|
- />
|
|
|
- <input-number
|
|
|
- v-model="data.style[styleIndex][dependency.field].y"
|
|
|
- placeholder="垂直偏移"
|
|
|
- class="flex-1"
|
|
|
- :min="0"
|
|
|
- />
|
|
|
- </div>
|
|
|
- <div class="flex flex-1 gap-10px">
|
|
|
- <input-number
|
|
|
- v-model="data.style[styleIndex][dependency.field].width"
|
|
|
- placeholder="模糊半径"
|
|
|
- class="flex-1"
|
|
|
- :min="0"
|
|
|
- />
|
|
|
-
|
|
|
- <input-number
|
|
|
- v-model="data.style[styleIndex][dependency.field].spread"
|
|
|
- placeholder="阴影扩展半径"
|
|
|
- class="flex-1"
|
|
|
- :min="0"
|
|
|
- />
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- <!-- 内边距 -->
|
|
|
- <div v-if="dependency.field === 'padding'" class="w-full">
|
|
|
- <div class="flex flex-1 gap-10px mb-10px">
|
|
|
- <input-number
|
|
|
- v-model="data.style[styleIndex][dependency.field].top"
|
|
|
- placeholder="内部上边距"
|
|
|
- class="flex-1"
|
|
|
- :min="0"
|
|
|
- />
|
|
|
- <input-number
|
|
|
- v-model="data.style[styleIndex][dependency.field].right"
|
|
|
- placeholder="内部右边距"
|
|
|
- class="flex-1"
|
|
|
- :min="0"
|
|
|
- />
|
|
|
- </div>
|
|
|
- <div class="flex flex-1 gap-10px">
|
|
|
- <input-number
|
|
|
- v-model="data.style[styleIndex][dependency.field].bottom"
|
|
|
- placeholder="内部下边距"
|
|
|
- class="flex-1"
|
|
|
- :min="0"
|
|
|
- />
|
|
|
-
|
|
|
- <input-number
|
|
|
- v-model="data.style[styleIndex][dependency.field].left"
|
|
|
- placeholder="内部左边距"
|
|
|
- class="flex-1"
|
|
|
- :min="0"
|
|
|
- />
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- <!-- 间距 -->
|
|
|
- <div v-if="dependency.field === 'gap'" class="w-full flex flex-1 gap-10px">
|
|
|
- <input-number
|
|
|
- v-model="data.style[styleIndex][dependency.field].row"
|
|
|
- placeholder="横向"
|
|
|
- class="flex-1"
|
|
|
- :min="0"
|
|
|
- />
|
|
|
-
|
|
|
- <input-number
|
|
|
- v-model="data.style[styleIndex][dependency.field].column"
|
|
|
- placeholder="纵向"
|
|
|
- class="flex-1"
|
|
|
- :min="0"
|
|
|
- />
|
|
|
- </div>
|
|
|
- </el-form-item>
|
|
|
- </template>
|
|
|
- </template>
|
|
|
- </template>
|
|
|
- </el-scrollbar>
|
|
|
- </el-collapse>
|
|
|
- </SplitterCollapseItem>
|
|
|
- </SplitterCollapse>
|
|
|
- </el-form>
|
|
|
- </el-scrollbar>
|
|
|
-</template>
|
|
|
-
|
|
|
-<script setup lang="ts">
|
|
|
-import { ref, watch, computed } from 'vue'
|
|
|
-import type { Page } from '@/types/page'
|
|
|
-import LvglWidgets from '@/lvgl-widgets'
|
|
|
-import { View } from '@element-plus/icons-vue'
|
|
|
-import { textAlign, textWeight, borderSides } from '@/constants'
|
|
|
-import { SplitterCollapse, SplitterCollapseItem } from '@/components/SplitterCollapse'
|
|
|
-
|
|
|
-interface Emits {
|
|
|
- (e: 'update:selected', val: Page['props']): void
|
|
|
-}
|
|
|
-const props = defineProps<{
|
|
|
- selected?: Page['props']
|
|
|
-}>()
|
|
|
-const emit = defineEmits<Emits>()
|
|
|
-const data = ref<Page['props']>(props.selected || ({} as Page['props']))
|
|
|
-watch(data, (val) => emit('update:selected', val))
|
|
|
-
|
|
|
-watch(
|
|
|
- () => props.selected,
|
|
|
- (value) => {
|
|
|
- if (value) {
|
|
|
- moduleValue.value = LvglWidgets[data.value.type]?.parts[0].name || 'main'
|
|
|
- stateValue.value = LvglWidgets[data.value.type]?.parts[0].stateList[0] || 'default'
|
|
|
- data.value = value || ({} as Page['props'])
|
|
|
- }
|
|
|
- }
|
|
|
-)
|
|
|
-
|
|
|
-const activeNames = ref<string[]>(['基本属性', '位置/大小', '添加标识', '删除标识'])
|
|
|
-
|
|
|
-const moduleValue = ref('')
|
|
|
-const stateValue = ref('')
|
|
|
-const visibleStyle = ref(true)
|
|
|
-const predefineColors = [
|
|
|
- '#ff4500',
|
|
|
- '#ff8c00',
|
|
|
- '#ffd700',
|
|
|
- '#90ee90',
|
|
|
- '#00ced1',
|
|
|
- '#1e90ff',
|
|
|
- '#c71585',
|
|
|
- 'rgba(255, 69, 0, 0.68)',
|
|
|
- 'rgb(255, 120, 0)',
|
|
|
- 'hsv(51, 100, 98)',
|
|
|
- 'hsva(120, 40, 94, 0.5)',
|
|
|
- 'hsl(181, 100%, 37%)',
|
|
|
- 'hsla(209, 100%, 56%, 0.73)',
|
|
|
- '#c7158577'
|
|
|
-]
|
|
|
-
|
|
|
-const loadStyle = async (name) => {
|
|
|
- try {
|
|
|
- const Json = await import(`@/lvgl-widgets/${name}/style.json`)
|
|
|
- return Json.default
|
|
|
- } catch (error) {
|
|
|
- console.error(error)
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-const styleIndex = computed(() => {
|
|
|
- return data.value.style.findIndex(
|
|
|
- (item) => item.part.name === moduleValue.value && item.part.state === stateValue.value
|
|
|
- )
|
|
|
-})
|
|
|
-
|
|
|
-const getStateList = (partName) => {
|
|
|
- const part = LvglWidgets[data.value.type].parts.find((item) => item.name === partName)
|
|
|
- return part ? part.stateList : []
|
|
|
-}
|
|
|
-
|
|
|
-const isActive = (prop, addFlags) => {
|
|
|
- return data.value.props[prop.field].some((item) => item.value === addFlags.value)
|
|
|
-}
|
|
|
-
|
|
|
-const handleClick = (prop, addFlags) => {
|
|
|
- const selectedOptions = data.value.props[prop.field]
|
|
|
-
|
|
|
- const index = selectedOptions.findIndex((item) => item.value === addFlags.value)
|
|
|
-
|
|
|
- if (index !== -1) {
|
|
|
- selectedOptions.splice(index, 1)
|
|
|
- } else {
|
|
|
- selectedOptions.push(addFlags)
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-const handleVisibleStyle = () => {
|
|
|
- visibleStyle.value = !visibleStyle.value
|
|
|
-}
|
|
|
-
|
|
|
-const handlePartChange = (targetPartName) => {
|
|
|
- const existingPart = data.value.style.find((item) => item.part.name === targetPartName)
|
|
|
- if (!existingPart) {
|
|
|
- loadStyle(data.value.props.name).then((loadedStyle) => {
|
|
|
- if (loadedStyle) {
|
|
|
- const targetPart = loadedStyle.part.find((item) => item.partName === moduleValue.value)
|
|
|
-
|
|
|
- if (targetPart) {
|
|
|
- const targetStyle = targetPart.state.find((item) => item.state === targetPart)
|
|
|
-
|
|
|
- if (targetStyle) {
|
|
|
- targetStyle.style.part = {
|
|
|
- name: moduleValue.value,
|
|
|
- state: targetPart
|
|
|
- }
|
|
|
- data.value.style.push(targetStyle.style)
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- })
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-const handleStateChange = (targetState) => {
|
|
|
- const existingState = data.value.style.find((item) => item.part.state === targetState)
|
|
|
-
|
|
|
- if (!existingState) {
|
|
|
- loadStyle(data.value.props.name).then((loadedStyle) => {
|
|
|
- if (loadedStyle) {
|
|
|
- const targetPart = loadedStyle.part.find((item) => item.partName === moduleValue.value)
|
|
|
-
|
|
|
- if (targetPart) {
|
|
|
- const targetStyle = targetPart.state.find((item) => item.state === targetState)
|
|
|
-
|
|
|
- if (targetStyle) {
|
|
|
- targetStyle.style.part = {
|
|
|
- name: moduleValue.value,
|
|
|
- state: targetState
|
|
|
- }
|
|
|
- data.value.style.push(targetStyle.style)
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- })
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-const getDynamicFields = (prop) => {
|
|
|
- if (prop.valueType === 'dependency' && prop.name && Array.isArray(prop.name)) {
|
|
|
- const fieldValues = prop.name.reduce((values, field) => {
|
|
|
- if (field === 'part') {
|
|
|
- values[field] = moduleValue.value
|
|
|
- } else {
|
|
|
- values[field] = data.value[field] || data.value.props[field]
|
|
|
- }
|
|
|
-
|
|
|
- return values
|
|
|
- }, {})
|
|
|
-
|
|
|
- return prop.dependency(fieldValues) || []
|
|
|
- }
|
|
|
- return []
|
|
|
-}
|
|
|
-</script>
|
|
|
-
|
|
|
-<style scoped lang="less">
|
|
|
-:deep(.el-collapse-item__header) {
|
|
|
- padding-right: 0px;
|
|
|
-}
|
|
|
-:deep(.el-collapse-item__content) {
|
|
|
- padding-bottom: 0;
|
|
|
- display: flex;
|
|
|
- flex-wrap: wrap;
|
|
|
- gap: 0 10px;
|
|
|
-}
|
|
|
-
|
|
|
-:deep(.el-scrollbar__view) {
|
|
|
- height: 100%;
|
|
|
-}
|
|
|
-:deep(.flex-none) {
|
|
|
- flex: none !important;
|
|
|
-}
|
|
|
-</style>
|