Files
lucky_shop/components-diy/diy-form.vue
ZF sun 14ba88b645 refactor(diy-form): 重构自定义表单组件,替换为通用表单组件
1.  替换硬编码表单项为可配置的ns-newform组件
2.  支持横向/纵向两种布局模式
3.  添加表单Banner、提示语配置能力
4.  统一表单提交逻辑,新增表单校验和重置功能
5.  优化ns-newform组件样式与交互细节
2026-06-08 16:47:02 +08:00

166 lines
4.1 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<template>
<view data-component-name="diy-form" class="diy-from" :class="[formLayoutClass]" :style="style">
<!-- Banner -->
<view v-if="value.show_banner && value.form_banner" class="form-banner">
<image :src="$util.img(value.form_banner)" mode="widthFix" class="banner-img" />
</view>
<!-- 提示语 -->
<view v-if="value.show_tip && value.form_tip" class="form-tip">{{ value.form_tip }}</view>
<!-- 表单组件 -->
<ns-newform
:data="formComponents"
:customAttr="value"
:mode="value.form_layout === 'vertical' ? 'vertical' : 'horizontal'"
:labelWidthMode="value.label_width_mode"
:labelFixedWidth="value.label_fixed_width"
:labelFontSize="value.label_font_size"
:labelColor="value.label_color"
:requiredColor="value.required_color"
ref="nsNewform"
/>
<!-- 提交按钮 -->
<view @click.stop="submitForm" class="fui-btn btn-danger block mtop">提交信息</view>
</view>
</template>
<script>
// 自定义表单
import DiyMinx from './minx.js'
import NsNewform from '../pages_tool/_components/ns-newform/ns-newform.vue'
export default {
name: 'diy-from',
components: { NsNewform },
props: {
value: {
type: Object
}
},
mixins: [DiyMinx],
data() {
return {
formComponents: [] // 转换后的表单组件
};
},
created() {
this.initForm();
},
watch: {
'value.formComponents': {
deep: true,
handler() {
this.initForm();
}
}
},
computed: {
style() {
var css = '';
css += 'background-color:' + this.value.contentBgColor + ';';
if (this.value.elementAngle === 'round') {
css += 'border-top-left-radius:' + this.value.topElementAroundRadius * 2 + 'rpx;';
css += 'border-top-right-radius:' + this.value.topElementAroundRadius * 2 + 'rpx;';
css += 'border-bottom-left-radius:' + this.value.bottomElementAroundRadius * 2 + 'rpx;';
css += 'border-bottom-right-radius:' + this.value.bottomElementAroundRadius * 2 + 'rpx;';
}
return css;
},
formLayoutClass() {
return this.value.form_layout === 'vertical' ? 'form-vertical' : 'form-horizontal';
}
},
methods: {
// 初始化表单 - 将 diy-form 的数据格式转换成 ns-newform 的格式
initForm() {
var components = this.value.formComponents || [];
// 转换格式:type -> controller
this.formComponents = components.map(function(item) {
return {
controller: item.type,
value: item.value,
val: item.value.default || '' // 添加初始值
};
});
},
// 提交表单
submitForm() {
var self = this;
// 使用 ns-newform 的验证
if (this.$refs.nsNewform && this.$refs.nsNewform.verify) {
var verifyResult = this.$refs.nsNewform.verify();
if (!verifyResult) {
return;
}
}
// 获取表单数据
var submitData = {};
if (this.$refs.nsNewform && this.$refs.nsNewform.formData) {
this.$refs.nsNewform.formData.forEach(function(item, index) {
submitData[index] = item.val;
});
}
// 提交到后端
this.$api.sendRequest({
url: '/form/api/form/create',
data: {
form_id: this.value.form_id || 0,
form_data: JSON.stringify(submitData),
component_id: this.value.id || '',
form_name: this.value.form_name || '默认表单'
},
success: function(res) {
if (res.code === 0) {
uni.showToast({
title: '提交成功',
icon: 'success'
});
// 重置表单
if (self.$refs.nsNewform && self.$refs.nsNewform.setFormData) {
self.$refs.nsNewform.setFormData();
}
} else {
uni.showToast({
title: res.message || '提交失败',
icon: 'none'
});
}
}
});
}
}
};
</script>
<style lang="scss">
.diy-from {
background: #fff;
padding: 0 30rpx 20rpx;
border-radius: 10rpx;
.form-banner {
width: 100%;
overflow: hidden;
margin: 0 -30rpx;
.banner-img {
width: 100%;
display: block;
}
}
.form-tip {
padding: 30rpx 0;
text-align: center;
color: #666;
font-size: 28rpx;
}
.fui-btn {
margin: 30rpx 0 0;
}
}
</style>