chore:表单样式修改
This commit is contained in:
@@ -6,7 +6,7 @@
|
|||||||
否则会触发 MP 编译器注入的 propsToData 观察者(对应编译产物里
|
否则会触发 MP 编译器注入的 propsToData 观察者(对应编译产物里
|
||||||
r=function(){var o=this.value.show_banner...this.$mp.data...})
|
r=function(){var o=this.value.show_banner...this.$mp.data...})
|
||||||
报 "Cannot read properties of undefined (reading 'show_banner')"。 -->
|
报 "Cannot read properties of undefined (reading 'show_banner')"。 -->
|
||||||
<view v-if="value && value.show_banner && value.form_banner" class="form-banner is-card-overlap" :style="bannerStyle">
|
<view v-if="value && value.show_banner && value.form_banner" class="form-banner is-card-overlap" :style="bannerStyle + bannerBleedStyle">
|
||||||
<image :src="$util.img(value.form_banner)" mode="widthFix" class="banner-img" />
|
<image :src="$util.img(value.form_banner)" mode="widthFix" class="banner-img" />
|
||||||
</view>
|
</view>
|
||||||
<!-- 卡片容器:仅在后台配置了 banner 图片时启用,让表单浮在 banner 之上(参考左图布局)。
|
<!-- 卡片容器:仅在后台配置了 banner 图片时启用,让表单浮在 banner 之上(参考左图布局)。
|
||||||
@@ -78,6 +78,14 @@ export default {
|
|||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: true
|
default: true
|
||||||
},
|
},
|
||||||
|
// 父级容器左右内边距(rpx)。卡片模式下让 banner 图片突破这个内边距左右铺满(如 system-form-wrap 的 padding-x)。
|
||||||
|
// 仅在 hasBannerMode=true 时生效;默认 0(不铺满)。
|
||||||
|
// 引入原因:formdata.vue 的 .system-form-wrap 默认 padding: 0 50rpx,banner 图片被左右各 50rpx 收缩,
|
||||||
|
// 后台配 form_banner 后图片应跨越屏幕宽度,而不是被容器内缩。
|
||||||
|
containerInset: {
|
||||||
|
type: Number,
|
||||||
|
default: 0
|
||||||
|
},
|
||||||
// 父级可选地接管提交:传入函数 prop 时,verify 通过后由它处理 formData;
|
// 父级可选地接管提交:传入函数 prop 时,verify 通过后由它处理 formData;
|
||||||
// 不传时走组件内置 defaultSubmit(兜底)。default 必须是 null,不能写成函数返回 null
|
// 不传时走组件内置 defaultSubmit(兜底)。default 必须是 null,不能写成函数返回 null
|
||||||
onSubmit: {
|
onSubmit: {
|
||||||
@@ -133,23 +141,45 @@ export default {
|
|||||||
const v = this.value || {};
|
const v = this.value || {};
|
||||||
return !!(v.show_banner && v.form_banner);
|
return !!(v.show_banner && v.form_banner);
|
||||||
},
|
},
|
||||||
// 卡片容器内联样式:maring-top(负偏移让卡片向上压住 banner 底部)+ border-radius + padding-x(与 bannerPaddingX 对齐)+ box-shadow。
|
// 卡片容器内联样式:maring-top(负偏移让卡片向上压住 banner 底部)+ border-radius + padding-x + box-shadow + background。
|
||||||
// 数值由 formConfig 走 camelCase/snake_case 双读,缺省走默认值,使后端零配置时也能看到卡片浮起效果。
|
// 数值由 formConfig 走 camelCase/snake_case 双读,缺省走默认值,使后端零配置时也能看到卡片浮起效果。
|
||||||
|
// 关键:卡片必须自带白底 + z-index(见 SCSS .form-card)—— 只有卡片自己的背景才能"盖住"banner 图片底部,
|
||||||
|
// 父级容器(如 formdata.vue 的 .system-form-wrap)是 banner 的祖先,其背景会被 banner 覆盖,无法形成浮起效果。
|
||||||
cardWrapStyle() {
|
cardWrapStyle() {
|
||||||
const cfg = this.mergedFormConfig || {};
|
const cfg = this.mergedFormConfig || {};
|
||||||
const sidePad = this._num(cfg.cardSidePad, this._num(cfg.bannerPaddingX, 28));
|
// 父级传了 containerInset(即 formdata.vue 场景),外层 system-form-wrap 已给左右 padding-x,这里默认 0 不重复
|
||||||
|
// 其他场景(diy-group / diy-article 等未传 containerInset),回退到 bannerPaddingX 或 28rpx 保证卡片模式视觉正常
|
||||||
|
const parentInset = this._num(this.containerInset, 0);
|
||||||
|
const defaultSidePad = parentInset > 0 ? 0 : this._num(cfg.bannerPaddingX, 28);
|
||||||
|
const sidePad = this._num(cfg.cardSidePad, defaultSidePad);
|
||||||
// overlap:负值,让卡片向上"压"住 banner 底部(与设计图一致)
|
// overlap:负值,让卡片向上"压"住 banner 底部(与设计图一致)
|
||||||
const overlap = -Math.abs(this._num(cfg.cardOverlap, 48));
|
const overlap = -Math.abs(this._num(cfg.cardOverlap, 48));
|
||||||
// 卡片圆角:缺省 24rpx
|
// 卡片圆角:缺省 24rpx(浮起卡片的圆角,比外层卡片的 16rpx 更明显,突出浮起感)
|
||||||
const radius = this._num(cfg.cardRadius, 24);
|
const radius = this._num(cfg.cardRadius, 24);
|
||||||
// 阴影:缺省中等阴影(与设计方案一致)
|
// 阴影:缺省中等阴影(与设计方案一致)—— 由本容器承担浮起感
|
||||||
const shadow = cfg.cardShadow || '0 8rpx 24rpx rgba(0,0,0,0.08)';
|
const shadow = cfg.cardShadow || '0 8rpx 24rpx rgba(0,0,0,0.08)';
|
||||||
|
// 卡片底色:纯白,与设计方案一致;可由后台 formConfig.cardBgColor 覆盖
|
||||||
|
const bgColor = cfg.cardBgColor || '#ffffff';
|
||||||
return this.$util.objToStyle({
|
return this.$util.objToStyle({
|
||||||
marginTop: overlap + 'rpx',
|
marginTop: overlap + 'rpx',
|
||||||
paddingLeft: sidePad + 'rpx',
|
paddingLeft: sidePad + 'rpx',
|
||||||
paddingRight: sidePad + 'rpx',
|
paddingRight: sidePad + 'rpx',
|
||||||
borderRadius: radius + 'rpx',
|
borderRadius: radius + 'rpx',
|
||||||
boxShadow: shadow
|
boxShadow: shadow,
|
||||||
|
backgroundColor: bgColor
|
||||||
|
});
|
||||||
|
},
|
||||||
|
// Banner 容器破壳样式:仅在卡片模式下 + 父级传了 containerInset>0 时启用,让 banner 突破父容器 padding 跨越屏幕宽度。
|
||||||
|
// 计算逻辑:负 margin-left/right + 等量扩宽 width,使 banner 元素左/右边界对齐到屏幕边缘。
|
||||||
|
// 父级未传 containerInset 或传 0 时返回空样式,banner 保持原尺寸(零外溢)。
|
||||||
|
bannerBleedStyle() {
|
||||||
|
const inset = this._num(this.containerInset, 0);
|
||||||
|
if (!this.hasBannerMode || inset <= 0) return '';
|
||||||
|
const expand = inset * 2;
|
||||||
|
return this.$util.objToStyle({
|
||||||
|
marginLeft: -inset + 'rpx',
|
||||||
|
marginRight: -inset + 'rpx',
|
||||||
|
width: 'calc(100% + ' + expand + 'rpx)'
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
// 提示语样式:padding-x、font-size、color、bg-color、border-bottom(与后端 .form-preview-tip 对齐)
|
// 提示语样式:padding-x、font-size、color、bg-color、border-bottom(与后端 .form-preview-tip 对齐)
|
||||||
@@ -278,7 +308,8 @@ export default {
|
|||||||
cardOverlap: pick('cardOverlap', 'card_overlap'),
|
cardOverlap: pick('cardOverlap', 'card_overlap'),
|
||||||
cardRadius: pick('cardRadius', 'card_radius'),
|
cardRadius: pick('cardRadius', 'card_radius'),
|
||||||
cardShadow: pick('cardShadow', 'card_shadow'),
|
cardShadow: pick('cardShadow', 'card_shadow'),
|
||||||
cardSidePad: pick('cardSidePad', 'card_side_pad')
|
cardSidePad: pick('cardSidePad', 'card_side_pad'),
|
||||||
|
cardBgColor: pick('cardBgColor', 'card_bg_color')
|
||||||
};
|
};
|
||||||
// 移除 undefined / 空字符串(保留 0/false)
|
// 移除 undefined / 空字符串(保留 0/false)
|
||||||
Object.keys(base).forEach(function(k) {
|
Object.keys(base).forEach(function(k) {
|
||||||
@@ -456,17 +487,19 @@ export default {
|
|||||||
|
|
||||||
// 卡片容器:浮在 banner 图片上方(参考设计左图)。
|
// 卡片容器:浮在 banner 图片上方(参考设计左图)。
|
||||||
// 仅在 hasBannerMode=true 时渲染(见 template v-if);
|
// 仅在 hasBannerMode=true 时渲染(见 template v-if);
|
||||||
// 外边距 / 圆角 / 阴影 / 左右内边距 全部由 cardWrapStyle 内联写入(读取后台 formConfig.card*)。
|
// 阴影 + margin-top(负偏移)+ 圆角 + 白底 全部由 cardWrapStyle 内联写入(读取后台 formConfig.card*)。
|
||||||
|
// 关键:卡片必须自带白底并 z-index 高于 banner,才能真正"盖住"banner 图片底部形成浮起;
|
||||||
|
// 父级容器(formdata.vue 的 .system-form-wrap)虽也是白底,但它是 banner 的祖先、背景会被 banner 覆盖,
|
||||||
|
// 因此本容器的白底不可省略(与 .system-form-wrap 同色,视觉上从卡片向下自然延续到页面底部)。
|
||||||
.form-card {
|
.form-card {
|
||||||
|
// 定位上下文 + 高于 banner 的层级:让卡片盖住 banner 底部(banner z-index:1)
|
||||||
position: relative;
|
position: relative;
|
||||||
z-index: 2;
|
z-index: 2;
|
||||||
|
// 兜底白底 / 圆角 / 阴影:与后端未配置时内联写入的默认值一致;后台配置时由内联 cardWrapStyle 覆盖
|
||||||
background-color: #ffffff;
|
background-color: #ffffff;
|
||||||
// 兜底圆角:与后端未配置时内联写入的 24rpx 一致;后台配置时由内联覆盖
|
|
||||||
border-radius: 24rpx;
|
border-radius: 24rpx;
|
||||||
// 兜底阴影:与后端未配置时内联写入的中等阴影一致
|
|
||||||
box-shadow: 0 8rpx 24rpx rgba(0, 0, 0, 0.08);
|
box-shadow: 0 8rpx 24rpx rgba(0, 0, 0, 0.08);
|
||||||
// 顶部负 margin 由内联 cardWrapStyle 写入(cardOverlap,缺省 -48rpx 把卡片向上压住 banner 底部)
|
// 兜底 padding-bottom:让卡片与后面内容(如推荐码、其它 diy 组件)有间距
|
||||||
// 底部留白让卡片与后面内容(如推荐码、其它 diy 组件)有间距
|
|
||||||
padding-bottom: 24rpx;
|
padding-bottom: 24rpx;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -39,7 +39,7 @@
|
|||||||
<view class="page harmony-page">
|
<view class="page harmony-page">
|
||||||
<scroll-view scroll-y="true" :show-scrollbar="false" class="form-scroll">
|
<scroll-view scroll-y="true" :show-scrollbar="false" class="form-scroll">
|
||||||
<view class="system-form-wrap" :style="containerStyle">
|
<view class="system-form-wrap" :style="containerStyle">
|
||||||
<diy-form ref="form" :value="diyValue" dataMode="raw" :showSubmit="!showCaptcha" :onSubmit="handleSubmit" />
|
<diy-form ref="form" :value="diyValue" dataMode="raw" :showSubmit="!showCaptcha" :onSubmit="handleSubmit" :container-inset="containerInset" />
|
||||||
<!-- 行为设置:提交验证码开启时,隐藏 diy-form 内置按钮,由本页渲染验证码+提交按钮 -->
|
<!-- 行为设置:提交验证码开启时,隐藏 diy-form 内置按钮,由本页渲染验证码+提交按钮 -->
|
||||||
<view v-if="showCaptcha" class="form-extra-wrap">
|
<view v-if="showCaptcha" class="form-extra-wrap">
|
||||||
<view class="captcha-wrap">
|
<view class="captcha-wrap">
|
||||||
@@ -65,7 +65,7 @@
|
|||||||
:onSubmit 接管提交逻辑(带 uniacid + showModal);跨 H5 / MP 一致,不依赖 $listeners。
|
:onSubmit 接管提交逻辑(带 uniacid + showModal);跨 H5 / MP 一致,不依赖 $listeners。
|
||||||
注意:create 重度依赖本组件 this(id/uniacid/memberInfo/$api 等),必须在 created 阶段 bind this,
|
注意:create 重度依赖本组件 this(id/uniacid/memberInfo/$api 等),必须在 created 阶段 bind this,
|
||||||
否则 diy-form 通过 this.onSubmit(formData) 调用时 this 会漂移到子组件实例 -->
|
否则 diy-form 通过 this.onSubmit(formData) 调用时 this 会漂移到子组件实例 -->
|
||||||
<diy-form ref="form" :value="diyValue" dataMode="raw" :showSubmit="!showCaptcha" :onSubmit="handleSubmit" />
|
<diy-form ref="form" :value="diyValue" dataMode="raw" :showSubmit="!showCaptcha" :onSubmit="handleSubmit" :container-inset="containerInset" />
|
||||||
<!-- 行为设置:提交验证码开启时,隐藏 diy-form 内置按钮,由本页渲染验证码+提交按钮 -->
|
<!-- 行为设置:提交验证码开启时,隐藏 diy-form 内置按钮,由本页渲染验证码+提交按钮 -->
|
||||||
<view v-if="showCaptcha" class="form-extra-wrap">
|
<view v-if="showCaptcha" class="form-extra-wrap">
|
||||||
<view class="captcha-wrap">
|
<view class="captcha-wrap">
|
||||||
|
|||||||
Reference in New Issue
Block a user