后台数据的结构如下:
"productfactors": [
{//产品投保要素
"factortype": "Period",//要素类型
"datatype": "08",//数据类型
"productfactorvalues": [
{ //投保要素值列表
"factorvalue": "1Y",//投保要素值计算值
"factordisplayvalue": "1年",//投保要素值显示值
"isdisplay": "Y",//是否显示
"isdefaultvalue": "Y",//是否为默认值
"showorder": 1//排序序号
},
{ //投保要素值列表
"factorvalue": "2Y",//投保要素值计算值
"factordisplayvalue": "1年",//投保要素值显示值
"isdisplay": "Y",//是否显示
"isdefaultvalue": "N",//是否为默认值
"showorder": 2//排序序号
},
]
},
{//产品投保要素
"factortype": "Period",//要素类型
"datatype": "08",//数据类型
"productfactorvalues": [
{ //投保要素值列表
"factorvalue": "1Y",//投保要素值计算值
"factordisplayvalue": "1岁",//投保要素值显示值
"isdisplay": "Y",//是否显示
"isdefaultvalue": "Y",//是否为默认值
"showorder": 1//排序序号
},
{ //投保要素值列表
"factorvalue": "2Y",//投保要素值计算值
"factordisplayvalue": "2岁",//投保要素值显示值
"isdisplay": "Y",//是否显示
"isdefaultvalue": "N",//是否为默认值
"showorder": 2//排序序号
}
]
}
],
html代码如下:
{{items.factortypename}}
{{items.productfactorvalues[ValData[items.factortype]].factordisplayvalue}}
首先要根据接口把数据获取回来,获取回来的数据进行处理,得到外层的数组就是上面的productfactors数组,只是我们在data中声明一个变量数组来接收获取回来的数据,例如:productfactorslist:[]。
正如官方文档所说的uni-app中picker,picker中range的值是一个数组,因为是双层数组,我们所需要的下拉框的值是一个数组,不需要便利,这时候我们如果通过items.productfactorvalues取值,再通过@change事件把我们下拉选择的索引传给e.target.value,这样我们是可以修改下拉框的值,但是会造成遍历出来的下拉框会联动,因为他们的索引没有区分,所以想要区分每一个下拉框的值,我们就需要在本质上区分他们的索引,每一个下拉框有自己的索引,这样选择一个下拉框的索引才不会干扰其他的下拉框。
我的做法是根据数据所获取回来的投保要素的要素类型factortype进行区分,首先要创建一个空对象,代码如下:
ValData:{},
然后再向空对象中传参数和值,参数就是我们遍历出来的每一个要素类型factortype,这是我们就要在初始加载页面的时候Onload中获取数据时候操作,代码如下:
success:(res) => {
var Data = res.data;
this.product = Data.data.product;
this.Initprem = this.product.initprem;
// this.productfactorslist = Data.data.product.productfactors;
var Datalist = [];
Datalist = Data.data.product.productfactors;
console.log(Datalist);
var len = Datalist.length;
this.productfactorslist = Datalist;
// 下拉框初始赋值
Datalist.forEach((Val,Valindex)=>{
if(Datalist[Valindex].datatype == '08'){
Val.productfactorvalues.forEach(({factorvalue,isdefaultvalue},index)=>{
if(isdefaultvalue == 'Y'){
this.ValData[Val.factortype]=index;
this.ValList[Val.factortype]=factorvalue;
}
})
}
})
console.log(this)
console.log(this.productfactorslist);
},
fail:(res)=> {
console.log(res);
}
这时候还会有一个下拉框初始显示默认值,是根据isdefaultvalue 属性来确定的,上面的数据中有,这样通过forEach遍历数组就会给每一个下拉框附一个初始值,初始值是根据索引来获取的在picker中,这样在页面加载的时候我们直接把获取到默认的索引值直接赋给所选取的索引值e.target.value即可,代码如下:
bindPickerChange: function(items,e) {
console.log(e)
console.log(items)
var id = items.factortype;
this.ValData[id] = e.target.value;
this.ValList[id] = items.productfactorvalues[this.ValData[items.factortype]].factorvalue;
console.log(this)
this.$forceUpdate();
},
这样就可以选择单独的下拉框,索引值不会共用了,就可以数据单独选择了,在这里他也出现了一个问题,因为vue框架在加载多层数据时候有时候不会自动自动渲染数据,需要我们强制让页面选自然数据,只需要在change事件末尾加一个this.$forceUpdate();就可以强制渲染,完成数据加载。
在完成下拉框的数据加载之后,选择完数据之后我们就要把选择的数据传到后台进行提交,这时候就需要进行表单提交了,但是这个uni-app中picker的表单提交只能默认在e.target.detail中,并且我不太懂他传过去数据的属性是怎末来的,所以我还是自己写了个对象,用来接受表单提交的数据,和刚才获取索引的时候的方法一样。过程如下:
首先建立一个空对象ValList:{},
然后在页面初始加载数据的时候就给ValList赋予一个初始的属性和值,属性还是刚才数据中的投保要素类型factorvalue,值就是根据isdefaultvalue来判断获取的一个值,代码如下:this.ValList那行
Datalist.forEach((Val,Valindex)=>{
if(Datalist[Valindex].datatype == '08'){
Val.productfactorvalues.forEach(({factorvalue,isdefaultvalue},index)=>{
if(isdefaultvalue == 'Y'){
this.ValData[Val.factortype]=index;
this.ValList[Val.factortype]=factorvalue;
}
})
}
})
然后再@change事件中也要根据刚才获取的索引来取值并添加到我们创建的空对象ValList中,代码如下:this.ValList那行
bindPickerChange: function(items,e) {
console.log(e)
console.log(items)
var id = items.factortype;
this.ValData[id] = e.target.value;
this.ValList[id] = items.productfactorvalues[this.ValData[items.factortype]].factorvalue;
console.log(this)
this.$forceUpdate();
},
这时候我们选择一个值之后就会创建一个空对象ValData存储我们获取值的属性和索引,同时创建一个空对象ValList来存储我们要提交的表单的值,也就是获取的下拉框的属性和值。控制台打印出的this的值如下:
实现的下拉框效果如下:
选择一个下拉框修改值之后