创建menu目录 index.vue页面和组件components/index页面
最主要的还是组件components/index 里的代码
<template>
<view class="form-container">
<view class="form-box">
<block v-for="(item,index) in formData" :key="index">
<uni-section :title="item.label" type="line"
:sub-title="item.rules.subTiltle + item.limit"></uni-section>
<!-- 文本框 -->
//name必须为 :name="[index,'value']" 其她的可以用item访问属性
<uni-forms-item :name="[index,'value']" :required="item.rules.required" :rules='item.rules'
v-if="item.type=='text' || item.type=='number' || item.type=='password'|| item.type=='textarea'">
<uni-easyinput :type="item.type" v-model="item.value" :placeholder='item.placeholder'
@input="inputVal(index)">
<template v-if="item.rightSlot" v-slot:right>
<view class="" style="margin-right: 14rpx;">
{{item.rightSlot}}
</view>
</template>
</uni-easyinput>
</uni-forms-item>
<!-- 日期时间 -->
<uni-forms-item :name="[index,'value']" :rules="[{
required: item.rules.required,errorMessage: item.rules.errMess
}]" v-else-if="item.type=='datetime'|| item.type=='date'||item.type=='daterange'||item.type=='datetimerange'">
<uni-datetime-picker @change="dataTimeChange($event,index)" :type="item.type"
return-type="timestamp" v-model="item.value" />
</uni-forms-item>
<!-- 单选框-->
<uni-forms-item :name="[index,'value']" :rules="item.rules" :required="item.rules.required"
v-else-if="item.type=='radio'">
<uni-data-checkbox @change="checkBoxChange($event,item,index)" :multiple="item.rules.multiple"
v-model="item.value" :localdata="item.selectVal" />
</uni-forms-item>
<!-- 选择 -->
<uni-forms-item :name="[index,'value']" v-else-if="item.type=='picker'" :required="item.rules.required"
:rules="item.rules">
<picker @change="bindPickerChange($event,item,index)" :value="index" :range="item.selectVal"
style="height: 100%;" range-key="text">
<view class=""
style="padding: 10px; background: #fff;border-radius: 8rpx;border: 1px solid #dcdfe6;">
{{item.value?item.value:'请选择'}}
</view>
</picker>
</uni-forms-item>
<!-- 上传图片 -->
<uni-forms-item :name="[index,'value']" :required="item.rules.required" v-else-if="item.type=='image'">
<view class="example-body">
<uni-file-picker v-model="item.value" :limit="item.limit"
@select="selectHandle($event,index,item)" :value="item.fileLists" @success="handleSuccess"
@fail="handleFail" @progress="handleProgress"
:file-mediatype="item.fileMediatype"></uni-file-picker>
</view>
</uni-forms-item>
<!-- 下拉选 -->
<uni-forms-item :name="[index,'value']" :required="item.rules.required" :rules="item.rules"
v-else-if="item.type=='select'">
<uni-data-select v-model="item.value" :localdata="item.selectVal?item.selectVal:getSelectList(item)"
@change="selectChange($event,item,index)"></uni-data-select>
</uni-forms-item>
</block>
</view>
</view>
</template>
<script setup>
import {
ref
} from 'vue'
const emit = defineEmits(["input-val", 'picker-input-btn', 'select-input-btn', 'check-box', 'upload-handle',
'time-handle'
])
const props = defineProps({
formData: {
type: Array,
default: () => []
},
})
function getSelectList(item) {
// 在这里可以调接口 查询列表
let list = [{
value: 0,
text: "是"
},
{
value: 1,
text: "否"
},
]
item.selectVal = list
return list
}
// 文本框
function inputVal(index) {
emit("input-val", {
val: props.formData[index].value,
index: index
})
}
// 选择
function bindPickerChange(e, item, index) {
// selectedValue为传给后台的值
item.selectedValue = e.detail.value
emit("picker-input-btn", item, index)
}
// 单选框
function checkBoxChange(e, item, index) {
item.value = e.detail.data.value
emit("check-box", item, index)
}
// 下拉选
function selectChange(e, item, index) {
item.selectedValue = e
emit("select-input-btn", item, index)
}
// 上传图片
function selectHandle(event, index, item) {
console.log(event, 'selectHandle', index)
item.fileLists = [{
url: 'blob:http://localhost:9090/4bacdb76-70d6-426e-9be4-3bca40c5dca2'
}]
emit('upload-handle', event.tempFiles, index)
}
function handleSuccess(event) {
console.log('handleSuccess', event.detail.files);
}
function handleProgress(event) {
console.log('handleProgress', event.detail.files);
}
// 时间
function dataTimeChange(val, index) {
console.log(val, 'val')
emit('time-handle', val, index)
}
function handleFail(error) {
// 处理文件选择失败的情况
console.error('handleFail', error);
// 可以给用户一个错误提示
}
</script>
<style lang="scss">
// 弹框
.select-modal {
position: fixed;
left: 0;
top: 0;
width: 100%;
height: 100%;
z-index: 300000;
.select-bg {
width: 100%;
height: 100%;
background: rgba(0, 0, 0, 0.3);
}
.select-box {
position: absolute;
left: 0;
bottom: -1000upx;
width: 100%;
background: #fff;
max-height: 50%;
// height: 0%;
overflow: auto;
.select-title {
display: flex;
justify-content: space-between;
height: 80upx;
background: #f5f5f5;
line-height: 80upx;
padding: 0 30upx;
}
.select-item {
font-size: 28upx;
color: #333;
border-bottom: 1px solid #eee;
height: 75upx;
line-height: 75upx;
padding: 0 30upx;
i {
display: block;
float: right;
border-bottom: 4upx solid #1ca032;
border-right: 4upx solid #1ca032;
width: 12upx;
height: 26upx;
transform: rotate(45deg);
margin-top: 24.5upx;
}
}
}
@keyframes mymove {
0% {
max-height: 10%;
}
100% {
max-height: 50%;
}
}
/*Safari 和 Chrome:*/
@-webkit-keyframes mymove {
0% {
max-height: 10%;
}
100% {
max-height: 50%;
}
}
}
// 下拉icon
.select-icon {
// display: block;
float: right;
border-bottom: 2upx solid #999;
border-right: 2upx solid #999;
width: 16upx;
height: 16upx;
transform: rotate(-45deg);
margin-right: 10upx;
}
.color-orange {
color: #ff5b01;
}
.color-999 {
color: #999;
}
.font32 {
font-size: 32upx;
}
.plaClass {
color: #dbdbdb;
}
.form-container {
padding: 0 30upx;
.form-box {
width: 100%;
box-sizing: border-box;
}
.colorRed {
color: red;
}
.img-box {
border-bottom: 1px solid #ededed;
padding: 30upx 0;
.update-img-box {
border: 1px solid #ededed;
display: flex;
.update-img {
width: 140upx;
height: 140upx;
}
}
.update-img-box2 {
overflow: hidden;
display: flex;
}
.update-img-box,
.update-btn-box {
width: 140upx;
height: 140upx;
position: relative;
margin-top: 20upx;
}
.update-img-box .close-img {
width: 40upx;
height: 40upx;
position: absolute;
right: -12upx;
top: -16upx;
background: #fff;
border-radius: 50%;
}
img {
width: 140upx;
height: 140upx;
object-fit: cover;
}
}
.line-right {
flex: 1;
height: 100%;
display: flex;
align-items: center;
justify-content: space-between;
position: relative;
}
.send-code-box {
.send-code {
font-size: 28upx;
padding: 0;
white-space: nowrap;
// width: 60%;
//color:#ff5b01;
height: 90upx;
line-height: 90upx;
cursor: pointer;
}
}
.line-left {
display: flex;
width: 22%;
align-items: center;
height: 100%;
font-size: 28upx;
color: #333;
box-sizing: border-box;
}
.img-label {
width: 100%;
height: 100%;
font-size: 28upx;
color: #333;
box-sizing: border-box;
}
.p-l14 {
padding-left: 14upx;
}
.textarea-box {
// display: flex;
border-bottom: 1px solid #ededed;
padding-top: 20upx;
// align-items: center;
textarea {
height: 150upx;
font-size: 28upx;
color: #333;
width: 100%;
margin-top: 20upx;
}
}
.line {
margin-top: 30upx;
height: 100upx;
width: 100%;
margin: 0 auto;
border-bottom: 1px solid #ededed;
display: flex;
overflow: hidden;
.input {
padding-right: 20upx;
height: 100%;
width: 100%;
text-align: left;
font-size: 28upx;
color: #333;
border: none;
overflow: hidden;
text-overflow: ellipsis;
outline: none;
}
}
}
</style>
下面是menu/index的代码
<template>
<view class="menu-style" style="">
<uni-forms ref="valiForm" :modelValue="formData">
<form-list :formData="formData" @upload-handle="uploadHandle" @input-val="inputVal"
@time-handle="timeHandle" @picker-input-btn="pickerInputBtn" @check-box="checkBoxChange"
@select-input-btn="selectInputBtn"></form-list>
</uni-forms>
<view class="buttonBox" @click="submit1">
提交
</view>
</view>
</template>
<script setup>
import FormList from './components/index'
import {
ref
} from 'vue'
const valiForm = ref(null)
const formData = ref([{
label: "到场拍照反馈",
type: "image",
updateImg: false, //默认只显示上传按钮
fileLists: [],
name: "presentPhoto",
value: "",
limit: 9,
subTiltle: '最大图片量',
rules: [{
errMess: "请上传到场拍照",
required: true
}]
},
{
label: "箱内照片",
type: "image",
updateImg: false, //默认只显示上传按钮
fileLists: [],
name: "inpic",
value: "",
limit: 9,
subTiltle: '最大图片量',
rules: [{
errMess: "请上传箱内照片",
required: true,
}]
},
{
placeholder: "请输入进口压力",
label: "进口压力",
type: "text",
name: "pressure",
rightSlot: 'MPa',
value: "",
rules: [{
errorMessage: "请输入进口压力",
required: true,
},
{
required: true,
minLength: 2,
maxLength: 10,
}
]
},
{
placeholder: "请选择",
label: "压力是否正常",
type: "select",
selectedValue: '',
// selectVal: [
// {value:0,text:"是"},
// {value:1,text:"否"},
// ],
selectPost: 'pressureType',
name: "pressureType",
value: "",
rules: [{
required: true,
errorMessage: "请选择压力是否正常"
}]
},
{
placeholder: "请选择",
label: "泄漏",
type: "select",
selectedValue: '',
name: "leakage",
// selectVal: [
// {value:0,text:"是"},
// {value:1,text:"否"},
// ],
value: "",
selectPost: 'leakage',
rules: [{
required: true,
errorMessage: "请选择是否泄漏"
}]
},
{
placeholder: "请输入泄漏浓度",
label: "泄漏浓度",
type: "text",
name: "concentration",
rightSlot: '%LEL',
value: "",
rules: [{
errMess: "请输入泄漏浓度",
required: false,
},
{
required: false,
minlength: 1,
maxlength: 10
}
]
},
])
const submitData = ref('')
function pickerInputBtn(item, index) {
if (item.selectedValue) {
formData.value[index].value = item.selectVal[item.selectedValue].text
}
}
function checkBoxChange(item, index) {
formData.value[index] = item
}
function selectInputBtn(item, index) {
if (item.selectedValue) {
formData.value[index].value = item.selectVal[item.selectedValue].value
}
}
// 提交表单的函数
function submit1() {
console.log(valiForm, '====')
valiForm.value.validate().then((res) => {
console.log('success', res);
uni.showToast({
title: `校验通过`
})
}).catch((err) => {
console.log('err', err);
})
}
function inputVal(data2) {
// var data = JSON.parse(data2);
console.log(data2)
if (String(data2.val) != "" && String(data2.index) != "") {
formData.value[data2.index].value = data2.val;
console.log(formData.value, '=-==')
}
}
function uploadHandle(tem, index) {
formData.value[index].value = tem
}
function timeHandle(val, index) {
formData.value[index].value = val
}
</script>
<style lang="scss" scoped>
.menu-style {
padding: 20rpx 0;
background: #fff;
margin: 20rpx;
border-radius: 8rpx;
}
.buttonBox {
width: calc(100% - 40rpx);
height: 84rpx;
color: white;
display: flex;
align-items: center;
justify-content: center;
background-color: #3C9CFF;
border-radius: 50rpx;
margin: 20rpx;
// position: fixed;
bottom: 50px;
left: 0;
right: 0;
z-index: 999;
}
</style>
可能有写的不好的地方。多多指教