refactor(form): 抽离平台检测逻辑到共用mixin,统一多端表单配置处理
1. 新增form-platform-mixin.js集中管理平台判断、别名兼容和配置键获取逻辑 2. 移除ns-form和ns-newform组件内重复的平台相关代码 3. 统一替换rpx单位处理逻辑为$util.rpx,简化样式计算代码 4. 移除冗余的_resolveFontSize工具方法,复用现有工具能力
This commit is contained in:
@@ -280,8 +280,11 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import formPlatformMixin from '@/common/js/form-platform-mixin.js';
|
||||
|
||||
export default {
|
||||
name: 'ns-newform',
|
||||
mixins: [formPlatformMixin],
|
||||
props: {
|
||||
data: {
|
||||
type: Array,
|
||||
@@ -349,61 +352,7 @@ export default {
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
// 当前运行平台标识(与后端 formConfig.terminal 键名对齐:h5 / wechat / weapp / harmony)
|
||||
platform() {
|
||||
// 优先使用后端在 formConfig.terminal 中使用的键名
|
||||
// #ifdef H5
|
||||
return 'h5';
|
||||
// #endif
|
||||
// #ifdef MP-WEIXIN
|
||||
return 'weapp';
|
||||
// #endif
|
||||
// #ifdef MP-ALIPAY
|
||||
return 'mp-alipay';
|
||||
// #endif
|
||||
// #ifdef MP-BAIDU
|
||||
return 'mp-baidu';
|
||||
// #endif
|
||||
// #ifdef MP-TOUTIAO
|
||||
return 'mp-toutiao';
|
||||
// #endif
|
||||
// #ifdef APP-PLUS
|
||||
return 'app';
|
||||
// #endif
|
||||
// #ifdef MP-HARMONY
|
||||
return 'harmony';
|
||||
// #endif
|
||||
// #ifdef QUICKAPP-WEBVIEW
|
||||
return 'quickapp';
|
||||
// #endif
|
||||
return 'h5';
|
||||
},
|
||||
// 平台配置兼容层:后端键名(h5/wechat/weapp/harmony)→ 内部 platform 名
|
||||
platformAliases() {
|
||||
return {
|
||||
'h5': 'h5',
|
||||
'weapp': 'weapp',
|
||||
'mp-weixin': 'weapp',
|
||||
'wechat': 'wechat',
|
||||
'harmony': 'harmony',
|
||||
'app': 'app',
|
||||
'app-plus': 'app'
|
||||
};
|
||||
},
|
||||
// 当前平台的有效配置键集合(用于 config() 中查找 platformCfg)
|
||||
platformConfigKeys() {
|
||||
const cur = this.platform;
|
||||
const aliases = this.platformAliases;
|
||||
// 找出所有映射到当前平台的后端键名
|
||||
const keys = [];
|
||||
Object.keys(aliases).forEach(k => {
|
||||
if (aliases[k] === cur) keys.push(k);
|
||||
});
|
||||
// 加入当前平台名(兼容 formConfig[platform] 这种写法)
|
||||
if (keys.indexOf(cur) === -1) keys.push(cur);
|
||||
return keys;
|
||||
},
|
||||
// 合并配置:内置默认 < 全局 < 当前平台
|
||||
// 合并配置:内置默认 < 全局 < 当前平台
|
||||
config() {
|
||||
// 内置默认值(最低优先级)- 与后端 D:\projects\shop-projects\backend\src\app\component\view\form\js\design.js getDefaultFormData().formConfig 对齐
|
||||
const defaults = {
|
||||
@@ -455,9 +404,9 @@ export default {
|
||||
}
|
||||
let width;
|
||||
if (this.config.labelWidthMode === 'fixed') {
|
||||
width = `${this.config.labelFixedWidth}rpx`;
|
||||
width = this.$util.rpx(this.config.labelFixedWidth);
|
||||
} else {
|
||||
width = this.maxLabelWidth ? `${this.maxLabelWidth}rpx` : 'auto';
|
||||
width = this.maxLabelWidth ? this.$util.rpx(this.maxLabelWidth) : 'auto';
|
||||
}
|
||||
return {
|
||||
width: width
|
||||
@@ -470,30 +419,30 @@ export default {
|
||||
|
||||
return this.$util.objToStyle({
|
||||
// 仅保留左右内边距 = form-padding-x;上下由每行 row-padding-y 承担
|
||||
padding: `0 ${cfg.formPaddingX}rpx`,
|
||||
padding: `0 ${this.$util.rpx(cfg.formPaddingX)}`,
|
||||
background: cfg.formBgColor,
|
||||
// 通过 CSS 变量传递:与后端 design.css 的 :root 变量一一对应
|
||||
'--form-padding-x': `${cfg.formPaddingX}rpx`,
|
||||
'--banner-padding-x': `${cfg.bannerPaddingX}rpx`,
|
||||
'--tip-padding-x': `${cfg.tipPaddingX}rpx`,
|
||||
'--tip-font-size': `${cfg.tipFontSize}rpx`,
|
||||
'--form-padding-x': this.$util.rpx(cfg.formPaddingX),
|
||||
'--banner-padding-x': this.$util.rpx(cfg.bannerPaddingX),
|
||||
'--tip-padding-x': this.$util.rpx(cfg.tipPaddingX),
|
||||
'--tip-font-size': this.$util.rpx(cfg.tipFontSize),
|
||||
'--tip-color': cfg.tipColor,
|
||||
'--tip-bg-color': cfg.tipBgColor,
|
||||
'--row-padding-y': `${cfg.rowPaddingY}rpx`,
|
||||
'--row-min-height': `${cfg.rowMinHeight}rpx`,
|
||||
'--label-gap': `${cfg.labelGap}rpx`,
|
||||
'--row-padding-y': this.$util.rpx(cfg.rowPaddingY),
|
||||
'--row-min-height': this.$util.rpx(cfg.rowMinHeight),
|
||||
'--label-gap': this.$util.rpx(cfg.labelGap),
|
||||
'--form-bg-color': cfg.formBgColor,
|
||||
'--row-divider-color': cfg.rowDividerColor,
|
||||
'--input-height': `${cfg.inputHeight}rpx`,
|
||||
'--input-radius': `${cfg.inputRadius}rpx`,
|
||||
'--label-fixed-width': `${cfg.labelFixedWidth}rpx`,
|
||||
'--label-font-size': `${num(cfg.labelFontSize, 28)}rpx`,
|
||||
'--input-height': this.$util.rpx(cfg.inputHeight),
|
||||
'--input-radius': this.$util.rpx(cfg.inputRadius),
|
||||
'--label-fixed-width': this.$util.rpx(cfg.labelFixedWidth),
|
||||
'--label-font-size': this.$util.rpx(num(cfg.labelFontSize, 28)),
|
||||
'--label-color': cfg.labelColor,
|
||||
'--required-color': cfg.requiredColor,
|
||||
'--checked-color': cfg.checkedColor,
|
||||
'--submit-color': cfg.submitColor,
|
||||
'--submit-bg-color': cfg.submitBgColor,
|
||||
'--submit-margin-top': `${cfg.submitMarginTop || 0}rpx`,
|
||||
'--submit-margin-top': this.$util.rpx(cfg.submitMarginTop || 0),
|
||||
// 分割线显隐
|
||||
'--show-row-divider': cfg.showRowDivider === false ? '0' : '1'
|
||||
});
|
||||
@@ -501,7 +450,7 @@ export default {
|
||||
// 行间距样式:仅上下内边距,水平由外层 form-wrap 控制(与后端 form-gorup 对齐)
|
||||
rowWrapStyle() {
|
||||
return this.$util.objToStyle({
|
||||
padding: `${this.config.rowPaddingY}rpx 0`
|
||||
padding: `${this.$util.rpx(this.config.rowPaddingY)} 0`
|
||||
});
|
||||
},
|
||||
// 行容器 class:用于控制分割线显隐
|
||||
@@ -511,7 +460,7 @@ export default {
|
||||
// 行最小高度
|
||||
rowCellStyle() {
|
||||
return this.$util.objToStyle({
|
||||
'min-height': `${this.config.rowMinHeight}rpx`
|
||||
'min-height': this.$util.rpx(this.config.rowMinHeight)
|
||||
});
|
||||
},
|
||||
// 标签与输入框间距
|
||||
@@ -520,26 +469,21 @@ export default {
|
||||
return {};
|
||||
}
|
||||
return {
|
||||
'margin-right': `${this.config.labelGap}rpx`
|
||||
'margin-right': this.$util.rpx(this.config.labelGap)
|
||||
};
|
||||
},
|
||||
// 输入框样式(全局,未指定 item 时使用)
|
||||
inputStyle() {
|
||||
return this.$util.objToStyle({
|
||||
'min-height': `${this.config.inputHeight}rpx`,
|
||||
'border-radius': `${this.config.inputRadius}rpx`
|
||||
'min-height': this.$util.rpx(this.config.inputHeight),
|
||||
'border-radius': this.$util.rpx(this.config.inputRadius)
|
||||
});
|
||||
},
|
||||
labelStyle() {
|
||||
let style = {};
|
||||
let fontSize = this.config.labelFontSize;
|
||||
if (typeof fontSize === 'number') {
|
||||
fontSize = `${fontSize}rpx`;
|
||||
} else if (typeof fontSize === 'string' && !fontSize.endsWith('rpx') && !fontSize.endsWith('px')) {
|
||||
fontSize = `${fontSize}rpx`;
|
||||
}
|
||||
style.fontSize = fontSize;
|
||||
style.color = this.config.labelColor;
|
||||
const style = {
|
||||
fontSize: this.$util.rpx(this.config.labelFontSize),
|
||||
color: this.config.labelColor
|
||||
};
|
||||
return this.$util.objToStyle(style);
|
||||
},
|
||||
requiredColor() {
|
||||
@@ -559,21 +503,6 @@ export default {
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
// 处理 rpx 字号:与后端 label_font_size 字段语义对齐
|
||||
_resolveFontSize(value, fallback) {
|
||||
let v = value;
|
||||
if (v === '' || v === null || v === undefined) {
|
||||
v = fallback;
|
||||
}
|
||||
if (typeof v === 'number') {
|
||||
return `${v}rpx`;
|
||||
}
|
||||
if (typeof v === 'string') {
|
||||
if (v.endsWith('rpx') || v.endsWith('px')) return v;
|
||||
return `${v}rpx`;
|
||||
}
|
||||
return v;
|
||||
},
|
||||
// 预计算每项的样式(写到 item._labelStyle / item._boxAlignStyle),
|
||||
// 避免在模板里以方法形式调用:微信小程序 WXML 不支持 :style="getXxx(item)" 语法。
|
||||
// 触发时机:processFormData 末尾 / calculateMaxLabelWidth 末尾 / config 变化 / mode 变化。
|
||||
@@ -589,10 +518,7 @@ export default {
|
||||
|
||||
// item 级别 label 字号 / 颜色覆盖(与原 getItemLabelStyle 逻辑一致)
|
||||
if (itemValue.label_font_size !== undefined && itemValue.label_font_size !== null && itemValue.label_font_size !== '') {
|
||||
let fs = itemValue.label_font_size;
|
||||
if (typeof fs === 'number') fs = `${fs}rpx`;
|
||||
else if (typeof fs === 'string' && !fs.endsWith('rpx') && !fs.endsWith('px')) fs = `${fs}rpx`;
|
||||
style['--item-label-font-size'] = fs;
|
||||
style['--item-label-font-size'] = this.$util.rpx(itemValue.label_font_size);
|
||||
}
|
||||
if (itemValue.label_color) {
|
||||
style['--item-label-color'] = itemValue.label_color;
|
||||
|
||||
Reference in New Issue
Block a user