- 背景:开发微信小程序。使用uniapp提供的框架进行开发。在pc端可以使用的component动态组件标签不被支持。HbuilderX中启动微信小程序时报编译错误。

- 替代方案。在诸多收费的自定义表单中。很少有提供微信小程序端的渲染组件。可能是基于此原因。也有支持的,但仅仅是在web-view页面中使用。

- 通过if-else判断。暂时能满足要求
<template>
<view class="dynamic-form">
<form>
<input type="text" value="测试" v-model="a" placeholder="请输入内容" name="testInput" />
<view v-for="item in formItems" :key="item.formItemId" class="form-item">
<!-- 图片 -->
<image name="image" v-if="item.type === 'IMAGE'" :src="item.scheme.src" mode="aspectFit"/>
<!-- 文本描述 -->
<rich-text v-else-if="item.type === 'DESC_TEXT'" :nodes="item.scheme.content"
v-model="formDataVar[item.scheme.vModel]"></rich-text>
<!-- 多选框 -->
<view v-else-if="item.type === 'CHECKBOX'">
<text>{{ item.label }}</text>
<checkbox-group :name="item.vModel">
<label v-for="(option, index) in item.scheme.config.options" :key="index">
<checkbox :value="option.value" /> {{ option.label }}
</label>
</checkbox-group>
</view>
<!-- 输入框 -->
<view v-else-if="item.type === 'INPUT'">
<text>{{ item.label }}</text>
<input :type="item.scheme.config.dataType.type || 'text'" :placeholder="item.placeholder" :name="item.vModel" v-model="formDataVar[item.scheme.vModel]"/>
</view>
<!-- 省市联动 -->
<view v-else-if="item.type === 'PROVINCE_CITY'">
<text>{{ item.label }}</text>
<!-- <picker mode="region" range="{{['北京','上海']}}" @change="handleRegionChange" @columnchange="handleColumnChange"
name="provinceCity">
<view class="picker">
当前选择:{{ region[0] }},{{ region[1] }}
</view>
</picker> -->
</view>
<!-- 日期 -->
<view v-else-if="item.type === 'DATE'">
<text>{{ item.label }}</text>
<picker mode="date" :range="dateRange" @change="(e) => handleDateChange(item, e)" name="date" >
<view class="picker">
当前选择:{{ formDataVar[item.scheme.vModel] || '请选择日期' }}
</view>
</picker>
</view>
</view>
<input v-model="message" placeholder="edit me">
<p>Message is: {{ message }}</p>
<button type="submit" @click="handleSubmit">提交</button>
<!-- 提交按钮 -->
<view class="fixed-bottom">
</view>
</form>
<view>
</view>
</view>
</template>
<script>
export default {
props: {
formData: {
type: Object,
required: true
},
processDefId: {
type: String,
required: true
}
},
data() {
return {
formItems: this.formData?.formItems || [],
region: ['北京市', '北京市'],
dateRange: [],
selectedDate: '',
formDataVar: {
},
message: ''
};
},
mounted() {
console.log('formData2:', this.formData);
console.log('formItems2:', this.formItems);
this.formItems.forEach(item => {
if (item.type === 'CHECKBOX') {
this.$set(this.formDataVar, item.scheme.vModel, []);
} else if (item.type === 'DATE') {
this.$set(this.formDataVar, item.scheme.vModel, '');
} else {
this.$set(this.formDataVar, item.scheme.vModel, '');
}
});
console.log('formDataVar:', this.formDataVar)
},
methods: {
handleSubmit(e) {
this.$emit('submitFormData', this.formDataVar)
},
handleRegionChange(e) {
const regions = ['北京', '上海'];
this.region = [regions[e.detail.value[0]], regions[e.detail.value[1]]];
},
handleColumnChange(e) {
},
handleDateChange(item, e) {
console.log('日期变化:', e.detail.value);
const date = new Date(e.detail.value).toLocaleDateString();
this.formDataVar[item.scheme.vModel] = date;
}
}
};
</script>
<style scoped>
.dynamic-form {
padding: 20px;
}
.form-item {
margin-bottom: 20px;
}
.fixed-bottom {
position: fixed;
bottom: 0;
left: 0;
right: 0;
padding: 20rpx;
background-color: #fff;
box-shadow: 0 2rpx 10rpx rgba(0, 0, 0, 0.05);
z-index: 999;
}
</style>