refactor(ns-newform.vue): 优化字段样式,支持组件独立的间距和内边距设置
This commit is contained in:
@@ -2,7 +2,7 @@
|
||||
<view class="form-wrap form-component" :style="formWrapStyle" >
|
||||
<view v-for="(item, index) in formData" :key="index">
|
||||
<!-- 文本输入框 -->
|
||||
<view v-if="item.controller == 'Text'" class="order-wrap" :class="rowWrapClass" :style="rowWrapStyle">
|
||||
<view v-if="item.controller == 'Text'" class="order-wrap" :class="rowWrapClass" :style="item._fieldWrapStyle">
|
||||
<view :class="['order-cell', { 'vertical-layout': mode === 'vertical' }]" :style="rowCellStyle">
|
||||
<view class="name" :style="item._labelStyle">
|
||||
<text class="required" :style="item._starStyle">{{ item.value.required ? '*' : '' }}</text>
|
||||
@@ -20,7 +20,7 @@
|
||||
</view>
|
||||
|
||||
<!-- 多行文本输入框 -->
|
||||
<view v-if="item.controller == 'Textarea'" class="order-wrap" :class="rowWrapClass" :style="rowWrapStyle">
|
||||
<view v-if="item.controller == 'Textarea'" class="order-wrap" :class="rowWrapClass" :style="item._fieldWrapStyle">
|
||||
<view :class="['order-cell', 'flex-box', 'textarea', { 'vertical-layout': mode === 'vertical' }]">
|
||||
<view class="name" :style="item._labelStyle">
|
||||
<text class="required" :style="item._starStyle">{{ item.value.required ? '*' : '' }}</text>
|
||||
@@ -43,7 +43,7 @@
|
||||
</view>
|
||||
|
||||
<!-- 下拉选择器 -->
|
||||
<view v-if="item.controller == 'Select'" class="order-wrap" :class="rowWrapClass" :style="rowWrapStyle">
|
||||
<view v-if="item.controller == 'Select'" class="order-wrap" :class="rowWrapClass" :style="item._fieldWrapStyle">
|
||||
<picker
|
||||
mode="selector"
|
||||
:range="item.value.options"
|
||||
@@ -64,7 +64,7 @@
|
||||
</view>
|
||||
|
||||
<!-- 复选框 -->
|
||||
<view v-if="item.controller == 'Checkbox'" class="order-wrap" :class="rowWrapClass" :style="rowWrapStyle">
|
||||
<view v-if="item.controller == 'Checkbox'" class="order-wrap" :class="rowWrapClass" :style="item._fieldWrapStyle">
|
||||
<view :class="['order-cell', { 'vertical-layout': mode === 'vertical' }]">
|
||||
<view class="name" :style="item._labelStyle">
|
||||
<text class="required" :style="item._starStyle">{{ item.value.required ? '*' : '' }}</text>
|
||||
@@ -93,7 +93,7 @@
|
||||
</view>
|
||||
|
||||
<!-- 单选框 -->
|
||||
<view v-if="item.controller == 'Radio'" class="order-wrap" :class="rowWrapClass" :style="rowWrapStyle">
|
||||
<view v-if="item.controller == 'Radio'" class="order-wrap" :class="rowWrapClass" :style="item._fieldWrapStyle">
|
||||
<view :class="['order-cell', { 'vertical-layout': mode === 'vertical' }]">
|
||||
<view class="name" :style="item._labelStyle">
|
||||
<text class="required" :style="item._starStyle">{{ item.value.required ? '*' : '' }}</text>
|
||||
@@ -122,7 +122,7 @@
|
||||
</view>
|
||||
|
||||
<!-- 图片上传 -->
|
||||
<view v-if="item.controller == 'Img'" class="order-wrap" :class="rowWrapClass" :style="rowWrapStyle">
|
||||
<view v-if="item.controller == 'Img'" class="order-wrap" :class="rowWrapClass" :style="item._fieldWrapStyle">
|
||||
<view :class="['order-cell', 'flex-box', { 'vertical-layout': mode === 'vertical' }]">
|
||||
<view class="name" :style="item._labelStyle">
|
||||
<text class="required" :style="item._starStyle">{{ item.value.required ? '*' : '' }}</text>
|
||||
@@ -141,7 +141,7 @@
|
||||
</view>
|
||||
|
||||
<!-- 日期选择器 -->
|
||||
<view v-if="item.controller == 'Date'" class="order-wrap" :class="rowWrapClass" :style="rowWrapStyle">
|
||||
<view v-if="item.controller == 'Date'" class="order-wrap" :class="rowWrapClass" :style="item._fieldWrapStyle">
|
||||
<view :class="['order-cell', { 'vertical-layout': mode === 'vertical' }]">
|
||||
<view class="name" :style="item._labelStyle">
|
||||
<text class="required" :style="item._starStyle">{{ item.value.required ? '*' : '' }}</text>
|
||||
@@ -163,7 +163,7 @@
|
||||
</view>
|
||||
|
||||
<!-- 日期范围选择器 -->
|
||||
<view v-if="item.controller == 'Datelimit'" class="order-wrap" :class="rowWrapClass" :style="rowWrapStyle">
|
||||
<view v-if="item.controller == 'Datelimit'" class="order-wrap" :class="rowWrapClass" :style="item._fieldWrapStyle">
|
||||
<view :class="['order-cell', 'flex-box', { 'vertical-layout': mode === 'vertical' }]">
|
||||
<view class="name" :style="item._labelStyle">
|
||||
<text class="required" :style="item._starStyle">{{ item.value.required ? '*' : '' }}</text>
|
||||
@@ -202,7 +202,7 @@
|
||||
</view>
|
||||
|
||||
<!-- 时间选择器 -->
|
||||
<view v-if="item.controller == 'Time'" class="order-wrap" :class="rowWrapClass" :style="rowWrapStyle">
|
||||
<view v-if="item.controller == 'Time'" class="order-wrap" :class="rowWrapClass" :style="item._fieldWrapStyle">
|
||||
<view :class="['order-cell', { 'vertical-layout': mode === 'vertical' }]">
|
||||
<view class="name" :style="item._labelStyle">
|
||||
<text class="required" :style="item._starStyle">{{ item.value.required ? '*' : '' }}</text>
|
||||
@@ -224,7 +224,7 @@
|
||||
</view>
|
||||
|
||||
<!-- 时间范围选择器 -->
|
||||
<view v-if="item.controller == 'Timelimit'" class="order-wrap" :class="rowWrapClass" :style="rowWrapStyle">
|
||||
<view v-if="item.controller == 'Timelimit'" class="order-wrap" :class="rowWrapClass" :style="item._fieldWrapStyle">
|
||||
<view :class="['order-cell', 'flex-box', { 'vertical-layout': mode === 'vertical' }]">
|
||||
<view class="name" :style="item._labelStyle">
|
||||
<text class="required" :style="item._starStyle">{{ item.value.required ? '*' : '' }}</text>
|
||||
@@ -263,7 +263,7 @@
|
||||
</view>
|
||||
|
||||
<!-- 城市选择器 -->
|
||||
<view v-if="item.controller == 'City'" class="order-wrap" :class="rowWrapClass" :style="rowWrapStyle">
|
||||
<view v-if="item.controller == 'City'" class="order-wrap" :class="rowWrapClass" :style="item._fieldWrapStyle">
|
||||
<view :class="['order-cell', { 'vertical-layout': mode === 'vertical' }]">
|
||||
<view class="name" :style="item._labelStyle">
|
||||
<text class="required" :style="item._starStyle">{{ item.value.required ? '*' : '' }}</text>
|
||||
@@ -503,12 +503,6 @@ export default {
|
||||
'--show-row-divider': cfg.showRowDivider === false ? '0' : '1'
|
||||
});
|
||||
},
|
||||
// 行间距样式:仅上下内边距,水平由外层 form-wrap 控制(与后端 form-gorup 对齐)
|
||||
rowWrapStyle() {
|
||||
return this.$util.objToStyle({
|
||||
padding: `${this.$util.rpx(this.config.rowPaddingY)} 0`
|
||||
});
|
||||
},
|
||||
// 行容器 class:用于控制分割线显隐
|
||||
rowWrapClass() {
|
||||
return this.config.showRowDivider === false ? 'order-wrap no-divider' : 'order-wrap';
|
||||
@@ -593,9 +587,41 @@ export default {
|
||||
|
||||
const widthStyle = this.nameWidthStyle || {};
|
||||
const nameMarginStyle = this.nameStyle || {};
|
||||
// 字段级间距(每个组件独立,互不影响):数值解析(''/null/undefined/非数字 → null = 未设置,跟随全局)
|
||||
const spNum = (x) => {
|
||||
if (x === undefined || x === null || x === '') return null;
|
||||
const n = parseFloat(x);
|
||||
return isNaN(n) ? null : n;
|
||||
};
|
||||
// 行容器基础上下内边距(原 rowWrapStyle 语义:全局行间距 rowPaddingY;左右恒 0)
|
||||
const rowPadY = this.$util.rpx(this.config.rowPaddingY);
|
||||
const clampRpx = (n, min, max) => this.$util.rpx(Math.max(min, Math.min(max, n)));
|
||||
|
||||
this.formData.forEach((item) => {
|
||||
const itemValue = (item && item.value) || {};
|
||||
|
||||
// ---- 字段级间距(每个组件独立):外边距直出(允许负值上移贴近相邻组件)----
|
||||
// clamp 与后端 fieldSpacingStyle 一致(margin -100..400 / padding 0..400 rpx)
|
||||
const mTop = spNum(itemValue.margin_top), mBottom = spNum(itemValue.margin_bottom),
|
||||
mLeft = spNum(itemValue.margin_left), mRight = spNum(itemValue.margin_right);
|
||||
const fieldMargin = {};
|
||||
if (mTop !== null) fieldMargin['margin-top'] = clampRpx(mTop, -100, 400);
|
||||
if (mBottom !== null) fieldMargin['margin-bottom'] = clampRpx(mBottom, -100, 400);
|
||||
if (mLeft !== null) fieldMargin['margin-left'] = clampRpx(mLeft, -100, 400);
|
||||
if (mRight !== null) fieldMargin['margin-right'] = clampRpx(mRight, -100, 400);
|
||||
const pTop = spNum(itemValue.padding_top), pBottom = spNum(itemValue.padding_bottom),
|
||||
pLeft = spNum(itemValue.padding_left), pRight = spNum(itemValue.padding_right);
|
||||
// 11 种输入控件行容器(.order-wrap,原 rowWrapStyle 承载层):
|
||||
// margin 直出;padding 覆盖对应边(未设置的边跟随全局:上下 rowPaddingY / 左右 0)
|
||||
if (item.controller != 'InfoCard') {
|
||||
const fieldWrapStyle = Object.assign({}, fieldMargin);
|
||||
fieldWrapStyle['padding-top'] = pTop !== null ? clampRpx(pTop, 0, 400) : rowPadY;
|
||||
fieldWrapStyle['padding-bottom'] = pBottom !== null ? clampRpx(pBottom, 0, 400) : rowPadY;
|
||||
fieldWrapStyle['padding-left'] = pLeft !== null ? clampRpx(pLeft, 0, 400) : '0';
|
||||
fieldWrapStyle['padding-right'] = pRight !== null ? clampRpx(pRight, 0, 400) : '0';
|
||||
this.$set(item, '_fieldWrapStyle', fieldWrapStyle);
|
||||
}
|
||||
|
||||
const style = Object.assign({}, widthStyle);
|
||||
|
||||
// item 级别 label 字号 / 颜色覆盖(与原 getItemLabelStyle 逻辑一致)
|
||||
@@ -662,6 +688,13 @@ export default {
|
||||
wrapStyle['border-radius'] = '6px';
|
||||
wrapStyle['padding'] = '8px 10px';
|
||||
}
|
||||
// 字段级间距(InfoCard 行容器即卡片本身,无全局行内边距):margin 直出;
|
||||
// padding 覆盖背景卡默认内边距的对应边(无 bg 时直接生效)
|
||||
Object.keys(fieldMargin).forEach((k) => { wrapStyle[k] = fieldMargin[k]; });
|
||||
if (pTop !== null) wrapStyle['padding-top'] = clampRpx(pTop, 0, 400);
|
||||
if (pBottom !== null) wrapStyle['padding-bottom'] = clampRpx(pBottom, 0, 400);
|
||||
if (pLeft !== null) wrapStyle['padding-left'] = clampRpx(pLeft, 0, 400);
|
||||
if (pRight !== null) wrapStyle['padding-right'] = clampRpx(pRight, 0, 400);
|
||||
this.$set(item, '_infoCardWrapStyle', wrapStyle);
|
||||
// 空白判定:去标签 + + 去空白后为空 → 不渲染富文本(与后台一致,避免空白块)
|
||||
const raw = itemValue.content == null ? '' : String(itemValue.content);
|
||||
|
||||
Reference in New Issue
Block a user