一、需求
地址選擇列表
- 默認地址置頂(字段:isDefult,只有一條)
- 默認勾選默認地址
- 只能勾選一條地址,且勾選地址要顯示成打勾
- 勾選好地址后,點擊確定按鈕,要發(fā)送請求
ps. 圖中的true和false 只是為了方便查看實時數(shù)據(jù);

二、需求實現(xiàn)
先上一個不大簡便的方法,組長說用‘醫(yī)院和科室’的選擇思路來做更好,后續(xù)優(yōu)化后再補。
大致思路:
1、向請求來的數(shù)據(jù)里,手動新增一個字段 ‘check’ ,因為默認地址要默認打勾,且默認的字段‘isDefult’也是一個Boolean值,所以只需要讓check的初始值等于idDefult的值就可以。
2、通過isdeful的值,對數(shù)組進行排序。
3、在data里設(shè)置對象defultForm:{},,初始值為默認地址的值,之后點擊哪條地址,defultForm就變成哪條地址的值,點擊確定按鈕后執(zhí)行的請求以其為參數(shù)。
三、所遇問題
我定義了一個公共函數(shù),請求地址列表數(shù)據(jù),返回一個this.commpatAddressList = list
async mixin_get_commpat_address_list(){
let {code,list} = await this.$http('smarthos.user.pat.address.list');
if(code==0){
return this.commpatAddressList = list
})
}
},
項目頁面組件
<template>
<div>
<v-header>
<span @click="toAddAddress" slot="right">新建地址</span>
選擇送藥地址
</v-header>
<div>
<choose-item v-for="(o,i) in commpatAddressList" :key="i"
:info="o" :index="i" @checkAdd="checkAdd"></choose-item>
</div>
<button v-if="commpatAddressList && commpatAddressList.length>0" @click="addShip" >
確定寄到該地址</button>
</div>
</template>
<script>
export default {
data(){
return{
commpatAddressList:[], //傳給子組件的地址數(shù)組
defultForm:{}, //確認按鈕的http請求參數(shù)
}
},
methods:{
// 獲取收貨地址列表
async getAddressList(){
await this.mixin_get_commpat_address_list();
},
// 默認地址置頂,每條數(shù)據(jù)都添加check字段
//這種遍歷太麻煩,后面的優(yōu)化的方法
sortAddressList(){
let newAddList=[];
let defult = [];
for(let obj of this.commpatAddressList){
if (obj.isDefault==true){
obj.check = true;
defult = obj;
this.defultForm = obj;
}else{
obj.check = false;
newAddList.push(obj);
}
}
newAddList.unshift(defult);
this.commpatAddressList= newAddList;
},
//點擊地址時,子組件觸發(fā)的頁面組件函數(shù)
//將地址數(shù)組中所有數(shù)據(jù)的check字段都改為false,
//子組件返回的index數(shù)字所對應(yīng)的那條數(shù)據(jù)的check字段值變?yōu)閠rue
checkAdd(info, index){
let newAddList=[];
for(let obj of this.commpatAddressList){
obj.check=false;
newAddList.push(obj);
}
newAddList[index].check = true;
this.commpatAddressList.splice(0);
//嘗試了兩種this.$set方式,但是都沒有渲染
/* let news = newAddList[index];
news.check = true;
this.$set(this.commpatAddressList, index, news);*/
this.defultForm = info;
this.commpatAddressList=[].concat(newAddList);
//this.$set(this.$data, 'commpatAddressList', newAddList);
},
}
}
</script>
項目子組件
<template>
<div @click="tocheckAdd">
<div >
<font v-if="info.check"></font>
<font v-else ></font>
</div>
<div >
<p ><span class="flex0 ziti">{{info.name}}</span><span>{{info.mobile}}</span></p>
<p >{{info.areaName}},{{info.address}}</p>
</div>
</div>
</template>
<script>
export default {
name: "choose-item",
props:{
info:{
type:Object,
},
index:{
type:Number,
}
},
methods:{
tocheckAdd(){
this.$emit('checkAdd', this.info, this.index)
},
},
}
</script>
但是這樣運行之后,點擊地址,check的確發(fā)生了改變,但是頁面上打勾選項一直沒有反應(yīng);

然后試了
1、watch函數(shù)、
2、在addCheck里采用this.$set的方法修改check值,
3、采用splice方式歸零commpatAddressList數(shù)組,
4、 同步傳遞數(shù)據(jù) :info.sync="o",點擊地址
仍舊沒有反應(yīng);
最后找到了最初的公共的請求函數(shù),問題就出在 return this.commpatAddressList = list 里,此處的 this.commpatAddressList 意味著初始化了組件的數(shù)據(jù) ‘this.commpatAddressList’,然后在父組件中,再添加check,check也只存在于js層,而不受vue的承認。
所以解決辦法是,在公共的請求函數(shù)里,就加上check字段
async mixin_get_commpat_address_list(){
let {code,list} = await this.$http('smarthos.user.pat.address.list');
if(code==0){
//代替了遍歷數(shù)組添加check字段 以及 添加sort字段方便排序
this.commpatAddressList = list.map(r=>{
r.check=r.isDefault; //默認地址默認打勾
r.sort=r.isDefault?1:0; //idDefult為true就為1,否則為0
return r;
}).sort((a,b)=>{ //根據(jù)sort字段將數(shù)組降序排列,默認字段置頂
return b.sort-a.sort;
});
}
},