1. 替换硬编码表单项为可配置的ns-newform组件 2. 支持横向/纵向两种布局模式 3. 添加表单Banner、提示语配置能力 4. 统一表单提交逻辑,新增表单校验和重置功能 5. 优化ns-newform组件样式与交互细节
166 lines
4.1 KiB
Vue
166 lines
4.1 KiB
Vue
<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>
|