主组件:
<formPage :urlApi="formUrl" :type="formType" :mer_id="item.mer_id" :json="formJson" @saveFromData="saveFromData"></formPage>
参数:
mer_id: 0,
formUrl: '*****', // 表单api请求地址
formType: true,
fromJson: '', // {"cartId":{"75":[722636],"76":[124541]}}
fromDataSub: {} ,//提交对象 最后将其转换为json字符串
方法:
authFromData(data){
if(typeof data == "object" && data.question_id && data.data.length > 0){
try{
data.data.forEach((item, index)=> {
if(item.required == "required" || item.required == true){
if (typeof item.use == 'object'){
if(item.use != undefined && item.use.length > 0){
}else {
throw new Error("退出循环");
}
} else {
if(item.use == ''){
throw new Error("退出循环");
}
}
}
})
}catch(e){
// 出现异常
return false
}
}else {
return false
}
return true
},
// 表单数据提交参数
saveFromData(data){
console.log(data, '接收数据')
// 传输数据当form提交中
this.fromDataSub = data;
},
子组件: form 表单
<template>
<view v-if="type" class="content-from">
<view class="forData">
<view class="from" v-for="(item, index) in fromData" :key="index">
<view v-if="item.type == 'text'" class="input">
<view class="title"><span class="require" v-if="item.required">*</span>{{item.key}}</view>
<view class="text">
<!-- @blur="inputFrom(e, index)" -->
<input type="text" v-model="fromData[index].use" @blur="mountedBlur">
</view>
</view>
<view v-if="item.type == 'select'" class="select">
<view class="item">
<view class="title"><span class="require" v-if="item.required">*</span>{{item.key}}</view>
<view class="option" @click.stop="showSelectClick">{{fromData[index].use !='' ?fromData[index].use:'请选择'}}</view>
</view>
<view class="seletcList" v-if="showSelect">
<view class="select-item" v-if="li" v-for="(li, selectKey) in item.value" :key="selectKey">
<view class="rideo" :class="(fromData[index].use != undefined && fromData[index].use == li)?'rideoSelect':''" @click="selectFrom(li, index, item)"></view>
<view class="itemLi" @click.stop="selectFrom(li, index, item)">
{{li}}
</view>
</view>
</view>
</view>
<view v-if="item.type == 'redio'" class="redio">
<view class="title"><span class="require" v-if="item.required">*</span>{{item.key}}</view>
<view class="redioList">
<view class="item" v-if="redio" v-for="(redio, indexRe) in item.value" :key="indexRe">
<view class="rideo" :class="(fromData[index].use != undefined && fromData[index].use == redio)?'rideoSelect':''" @click="redioFrom(redio, index, item)"></view>
<view class="itemLi" @click.stop="redioFrom(redio, index, item)" >{{redio}}</view>
</view>
</view>
</view>
<view class="checkbox" v-if="item.type == 'checkbox'">
<view class="title"><span class="require" v-if="item.required">*</span>{{item.key}}</view>
<view class="checkboxList">
<view class="item" v-if="checkbox" v-for="(checkbox, checkboxRe) in item.value" :key="checkboxRe">
<view class="rideo" :class="(fromData[index].use != undefined && fromData[index].use.length >0 && fromData[index].use.indexOf(checkbox) !== -1)?'rideoSelect':''" @click="checkboxFrom(checkbox, index, item)"></view>
<view class="itemLi" @click.stop="checkboxFrom(checkbox, index, item)" >{{checkbox}}</view>
</view>
</view>
</view>
</view>
</view>
</view>
</template>
<!-- 页面获取当前需要显示的表单数据 从目标也跳转到当前页面 并且将请求地址发送过来 -->
<script>
import { getListFrom } from '@/api/dept_auth.js';
export default {
props: {
urlApi: {
type: String,
default: ''
},
type: { // 显示状态
type: Boolean,
default: false
},
mer_id: {
type:String,
default: ''
},
json: {
type: String,
default: ''
}
},
data() {
return {
fromData: {},
SubmitData: {},
showSelect: false,
parme: 0,// 用于数据监听切换作用 参数值并无任何其他效果
}
},
watch: {
mer_id: {
handler(nVal,oVal){
console.log(nVal,"我现在是在请求表单数据")
}
},
},
mounted() {
this.urlApi = this.urlApi;
console.log(this.json,"我先请求一下")
this.getFromDataPage()
},
methods: {
// inputFrom(e, index){
// let text = e.default
// this.fromData.index['use'] = text;
// },
mountedBlur(){
this.parme += 1;
this.synData()
},
// 点击select之后将其数据放入到提交数据中
selectFrom(li, index, item){
// 选中项使用use 表示当前使用的值
this.fromData[index].use = li;
this.parme += 1;
this.showSelectClick();
this.synData()
},
redioFrom(li, index, item){
this.fromData[index].use = li;
this.parme += 1;
this.synData()
},
checkboxFrom(li, index, item){
if(this.fromData[index].use != undefined && this.fromData[index].use.length > 0){
let UseIndex = this.fromData[index].use.indexOf(li);
if(UseIndex === -1){
this.fromData[index].use.push(li);
}else {
this.fromData[index].use.splice(UseIndex, 1);
}
}else {
this.fromData[index].use = [li];
}
this.parme += 1;
this.synData()
console.log(this.fromData)
},
showSelectClick(){
this.showSelect = !this.showSelect
this.parme += 1;
},
getFromDataPage(){
getListFrom(this.urlApi, this.json).then(res => {
if(this.mer_id){
let param = res.data[this.mer_id]
if(typeof param == 'object'){
this.fromData = param.data;
this.SubmitData = param
}else {
this.SubmitData = JSON.parse(param)
this.fromData = JSON.parse(param).data;
}
// 处理数据
this.fromData.forEach((item, index)=>{
if(item.value && item.value.indexOf(";")!== -1){
this.fromData[index].value = item.value.split(";"); // 将其变成数组类型
this.fromData[index].use = [];
}else{
this.fromData[index].use = '';
}
})
console.log(this.fromData, "初始数据")
}else {
this.type = false;
this.fromData = {};
}
}).catch(err=> {
console.log("请求失败");
})
},
// 同步数据
synData(){
this.SubmitData.data = this.fromData
this.$emit("saveFromData", this.SubmitData);
}
}
}
</script>
<style lang="scss">
.content-from{
background-color: #fff;
padding: 0 20rpx;
margin-bottom: 10rpx;
.forData{
padding: 0 20rpx;
.from {
padding: 20rpx 0;
.input{ // 上下排列
display: flex;
justify-content: left;
width: 100%;
align-items: left;
flex-wrap: wrap; // 允许换行
.title{
height: 2rem;
display: block;
width: 100%;
font-size: 32rpx;
.require{
color: red;
}
}
.text{
width: 100%;
height: 2rem;
font-size: 32rpx;
input{
height: 1.5rem;
display: block;
width: 100%;
background-color: #fff;
border-radius: 5rpx;
border: 1rpx solid #d4d4d4;
padding-left: 10rpx;
}
}
}
.select {
width: 100%;
position: relative;
.item{
display: flex;
height: 2rem;
justify-content: space-between;
align-items: left;
.title{
flex: 50%;
font-size: 32rpx;
.require{
color: red;
}
}
.option{
flex: 50%;
font-size: 32rpx;
color: #ababab;
text-align: right;
padding-right: 20rpx;
}
}
.seletcList{
display: flex;
position: absolute;
top: 2rem;
left: 0;
height: auto;
background-color: #fff;
border-radius: 5rpx;
width: 100%;
z-index: 10;
flex-wrap: wrap;
padding: 20rpx;
.select-item{
width: 100%;
height: 2rem;
background-color: #fff;
color: #222;
display: flex;
justify-content: left;
align-items: center;
.rideo{
margin: 5rpx;
padding: 5rpx;
width: 30rpx;
height: 30rpx;
border-radius: 50%;
background-color: #fff;
border: 1rpx solid #d4d4d4;
}
.rideoSelect{
background-color: red !important;
border: 1rpx solid red !important;
}
.itemLi{
flex: auto;
font-size: 32rpx;
color: #222;
text-indent: 0.5rem;
}
.bgSelect{
background-color: #ff9b43;
color: #fff;
}
}
}
}
.redio{
width: 100%;
display: flex;
justify-content: left;
flex-wrap: wrap;
align-items: left;
position: relative;
.title{
width: 100%;
font-size: 32rpx;
.require{
color: red;
}
}
.redioList{
width: 100%;
.item{
width: 100%;
display: flex;
justify-content: left;
align-items: center;
flex-wrap: wrap;
.rideo{
margin: 5rpx;
padding: 5rpx;
width: 30rpx;
height: 30rpx;
border-radius: 50%;
background-color: #fff;
border: 1rpx solid #d4d4d4;
}
.rideoSelect{
background-color: red !important;
border: 1rpx solid red !important;
}
.itemLi{
flex: auto;
font-size: 32rpx;
color: #222;
text-indent: 0.5rem;
}
}
}
}
.checkbox{
width: 100%;
display: flex;
justify-content: left;
flex-wrap: wrap;
align-items: left;
position: relative;
.title{
width: 100%;
font-size: 32rpx;
.require{
color: red;
}
}
.checkboxList{
width: 100%;
.item{
width: 100%;
display: flex;
justify-content: left;
align-items: center;
flex-wrap: wrap;
.rideo{
margin: 5rpx;
padding: 5rpx;
width: 30rpx;
height: 30rpx;
border-radius: 5rpx;
background-color: #fff;
border: 1rpx solid #d4d4d4;
}
.rideoSelect{
background-color: red !important;
border: 1rpx solid red !important;
}
.itemLi{
flex: auto;
font-size: 32rpx;
color: #222;
text-indent: 0.5rem;
}
}
}
}
}
}
}
</style>