使用uView创建一份表单,包括上传和各种数据提交。
封装的form
<template>
<view class="filter_container">
<view class="filter_container_title base_title">
<slot name="header">{{ title }}</slot>
</view>
<scroll-view scroll-y="true" :style="'height:' + height * 0.8 * heightRatio + 'px;'">
<!-- <map></map> -->
<slot name="filter">
<u-form :model="value" ref="uForm" :rules="rules" :labelPosition="labelPosition">
<u-form-item
v-for="(item, index) in formItem"
:key="item.key"
:label-width="item.labelWidth || 100"
:label="item.name"
:prop="item.key"
v-show="!item.parent || value[item.parent]"
>
<text v-if="item.require" style="color: #f70000">*</text>
<uni-datetime-picker v-if="item.type == 'timeRange'" v-model="value[item.key]" rangeSeparator="至" type="datetimerange" />
<uni-datetime-picker v-else-if="item.type == 'dateRange'" v-model="value[item.key]" rangeSeparator="至" type="daterange" />
<uni-datetime-picker v-else-if="item.type == 'date'" v-model="value[item.key]" type="datetime" />
<uni-datetime-picker v-else-if="item.type == 'datetime'" v-model="value[item.key]" type="date" />
<u-radio-group v-else-if="item.type == 'radio'" v-model="value[item.key]">
<u-radio v-for="(ritem, rItemIndex) in item.list" :key="ritem.value" :label="ritem.text" :name="ritem.value">{{ ritem.text }}</u-radio>
</u-radio-group>
<view v-else class="width-100">
<view v-if="item.enabled == true">
<u-input
border="bottom"
v-model="value[item.key]"
:type="item.type || 'text'"
:disabled="item.enabled"
:placeholder="item.placeholder || '请输入内容'"
>
</u-input>
</view>
<view v-else>
<u-input
border="bottom"
v-model="value[item.key]"
:type="item.type || 'text'"
:disabled="item.enabled"
:placeholder="item.placeholder || '请输入内容'"
:maxlength="item.maxlength || -1"
>
</u-input>
</view>
</view>
<!-- <u-action-sheet v-if="item.type=='select'" :list="item.list" v-model="item.show">
</u-action-sheet> -->
<text v-if="item.unit" class="width-20 margin_left_small flex align-center justify-center">{{ item.unit }}</text>
<u-button @click="clickedInput(item.key)" slot="right" v-if="item.hasBtn" :text="item.btn.text" :icon="item.btn.icon" type="primary" size="small"></u-button>
</u-form-item>
</u-form>
</slot>
<slot></slot>
</scroll-view>
<view class="filter_container_bottom">
<slot name="bottom">
<view class="width-100 flex">
<view class="flex width-50 margin_top_small margin_bottom_small margin_left margin_right">
<button class="cu-btn bg-grey text-white margin-tb-sm lg" @click="handleClear">重置</button>
</view>
<view class="flex width-50 margin_top_small margin_bottom_small margin_left margin_right">
<button class="cu-btn default-primary-color-bg text-white margin-tb-sm lg" @click="handleConfirm">确定</button>
</view>
</view>
</slot>
</view>
</view>
</template>
<script>
/**
* input 输入框
* @description 此组件为筛选组件
* @property {Object} value 表单内容,选择内容
* @property {Array} formItem 表单标签项
* 格式:
* [...{
* name: '产品型号',//标签名
key: 'productType',//对应key,必须唯一
type: "select",//类型,可选u-input所有类型,包括text文本,textarea文本域,select选择列表,radio单选等,
时间类型:datetimerange,日期时间范围,daterange日期范围.date日期
list: [],
require: true
* }...]
*
* @property {Object} rules 表单验证规则 参见https://github.com/yiminghe/async-validator
* https://www.uviewui.com/components/form.html
* @property {} v-model 用于双向绑定输入框的值
*
*
* @property {function} @handleConfirm 默认点击确认
* @example <free-form v-model="productData" :formItem="productItem" :rules="rules" @handleConfirm="handleUpdate"/>
*/
export default {
name: 'free-form',
watch: {
// 监听规则的变化
value: {
immediate: true,
handler(newVal) {
this.value=newVal
if(Object.keys(this.value).length==0){
return
}
if (this.rules&&this.$refs.uForm){
this.$refs.uForm.setRules(this.rules);
}
},
},
},
props: {
title: {
type: String,
default: '筛选'
},
value: {
type: Object,
default: () => {}
},
formItem: {
type: Array,
default: () => []
},
rules: Object,
labelPosition:{
type: String,
default: 'left'
},
heightRatio: {
type: Number,
default: 1,
}
},
data() {
return {
height: '150',
Width: '750',
formitem: []
};
},
methods: {
handleClear(e) {
this.$emit('input', {});
},
handleConfirm(e) {
let _this = this;
if (this.rules) {
this.$refs.uForm.validate().then(valid => {
if (valid) {
_this.$emit('handleConfirm', this.value);
}
});
} else this.$emit('handleConfirm', this.value);
},
clickedInput(key) {
this.$emit('clickedInput', key);
}
},
onResize() {
//获取信息
uni.getSystemInfo({
success(res) {
_this.height = res.windowHeight;
_this.Width = res.windowWidth;
}
});
},
onReady() {},
mounted() {
let _this = this;
//获取信息
uni.getSystemInfo({
success(res) {
_this.height = res.windowHeight;
_this.Width = res.windowWidth;
}
});
}
};
</script>
<style scoped lang="scss">
.filter_container {
display: flex;
padding: 16px;
flex-direction: column;
&_title {
width: 100%;
text-align: center;
}
&_bottom {
display: flex;
flex-direction: row;
justify-content: center;
button {
flex: 1;
}
}
}
</style>
使用方式
<u-popup ref="popup" :show="showAdd" mode="bottom" borderRadius="14" :closeable="true" @close="showAdd=false">
<free-form v-model="productData" @clickedInput="clickedInputListener" :formItem="productItem" :rules="rules" @handleConfirm="handleUpdate" title="新增">
<view class="flex flex-column">
<text>零配件绑定:</text>
<view :index="index" v-for="(item, index) in partsList" :key="item.id">
<ComponentItemView :item="item"></ComponentItemView>
<view class="f_gap"></view>
<view class="flex margin_right_large margin_bottom_large flex-item">
<view class="width-100 flex flex-item">
<button class="cu-btn bg-red text-white text-white margin-tb-sm sm margin-left-auto" @click="delParts(item)">删除</button>
</view>
</view>
</view>
<view>
<button class="cu-btn default-primary-color-bg text-white margin-tb-sm" @click="newParts">新增</button>
</view>
<text>上传图片:</text>
<view class="margin_top_small">
<u-grid :border="false" col="3">
<u-grid-item v-for="(item, index) in faultPicList" :key="item.bizType">
<view class="flex flex-column">
<view class="primary-text-color text-center text_wrap">{{item.name}}</view>
<u-upload
:fileList="faultPicList[index].fileList"
@afterRead="(event)=>{
afterRead(index, event)
}"
@delete="(event)=>{
deletePic(index, event)
}"
multiple
:maxCount="1"
></u-upload>
</view>
</u-grid-item>
</u-grid>
</view>
</view>
</free-form>
关键变量
faultPicList: [
{
name:'车牌号照片\n',
bizType:'licensePlatePic',
fileList:[],
},
{
name:'仪表照片\n',
bizType:'meterPic',
fileList:[],
},
{
name:'故障损坏位置\n',
bizType:'faultDamagePic',
fileList:[],
},
{
name:'故障件照片\n体现序列号',
bizType:'faultPic',
fileList:[],
},
{
name:'新件照片\n体现序列号',
bizType:'newAccPic',
fileList:[],
},
{
name:'故障解决后照片\n\n',
bizType:'faultResolvePic',
fileList:[],
},
{
name:'其他1',
bizType:'other1',
fileList:[],
},
{
name:'其他2',
bizType:'other2',
fileList:[],
},
{
name:'其他3',
bizType:'other3',
fileList:[],
},
],
rules: {
productCode: [{
required: true,
message: '请输入产品编号',
// 可以单个或者同时写两个触发验证方式
trigger: 'blur,change'
}],
occurrenceTime:[{
required: true,
message: '请选择发生时间',
},
{
pattern: /^((\d{2}(([02468][048])|([13579][26]))[\-\/\s]?((((0?[13578])|(1[02]))[\-\/\s]?((0?[1-9])|([1-2][0-9])|(3[01])))|(((0?[469])|(11))[\-\/\s]?((0?[1-9])|([1-2][0-9])|(30)))|(0?2[\-\/\s]?((0?[1-9])|([1-2][0-9])))))|(\d{2}(([02468][1235679])|([13579][01345789]))[\-\/\s]?((((0?[13578])|(1[02]))[\-\/\s]?((0?[1-9])|([1-2][0-9])|(3[01])))|(((0?[469])|(11))[\-\/\s]?((0?[1-9])|([1-2][0-9])|(30)))|(0?2[\-\/\s]?((0?[1-9])|(1[0-9])|(2[0-8]))))))(\s((([0-1][0-9])|(2?[0-3]))\:([0-5]?[0-9])((\s)|(\:([0-5]?[0-9])))))?$/g,
// 正则检验前先将值转为字符串
transform(value) {
return String(value);
},
message: '时间应包含年月日、时分秒'
}],
maintenanceTypeName:[{
required: true,
message: '请选择保养类型',
}],
maintenanceLevel:[{
required: true,
message: '请选择保养等级',
}],
duration: [{
required: true,
message: '请输入时长',
// 可以单个或者同时写两个触发验证方式
trigger: 'blur,change'
}],
workHour: [{
required: true,
message: '请输入工时',
// 可以单个或者同时写两个触发验证方式
trigger: 'blur,change'
}],
},
productItem: [
{
name: "产品编号",
key: 'productCode',
require: true,
enabled: true,
hasBtn:true,
btn:{
text:'',
icon:'search',
}
},
{
name: "保养单号",
key: 'maintenanceNumber',
enabled: true
},
{
name: "产品型号",
key: 'productType',
enabled: true
},
{
name: "产品功率",
key: 'outputPower',
unit:"kW",
enabled: true
},
{
name: "车架号",
key: 'frameNumber',
enabled: true
},
{
name: "车牌",
key: 'licensePlate',
enabled: true
},
{
name: "车辆编号",
key: 'vehicleCode',
},
{
name: "车辆型号",
key: 'vehicleModel',
enabled: true
},
{
name: "电堆运行时间",
key: 'reactorOperationTime',
type: 'digit',
unit: "小时",
hasBtn:true,
btn:{
text:'获取',
}
},
{
name: "车辆行驶里程",
key: 'vehicleMilwage',
type: 'digit',
unit: "km",
hasBtn:true,
btn:{
text:'获取',
}
},
{
name: "保养场地",
key: 'maintenanceSite',
hasBtn:true,
btn:{
text:'',
icon:'map',
}
},
{
name: '客户名称',
key: 'cusName',
enabled: true
},
{
name: '负责人',
key: 'cusContact',
enabled: true
},
{
name: '联系电话',
key: 'cusTelephone',
enabled: true
},
{
name: "在保情况",
key: 'warranty',
enabled: true
},
{
name: "发生时间",
key: 'occurrenceTime',
require: true,
type: 'date',
},
{
name: "保养类型",
key: 'maintenanceTypeName',
require: true,
list: [],
type: 'select',
},
{
name: "保养等级",
key: 'maintenanceLevel',
require: true,
list: [],
type: 'select',
},
{
name: "保养描述",
key: 'maintenanceDescription'
},
{
name: "合计",
key: 'total',
type: 'number',
},
{
name: "人员数量",
key: 'personNumber',
type: 'number',
},
{
name: "出发时间",
key: 'departureTime',
type: 'date',
},
{
name: "返回时间",
key: 'rebackTime',
type: 'date',
},
{
name: "时长",
key: 'duration',
require: true,
type: 'digit',
unit:'小时',
},
{
name: "工时",
key: 'workHour',
require: true,
type: 'digit',
unit:'小时',
},
{
name: "保养处理记录",
key: 'maintenanceRecords',
maxlength: 36,
},
{
name: "原因归纳",
key: 'mainAnalysisInduction',
maxlength: 36,
},
{
name: "服务人员安排",
key: 'servicePerson',
maxlength: 36,
},
{
name: "备注",
key: 'remark',
maxlength: 36,
},
],
formItem: [{
name: "保养单号",
key: 'maintenanceNumber'
}, {
name: "车辆编号",
key: 'vehicleCode'
}, {
name: "车辆型号",
key: 'vehicleModel'
},
{
name: "车架号",
key: 'frameNumber'
},
{
name: "保养状态",
key: 'maintenanceState',
list: [],
type: "select"
}, {
name: "审核状态",
key: 'auditStatus',
list: [],
type: "select"
}, {
name: "发生时间",
key: 'occurrenceTime',
type: "timeRange"
}],
···
2 个回复
m***@163.com (作者)
能不能帮忙看看?谢谢。
m***@163.com (作者)
请官方人员进行回复,这个问题比较严重。