refactor(form): 抽离平台检测逻辑到共用mixin,统一多端表单配置处理
1. 新增form-platform-mixin.js集中管理平台判断、别名兼容和配置键获取逻辑 2. 移除ns-form和ns-newform组件内重复的平台相关代码 3. 统一替换rpx单位处理逻辑为$util.rpx,简化样式计算代码 4. 移除冗余的_resolveFontSize工具方法,复用现有工具能力
This commit is contained in:
105
common/js/form-platform-mixin.js
Normal file
105
common/js/form-platform-mixin.js
Normal file
@@ -0,0 +1,105 @@
|
|||||||
|
/**
|
||||||
|
* form-platform-mixin.js
|
||||||
|
*
|
||||||
|
* 表单组件共用的平台检测 mixin
|
||||||
|
*
|
||||||
|
* 集中维护 3 个 computed:
|
||||||
|
* - platform 当前运行平台 key(与后端 formConfig.terminal 键名对齐)
|
||||||
|
* - platformAliases 后端键名 → 内部 platform 名 兼容层
|
||||||
|
* - platformConfigKeys 当前平台的有效配置键集合(用于从 formConfig.terminal 查找)
|
||||||
|
*
|
||||||
|
* 消费方:
|
||||||
|
* - components/ns-form/ns-form.vue
|
||||||
|
* - components/ns-newform/ns-newform.vue
|
||||||
|
* - 任何需要按端读取 formConfig.terminal.{h5|weapp|harmony|app} 的表单组件
|
||||||
|
*
|
||||||
|
* 设计原则:
|
||||||
|
* 1. 单一真值:避免 ns-form / ns-newform 各自维护导致漂移
|
||||||
|
* 2. 纯 computed mixin:不依赖 props/data/methods,便于跨组件复用
|
||||||
|
* 3. 不依赖 util.js 等其它模块,避免循环依赖
|
||||||
|
* 4. 通过 mixins: [...] 引入,组件侧不再写平台判断代码
|
||||||
|
*
|
||||||
|
* 用法:
|
||||||
|
* import formPlatformMixin from '@/common/js/form-platform-mixin.js';
|
||||||
|
* export default {
|
||||||
|
* mixins: [formPlatformMixin],
|
||||||
|
* computed: {
|
||||||
|
* config() {
|
||||||
|
* const cur = this.platform;
|
||||||
|
* const keys = this.platformConfigKeys;
|
||||||
|
* // ...
|
||||||
|
* }
|
||||||
|
* }
|
||||||
|
* };
|
||||||
|
*/
|
||||||
|
|
||||||
|
export default {
|
||||||
|
computed: {
|
||||||
|
/**
|
||||||
|
* 当前运行平台标识(与后端 formConfig.terminal 键名对齐)
|
||||||
|
* 后端在 formConfig.terminal 下挂的差异化配置键:h5 / weapp / mp-harmony / app
|
||||||
|
* 这里返回的 key 必须与后端设计器输出的 terminal 字段名一致
|
||||||
|
*/
|
||||||
|
platform() {
|
||||||
|
// #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';
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* 后端键名 → 内部 platform 名 兼容层
|
||||||
|
* 不同后端序列化路径可能用 mp-weixin / wechat / mp-harmony 等不同的 key,
|
||||||
|
* 在这里统一映射到内部 platform 名,避免 config() 里到处写 if/else。
|
||||||
|
*/
|
||||||
|
platformAliases() {
|
||||||
|
return {
|
||||||
|
'h5': 'h5',
|
||||||
|
'weapp': 'weapp',
|
||||||
|
'mp-weixin': 'weapp',
|
||||||
|
'wechat': 'weapp',
|
||||||
|
'harmony': 'harmony',
|
||||||
|
'app': 'app',
|
||||||
|
'app-plus': 'app'
|
||||||
|
};
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* 当前平台的有效配置键集合
|
||||||
|
* 用于 config() 中查找 formConfig.terminal 下的平台差异化配置:
|
||||||
|
* - 后端格式:formConfig.terminal = { h5: {...}, weapp: {...}, harmony: {...} }
|
||||||
|
* - 旧式扁平:formConfig[platformKey] = { ... }
|
||||||
|
* 返回所有映射到当前 platform 的后端键名,方便两种结构都能命中。
|
||||||
|
*/
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
3921
common/js/util.js
3921
common/js/util.js
File diff suppressed because it is too large
Load Diff
@@ -223,8 +223,11 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
import formPlatformMixin from '@/common/js/form-platform-mixin.js';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'ns-form',
|
name: 'ns-form',
|
||||||
|
mixins: [formPlatformMixin],
|
||||||
props: {
|
props: {
|
||||||
data: {
|
data: {
|
||||||
type: Array,
|
type: Array,
|
||||||
@@ -262,57 +265,6 @@
|
|||||||
};
|
};
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
// 当前运行平台标识(与后端 formConfig.terminal 键名对齐)
|
|
||||||
platform() {
|
|
||||||
// #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';
|
|
||||||
},
|
|
||||||
// 后端键名 → 内部 platform 名 兼容层
|
|
||||||
platformAliases() {
|
|
||||||
return {
|
|
||||||
'h5': 'h5',
|
|
||||||
'weapp': 'weapp',
|
|
||||||
'mp-weixin': 'weapp',
|
|
||||||
'wechat': 'weapp',
|
|
||||||
'harmony': 'harmony',
|
|
||||||
'app': 'app',
|
|
||||||
'app-plus': 'app'
|
|
||||||
};
|
|
||||||
},
|
|
||||||
// 当前平台的有效配置键集合
|
|
||||||
platformConfigKeys() {
|
|
||||||
const cur = this.platform;
|
|
||||||
const aliases = this.platformAliases;
|
|
||||||
const keys = [];
|
|
||||||
Object.keys(aliases).forEach(k => {
|
|
||||||
if (aliases[k] === cur) keys.push(k);
|
|
||||||
});
|
|
||||||
if (keys.indexOf(cur) === -1) keys.push(cur);
|
|
||||||
return keys;
|
|
||||||
},
|
|
||||||
// 合并配置:内置默认 < 全局 formConfig < 当前平台 formConfig.terminal[platform]
|
// 合并配置:内置默认 < 全局 formConfig < 当前平台 formConfig.terminal[platform]
|
||||||
// 同时兼容 snake_case 与 camelCase 字段名
|
// 同时兼容 snake_case 与 camelCase 字段名
|
||||||
config() {
|
config() {
|
||||||
@@ -394,18 +346,20 @@
|
|||||||
formWrapStyle() {
|
formWrapStyle() {
|
||||||
const cfg = this.config;
|
const cfg = this.config;
|
||||||
const num = (v, fb) => (typeof v === 'number' ? v : parseInt(v) || fb);
|
const num = (v, fb) => (typeof v === 'number' ? v : parseInt(v) || fb);
|
||||||
|
// 后端 formConfig 一律以 rpx 传递;
|
||||||
|
// _rpx() 按端分支:H5 输出 'Npx'(uni.upx2px),其它端输出 'Nrpx'
|
||||||
return this.$util.objToStyle({
|
return this.$util.objToStyle({
|
||||||
padding: `0 ${cfg.formPaddingX}rpx`,
|
padding: `0 ${this.$util.rpx(cfg.formPaddingX)}`,
|
||||||
background: cfg.formBgColor,
|
background: cfg.formBgColor,
|
||||||
'--form-padding-x': `${cfg.formPaddingX}rpx`,
|
'--form-padding-x': this.$util.rpx(cfg.formPaddingX),
|
||||||
'--form-bg-color': cfg.formBgColor,
|
'--form-bg-color': cfg.formBgColor,
|
||||||
'--row-padding-y': `${cfg.rowPaddingY}rpx`,
|
'--row-padding-y': this.$util.rpx(cfg.rowPaddingY),
|
||||||
'--row-min-height': `${cfg.rowMinHeight}rpx`,
|
'--row-min-height': this.$util.rpx(cfg.rowMinHeight),
|
||||||
'--label-gap': `${cfg.labelGap}rpx`,
|
'--label-gap': this.$util.rpx(cfg.labelGap),
|
||||||
'--input-height': `${cfg.inputHeight}rpx`,
|
'--input-height': this.$util.rpx(cfg.inputHeight),
|
||||||
'--input-radius': `${cfg.inputRadius}rpx`,
|
'--input-radius': this.$util.rpx(cfg.inputRadius),
|
||||||
'--label-fixed-width': `${cfg.labelFixedWidth}rpx`,
|
'--label-fixed-width': this.$util.rpx(cfg.labelFixedWidth),
|
||||||
'--label-font-size': `${num(cfg.labelFontSize, 28)}rpx`,
|
'--label-font-size': this.$util.rpx(num(cfg.labelFontSize, 28)),
|
||||||
'--label-color': cfg.labelColor,
|
'--label-color': cfg.labelColor,
|
||||||
'--required-color': cfg.requiredColor,
|
'--required-color': cfg.requiredColor,
|
||||||
'--checked-color': cfg.checkedColor,
|
'--checked-color': cfg.checkedColor,
|
||||||
@@ -416,7 +370,7 @@
|
|||||||
},
|
},
|
||||||
rowWrapStyle() {
|
rowWrapStyle() {
|
||||||
return this.$util.objToStyle({
|
return this.$util.objToStyle({
|
||||||
padding: `${this.config.rowPaddingY}rpx 0`
|
padding: `${this.$util.rpx(this.config.rowPaddingY)} 0`
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
rowWrapClass() {
|
rowWrapClass() {
|
||||||
@@ -424,25 +378,25 @@
|
|||||||
},
|
},
|
||||||
rowCellStyle() {
|
rowCellStyle() {
|
||||||
return this.$util.objToStyle({
|
return this.$util.objToStyle({
|
||||||
'min-height': `${this.config.rowMinHeight}rpx`
|
'min-height': this.$util.rpx(this.config.rowMinHeight)
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
// 标签宽度:根据 labelWidthMode 决定;fixed 用 --label-fixed-width,auto 用 maxLabelWidth
|
// 标签宽度:根据 labelWidthMode 决定;fixed 用 --label-fixed-width,auto 用 maxLabelWidth
|
||||||
nameWidthStyle() {
|
nameWidthStyle() {
|
||||||
const cfg = this.config;
|
const cfg = this.config;
|
||||||
if (cfg.labelWidthMode === 'fixed') {
|
if (cfg.labelWidthMode === 'fixed') {
|
||||||
return { width: `${cfg.labelFixedWidth}rpx` };
|
return { width: this.$util.rpx(cfg.labelFixedWidth) };
|
||||||
}
|
}
|
||||||
return this.maxLabelWidth ? { width: `${this.maxLabelWidth}rpx` } : { width: 'auto' };
|
return this.maxLabelWidth ? { width: this.$util.rpx(this.maxLabelWidth) } : { width: 'auto' };
|
||||||
},
|
},
|
||||||
// 输入框样式(input / textarea 共用)
|
// 输入框样式(input / textarea 共用)
|
||||||
inputStyle() {
|
inputStyle() {
|
||||||
return this.$util.objToStyle({
|
return this.$util.objToStyle({
|
||||||
'min-height': `${this.config.inputHeight}rpx`,
|
'min-height': this.$util.rpx(this.config.inputHeight),
|
||||||
'border-radius': `${this.config.inputRadius}rpx`,
|
'border-radius': this.$util.rpx(this.config.inputRadius),
|
||||||
'font-size': `${this.config.labelFontSize}rpx`,
|
'font-size': this.$util.rpx(this.config.labelFontSize),
|
||||||
'color': this.config.labelColor,
|
'color': this.config.labelColor,
|
||||||
'line-height': `${this.config.inputHeight}rpx`
|
'line-height': this.$util.rpx(this.config.inputHeight)
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
// 必填星号颜色
|
// 必填星号颜色
|
||||||
@@ -609,24 +563,13 @@
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
// 计算最长 label 宽度(与后端 design.js calculateMaxLabelWidth 算法对齐)
|
// 计算最长 label 宽度(封装自 util.calculateMaxLabelWidth)
|
||||||
// 用于 labelWidthMode === 'auto' 时把 .name 的 width 撑开,避免长短 label 错位
|
// 用于 labelWidthMode === 'auto' 时把 .name 的 width 撑开,避免长短 label 错位
|
||||||
calculateMaxLabelWidth() {
|
calculateMaxLabelWidth() {
|
||||||
if (!this.formData || this.formData.length === 0) {
|
this.maxLabelWidth = this.$util.calculateMaxLabelWidth(
|
||||||
this.maxLabelWidth = 0;
|
this.formData,
|
||||||
return;
|
this.config.labelFontSize
|
||||||
}
|
);
|
||||||
const fontSize = parseInt(this.config.labelFontSize) || 28;
|
|
||||||
let maxChars = 0;
|
|
||||||
this.formData.forEach(item => {
|
|
||||||
if (!item.value || !item.value.title) return;
|
|
||||||
let len = (item.value.title || '').length;
|
|
||||||
if (item.value.required) len += 1;
|
|
||||||
if (len > maxChars) maxChars = len;
|
|
||||||
});
|
|
||||||
// 公式:chars * (fontSize/2) * 1.1 + 12,单位 px → 转 rpx(×2)
|
|
||||||
const widthPx = Math.max(40, maxChars * (fontSize / 2) * 1.1 + 12);
|
|
||||||
this.maxLabelWidth = Math.round(widthPx * 2);
|
|
||||||
},
|
},
|
||||||
verify() {
|
verify() {
|
||||||
let verify = true;
|
let verify = true;
|
||||||
@@ -917,7 +860,9 @@
|
|||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
/* CSS 自定义属性:默认值,与组件内 config.defaults 一一对应,
|
/* CSS 自定义属性:默认值,与组件内 config.defaults 一一对应,
|
||||||
formConfig 未传时作为兜底;运行时会被 formWrapStyle 注入的 inline style 覆盖 */
|
formConfig 未传时作为兜底;运行时会被 formWrapStyle 注入的 inline style 覆盖。
|
||||||
|
后端 formConfig 一律以 rpx 传递,前端按 rpx 写入;
|
||||||
|
仅 H5 端需要在 JS computed(formWrapStyle 等)里通过 _rpx() 转 px。 */
|
||||||
.form-wrap {
|
.form-wrap {
|
||||||
--form-padding-x: 0rpx;
|
--form-padding-x: 0rpx;
|
||||||
--form-bg-color: #ffffff;
|
--form-bg-color: #ffffff;
|
||||||
|
|||||||
@@ -280,8 +280,11 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
import formPlatformMixin from '@/common/js/form-platform-mixin.js';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'ns-newform',
|
name: 'ns-newform',
|
||||||
|
mixins: [formPlatformMixin],
|
||||||
props: {
|
props: {
|
||||||
data: {
|
data: {
|
||||||
type: Array,
|
type: Array,
|
||||||
@@ -349,61 +352,7 @@ export default {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
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() {
|
config() {
|
||||||
// 内置默认值(最低优先级)- 与后端 D:\projects\shop-projects\backend\src\app\component\view\form\js\design.js getDefaultFormData().formConfig 对齐
|
// 内置默认值(最低优先级)- 与后端 D:\projects\shop-projects\backend\src\app\component\view\form\js\design.js getDefaultFormData().formConfig 对齐
|
||||||
const defaults = {
|
const defaults = {
|
||||||
@@ -455,9 +404,9 @@ export default {
|
|||||||
}
|
}
|
||||||
let width;
|
let width;
|
||||||
if (this.config.labelWidthMode === 'fixed') {
|
if (this.config.labelWidthMode === 'fixed') {
|
||||||
width = `${this.config.labelFixedWidth}rpx`;
|
width = this.$util.rpx(this.config.labelFixedWidth);
|
||||||
} else {
|
} else {
|
||||||
width = this.maxLabelWidth ? `${this.maxLabelWidth}rpx` : 'auto';
|
width = this.maxLabelWidth ? this.$util.rpx(this.maxLabelWidth) : 'auto';
|
||||||
}
|
}
|
||||||
return {
|
return {
|
||||||
width: width
|
width: width
|
||||||
@@ -470,30 +419,30 @@ export default {
|
|||||||
|
|
||||||
return this.$util.objToStyle({
|
return this.$util.objToStyle({
|
||||||
// 仅保留左右内边距 = form-padding-x;上下由每行 row-padding-y 承担
|
// 仅保留左右内边距 = form-padding-x;上下由每行 row-padding-y 承担
|
||||||
padding: `0 ${cfg.formPaddingX}rpx`,
|
padding: `0 ${this.$util.rpx(cfg.formPaddingX)}`,
|
||||||
background: cfg.formBgColor,
|
background: cfg.formBgColor,
|
||||||
// 通过 CSS 变量传递:与后端 design.css 的 :root 变量一一对应
|
// 通过 CSS 变量传递:与后端 design.css 的 :root 变量一一对应
|
||||||
'--form-padding-x': `${cfg.formPaddingX}rpx`,
|
'--form-padding-x': this.$util.rpx(cfg.formPaddingX),
|
||||||
'--banner-padding-x': `${cfg.bannerPaddingX}rpx`,
|
'--banner-padding-x': this.$util.rpx(cfg.bannerPaddingX),
|
||||||
'--tip-padding-x': `${cfg.tipPaddingX}rpx`,
|
'--tip-padding-x': this.$util.rpx(cfg.tipPaddingX),
|
||||||
'--tip-font-size': `${cfg.tipFontSize}rpx`,
|
'--tip-font-size': this.$util.rpx(cfg.tipFontSize),
|
||||||
'--tip-color': cfg.tipColor,
|
'--tip-color': cfg.tipColor,
|
||||||
'--tip-bg-color': cfg.tipBgColor,
|
'--tip-bg-color': cfg.tipBgColor,
|
||||||
'--row-padding-y': `${cfg.rowPaddingY}rpx`,
|
'--row-padding-y': this.$util.rpx(cfg.rowPaddingY),
|
||||||
'--row-min-height': `${cfg.rowMinHeight}rpx`,
|
'--row-min-height': this.$util.rpx(cfg.rowMinHeight),
|
||||||
'--label-gap': `${cfg.labelGap}rpx`,
|
'--label-gap': this.$util.rpx(cfg.labelGap),
|
||||||
'--form-bg-color': cfg.formBgColor,
|
'--form-bg-color': cfg.formBgColor,
|
||||||
'--row-divider-color': cfg.rowDividerColor,
|
'--row-divider-color': cfg.rowDividerColor,
|
||||||
'--input-height': `${cfg.inputHeight}rpx`,
|
'--input-height': this.$util.rpx(cfg.inputHeight),
|
||||||
'--input-radius': `${cfg.inputRadius}rpx`,
|
'--input-radius': this.$util.rpx(cfg.inputRadius),
|
||||||
'--label-fixed-width': `${cfg.labelFixedWidth}rpx`,
|
'--label-fixed-width': this.$util.rpx(cfg.labelFixedWidth),
|
||||||
'--label-font-size': `${num(cfg.labelFontSize, 28)}rpx`,
|
'--label-font-size': this.$util.rpx(num(cfg.labelFontSize, 28)),
|
||||||
'--label-color': cfg.labelColor,
|
'--label-color': cfg.labelColor,
|
||||||
'--required-color': cfg.requiredColor,
|
'--required-color': cfg.requiredColor,
|
||||||
'--checked-color': cfg.checkedColor,
|
'--checked-color': cfg.checkedColor,
|
||||||
'--submit-color': cfg.submitColor,
|
'--submit-color': cfg.submitColor,
|
||||||
'--submit-bg-color': cfg.submitBgColor,
|
'--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'
|
'--show-row-divider': cfg.showRowDivider === false ? '0' : '1'
|
||||||
});
|
});
|
||||||
@@ -501,7 +450,7 @@ export default {
|
|||||||
// 行间距样式:仅上下内边距,水平由外层 form-wrap 控制(与后端 form-gorup 对齐)
|
// 行间距样式:仅上下内边距,水平由外层 form-wrap 控制(与后端 form-gorup 对齐)
|
||||||
rowWrapStyle() {
|
rowWrapStyle() {
|
||||||
return this.$util.objToStyle({
|
return this.$util.objToStyle({
|
||||||
padding: `${this.config.rowPaddingY}rpx 0`
|
padding: `${this.$util.rpx(this.config.rowPaddingY)} 0`
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
// 行容器 class:用于控制分割线显隐
|
// 行容器 class:用于控制分割线显隐
|
||||||
@@ -511,7 +460,7 @@ export default {
|
|||||||
// 行最小高度
|
// 行最小高度
|
||||||
rowCellStyle() {
|
rowCellStyle() {
|
||||||
return this.$util.objToStyle({
|
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 {};
|
||||||
}
|
}
|
||||||
return {
|
return {
|
||||||
'margin-right': `${this.config.labelGap}rpx`
|
'margin-right': this.$util.rpx(this.config.labelGap)
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
// 输入框样式(全局,未指定 item 时使用)
|
// 输入框样式(全局,未指定 item 时使用)
|
||||||
inputStyle() {
|
inputStyle() {
|
||||||
return this.$util.objToStyle({
|
return this.$util.objToStyle({
|
||||||
'min-height': `${this.config.inputHeight}rpx`,
|
'min-height': this.$util.rpx(this.config.inputHeight),
|
||||||
'border-radius': `${this.config.inputRadius}rpx`
|
'border-radius': this.$util.rpx(this.config.inputRadius)
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
labelStyle() {
|
labelStyle() {
|
||||||
let style = {};
|
const style = {
|
||||||
let fontSize = this.config.labelFontSize;
|
fontSize: this.$util.rpx(this.config.labelFontSize),
|
||||||
if (typeof fontSize === 'number') {
|
color: this.config.labelColor
|
||||||
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;
|
|
||||||
return this.$util.objToStyle(style);
|
return this.$util.objToStyle(style);
|
||||||
},
|
},
|
||||||
requiredColor() {
|
requiredColor() {
|
||||||
@@ -559,21 +503,6 @@ export default {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
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),
|
// 预计算每项的样式(写到 item._labelStyle / item._boxAlignStyle),
|
||||||
// 避免在模板里以方法形式调用:微信小程序 WXML 不支持 :style="getXxx(item)" 语法。
|
// 避免在模板里以方法形式调用:微信小程序 WXML 不支持 :style="getXxx(item)" 语法。
|
||||||
// 触发时机:processFormData 末尾 / calculateMaxLabelWidth 末尾 / config 变化 / mode 变化。
|
// 触发时机:processFormData 末尾 / calculateMaxLabelWidth 末尾 / config 变化 / mode 变化。
|
||||||
@@ -589,10 +518,7 @@ export default {
|
|||||||
|
|
||||||
// item 级别 label 字号 / 颜色覆盖(与原 getItemLabelStyle 逻辑一致)
|
// item 级别 label 字号 / 颜色覆盖(与原 getItemLabelStyle 逻辑一致)
|
||||||
if (itemValue.label_font_size !== undefined && itemValue.label_font_size !== null && itemValue.label_font_size !== '') {
|
if (itemValue.label_font_size !== undefined && itemValue.label_font_size !== null && itemValue.label_font_size !== '') {
|
||||||
let fs = itemValue.label_font_size;
|
style['--item-label-font-size'] = this.$util.rpx(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;
|
|
||||||
}
|
}
|
||||||
if (itemValue.label_color) {
|
if (itemValue.label_color) {
|
||||||
style['--item-label-color'] = itemValue.label_color;
|
style['--item-label-color'] = itemValue.label_color;
|
||||||
|
|||||||
Reference in New Issue
Block a user