uniapp 开发微信小程序总结(五)实用组件

1、input-text.vue 组件,支持 输入姓名(realname 不可输入数字)、手机号(phone不可输入汉字)

 1 <template>
 2     <view class="cu-form-group padding-lr-0 padding-tb-xs margin-lr">
 3         <view class="title">{{title}}<text class="unit">{{unit}}</text></view>
 4         <input class="text-right" :disabled="disabled":type="type" :placeholder="placeholder" :value="value" @input="inputHandle"></input>
 5     </view>
 6 </template>
 7 
 8 <script>
 9     export default{
10         props:{
11             title:String,
12             placeholder:String,
13             disabled:{
14                 type:Boolean,
15                 default:false
16             },
17             value: String || Number,
18             unit: String,
19             type:String,
20             field:String
21         },
22         data(){
23             return{
24                 inputValue:this.value
25             }
26         },
27         methods:{
28             inputHandle(e){
29                 this.$emit('input',{value:e.detail.value})
30                 let strategy = {
31                     realname:function(){
32                         return e.detail.value.replace(/d/g,"")
33                     },
34                     phone:function(){
35                         return e.detail.value.replace(/D/g,"")
36                     }
37                 }
38                 if(strategy[this.field]){
39                     return strategy[this.field]()
40                 }
41             }
42         }
43     }
44 </script>
45 
46 <style lang="scss" scoped>
47     .cu-form-group {
48         border-bottom: 1upx solid #f9f9f9;
49         .title{
50             font-size: 34upx;
51             height: auto;
52             line-height: 1;
53             .unit{
54                 color: #9A9A9A;
55                 font-size: 24upx;
56                 align-self: flex-end;
57                 padding-left: 10upx;
58             }
59         }
60         input{
61             font-size: 30upx;
62             line-height: 1;
63             color: #9A9A9A;
64         }
65     }
66 </style>

2、picker-date.vue 

 1 <template>
 2     <view class="cu-form-group padding-lr-0 padding-tb-xs margin-lr">
 3         <view class="title">{{title}}<text class="unit">{{unit}}</text></view>
 4         <picker @change="change" :value="value" mode="date" :start="start" :end="end">
 5             <view class="picker">
 6                 {{value||"未填写"}}
 7             </view>
 8         </picker>
 9     </view>
10 </template>
11 
12 <script>
13     function getDate(type) {
14         const date = new Date();
15         let year = date.getFullYear();
16         let month = date.getMonth() + 1;
17         let day = date.getDate();
18 
19         if (type === 'start') {
20             year = year - 100;
21         } else if (type === 'end') {
22             year = year + 100;
23         }
24         month = month > 9 ? month : '0' + month;;
25         day = day > 9 ? day : '0' + day;
26         return `${year}-${month}-${day}`;
27     }
28     export default{
29         props:{
30             title:String,
31             value:String,
32             start:{
33                 type:String,
34                 default: getDate('start')
35             },
36             end:{
37                 type:String,
38                 default:getDate('end')
39             },
40             unit: String,
41         },
42         created() {
43             this.value
44         },
45         methods:{
46             change(e){
47                 this.$emit("change",{value:e.detail.value})
48             },
49             
50         }
51     }
52 </script>
53 
54 <style lang="scss" scoped>
55     .cu-form-group {
56         border-bottom: 1upx solid #f9f9f9;
57         .title{
58             font-size: 34upx;
59             height: auto;
60             line-height: 1;
61             .unit{
62                 color: #9A9A9A;
63                 font-size: 24upx;
64                 align-self: flex-end;
65                 padding-left: 10upx;
66             }
67         }
68         picker .picker{
69             font-size: 30upx;
70             color: #9A9A9A;
71         }
72     }
73 </style>

3、picker-default.vue

 1 <template>
 2     <view class="cu-form-group padding-lr-0 padding-tb-xs margin-lr">
 3         <view class="title">{{title}}<text class="unit">{{unit}}</text></view>
 4         <picker @change="change" v-model="value" :range="range" >
 5             <view class="picker">
 6                 {{range[value]||"请选择"}}
 7             </view>
 8         </picker>
 9     </view>
10 </template>
11 
12 <script>
13     export default{
14         props:{
15             title:String,
16             range:Array,
17             value:{
18                 type:Number,
19                 default:0
20             },
21             unit: String,
22         },
23         methods:{
24             change(e){
25                 this.$emit("change",{value:Number(e.detail.value)})
26             }
27         }
28     }
29 </script>
30 
31 <style lang="scss" scoped>
32     .cu-form-group {
33         border-bottom: 1upx solid #f9f9f9;
34         .title{
35             font-size: 34upx;
36             height: auto;
37             line-height: 1;
38             .unit{
39                 color: #9A9A9A;
40                 font-size: 24upx;
41                 align-self: flex-end;
42                 padding-left: 10upx;
43             }
44         }
45         picker .picker{
46             font-size: 30upx;
47             color: #9A9A9A;
48         }
49     }
50 </style>

4、picker-multiSelector.vue

 1 <template>
 2     <view class="cu-form-group padding-lr-0 padding-tb-xs margin-lr">
 3         <view class="title">{{title}}<text class="unit">{{unit}}</text></view>
 4         <picker mode="multiSelector" @change="change" v-model="value" :range="range">
 5             <view class="picker">
 6                 {{!range[0][value[0]]&&!range[1][value[1]]?'未填写':(range[0][value[0]]||'未填写')+''+(range[1][value[1]]||'- 未填写')}}
 7             </view>
 8         </picker>
 9     </view>
10 </template>
11 
12 <script>
13     export default {
14         props:{
15             title:String,
16             range:Array,
17             value:Array,
18             unit: String
19         },
20         methods:{
21             change(e){
22                 this.$emit("change",{value:e.detail.value})
23             }
24         }
25     }
26 </script>
27 
28 <style lang="scss" scoped>
29     .cu-form-group {
30         border-bottom: 1upx solid #f9f9f9;
31         .title{
32             font-size: 34upx;
33             height: auto;
34             line-height: 1;
35             .unit{
36                 color: #9A9A9A;
37                 font-size: 24upx;
38                 align-self: flex-end;
39                 padding-left: 10upx;
40             }
41         }
42         picker .picker{
43             font-size: 30upx;
44             color: #9A9A9A;
45         }
46     }
47 </style>

5、picker-range-key.vue

 1 <template>
 2     <view class="cu-form-group padding-lr-0 padding-tb-xs margin-lr">
 3         <view class="title">{{title}}<text class="unit">{{unit}}</text></view>
 4         <picker @change="change" v-model="value" :range="range" range-key="name">
 5             <view class="picker">
 6                 {{range[value].name||"请选择"}}
 7             </view>
 8         </picker>
 9     </view>
10 </template>
11 
12 <script>
13     export default{
14         props:{
15             title:String,
16             range:Array,
17             value:{
18                 type:Number,
19                 default:0
20             },
21             unit: String,
22         },
23         methods:{
24             change(e){
25                 const value = Number(e.detail.value)
26                 this.$emit("change",{value:value})
27             }
28         }
29     }
30 </script>
31 
32 <style lang="scss" scoped>
33     .cu-form-group {
34         border-bottom: 1upx solid #f9f9f9;
35         .title{
36             font-size: 34upx;
37             height: auto;
38             line-height: 1;
39             .unit{
40                 color: #9A9A9A;
41                 font-size: 24upx;
42                 align-self: flex-end;
43                 padding-left: 10upx;
44             }
45         }
46         picker .picker{
47             font-size: 30upx;
48             color: #9A9A9A;
49         }
50     }
51 </style>

6、title-bar.vue

 1 <template>
 2     <view class="title-bar flex align-center">
 3         <view class="title-icon">
 4             <image :src="icon" mode="aspectFit"></image>
 5         </view>
 6         <view class="name flex-sub">
 7             {{title}}
 8         </view>
 9         <slot name="btns"></slot>
10     </view>
11 </template>
12 
13 <script>
14     export default{
15         props:{
16             title:String,
17             icon:String
18         }
19     }
20 </script>
21 
22 <style lang="scss" scoped>
23     .title-bar{
24         padding: 30upx 28upx;
25         .title-icon{
26              40upx;
27             height: 40upx;
28             margin-right: 24upx;
29             image{
30                  100%;
31                 height: 100%;
32             }
33         }
34         .name{
35             font-size:30upx;
36             font-weight:400;
37             color: #2C3850;
38         }
39     }
40 </style>

7、以上组件的运用。(页面逻辑值得记录一下)

  1 <template>
  2     <view style="overflow-x: hidden;">
  3         <view class="select-box flex flex-direction align-center">
  4             <view class="tip padding-tb">
  5                 (可多选)完善不同身份的信息即可获得对应礼券
  6             </view>
  7             <view class="options flex flex-direction">
  8                 <view class="item flex justify-between margin-bottom" v-show="item.type<4" :class="{'current': selected.indexOf(item.type)>=0}" v-for="(item,index) in configs" :key="index">
  9                     <view class="left flex flex-direction align-center justify-center" @click="toggle(item.type)">
 10                         <view class="check-icon">
 11                             <image src="/static/account/selected-icon.png" mode="aspectFit"></image>
 12                         </view>
 13                         <view class="uncheck-icon">
 14                             <image src="/static/account/select-icon.png" mode="aspectFit"></image>
 15                         </view>
 16                         
 17                         <view class="icon">
 18                             <image :src="item.icon" mode="aspectFit"></image>
 19                         </view>
 20                         <text class="name">{{item.name}}</text>
 21                     </view>
 22                     <view :class="{'justify-between':item.coupon,'justify-center':!item.coupon}" class="right flex flex-direction bg-red" v-if="item.receive" @click="goMiniProgram">
 23                         <block v-if="item.coupon">
 24                             <view class="info flex align-center">
 25                                 <view class="flex-sub flex align-center">
 26                                     <text class="num margin-right-lg">¥{{item.coupon.discount}}</text>
 27                                     <image class="get-icon" src="/static/account/get-icon.png" mode="aspectFit"></image>
 28                                 </view>
 29                                 <text class="text" style="margin-top:-15upx;font-size: 22upx;">去使用</text>
 30                                 <text class="cuIcon-usefullfill text-white" style="margin-top:-15upx;transform: rotate(90deg);font-size: 26upx;"></text>
 31                             </view>
 32                             <view class="tips">
 33                                 {{item.coupon.tip}} 
 34                             </view>
 35                         </block>
 36                         <block v-else>
 37                             <div class="info flex align-center text-xs" style="padding-bottom: 0;">优惠券被领光啦!期待下个惊喜</div>
 38                         </block>
 39                     </view>
 40                     <view :class="{'justify-between':item.coupon,'justify-center':!item.coupon}" class="right flex flex-direction" v-else @click="toggle(item.type)">
 41                         <block v-if="item.coupon">
 42                             <view class="info flex align-center">
 43                                 <view class="flex-sub flex align-center">
 44                                     <text class="num margin-right-lg">¥{{item.coupon.discount}}</text>
 45                                 </view>
 46                                 <text class="text">完善信息后领取</text>
 47                             </view>
 48                             <view class="tips">
 49                                 {{item.coupon.tip}}
 50                             </view>
 51                         </block>
 52                         <block v-else>
 53                             <div class="info flex align-center text-xs" style="padding-bottom: 0;">优惠券被领光啦!期待下个惊喜</div>
 54                         </block>
 55                     </view>
 56                 </view>
 57             </view>
 58         </view>
 59         <!-- 表单 -->
 60         <view class="form-box">
 61             <form @submit="submitEdit"> 
 62                 <view class="my-info-box" v-show="showMy">
 63                     <title-bar :title="'我的信息'" :icon="myGender=='男'?'/static/account/honey-icon.png':'/static/account/my-icon.png'"></title-bar>
 64                     <block v-for="(item,index) in hasInfos" :key="index">
 65                         <input-text :disabled="true" :title="item.label" :value="item.value"  v-if="item.value"></input-text>
 66                     </block>
 67                     <view class="line" v-if="hasInfos.length>0"></view> 
 68                     <block v-for="(item,index) in my" :key="index">
 69                         <input-text :disabled="true" :title="item.label" :value="item.value"  v-if="item.field == 'birthday'"></input-text>
 70                         <input-text :disabled="true" :title="item.label" :value="item.value"  v-if="item.field == 'phone'"></input-text>
 71                         <input-text :disabled="true" :title="item.label" :value="myGender"  v-if="item.field == 'gender'"></input-text>
 72                         <input-text :title="item.label" type="text" :placeholder="'请输入' + item.label" :value="item.value" @input="change(item,$event)" :field="item.field" v-if="item.field == 'realname'"></input-text>
 73                         <!-- <picker-date :end="NowDate" :title="item.label" :placeholder="'请输入' + item.label" :value="item.value" @change="change(item,$event)" v-if="item.field == 'birthday'"></picker-date> -->
 74                         <!-- <picker-range-key :title="item.label" :range="Gender" :value="item.value" @change="change(item,$event)" v-if="item.field == 'gender'"></picker-range-key> -->
 75                         <!-- <picker-default :title="item.label" :range="Gender" :value="item.value" @change="change(item,$event)" v-if="item.field == 'gender'"></picker-default> -->
 76                         <picker-default :title="item.label" :range="HeightRange" :value="item.value" @change="change(item,$event)" v-if="item.field == 'stature'"></picker-default>
 77                         <picker-multi-selector :title="item.label" :range="BraSize" :value="item.value" @change="change(item,$event)" v-if="item.field == 'braSize'&&showMyBraSize"></picker-multi-selector>
 78                         <picker-default :title="item.label"  :unit="'(cm)'" :range="UnderwearSize" :value="item.value" @change="change(item,$event)" v-if="item.field == 'briefsSize'"></picker-default>
 79                         
 80                     </block>
 81                     <view class="line-lg"></view>
 82                 </view>
 83                 <view class="honey-info-box" v-show="showHoney">
 84                     <title-bar :title="'我的TA信息'" :icon="(honeyGender=='男'||(myGender=='女'&&!honeyGender))?'/static/account/honey-icon.png':'/static/account/my-icon.png'"></title-bar>
 85                     <block v-for="(item,index) in honey" :key="index">
 86                         <input-text :title="item.label" type="number" :placeholder="'请输入' + item.label" :value="item.value" @input="change(item,$event)" :field="item.field" v-if="item.field == 'phone'"></input-text>
 87                         <input-text :title="item.label" type="text" :placeholder="'请输入' + item.label" :value="item.value" @input="change(item,$event)" :field="item.field" v-if="item.field == 'realname'"></input-text>
 88                         <picker-date :end="NowDate" :title="item.label" :placeholder="'请输入' + item.label" :value="item.value" @change="change(item,$event)" v-if="item.field == 'birthday'"></picker-date>
 89                         <picker-range-key :title="item.label" :range="Gender" :value="item.value" @change="changeHoneyGender(item,$event)" v-if="item.field == 'gender'"></picker-range-key>
 90                         <picker-default :title="item.label" :range="HeightRange" :value="item.value" @change="change(item,$event)" v-if="item.field == 'stature'"></picker-default>
 91                         <picker-multi-selector :title="item.label" :range="BraSize" :value="item.value" @change="change(item,$event)" v-if="item.field == 'braSize'&&showHoneyBraSize"></picker-multi-selector>
 92                         <picker-default :title="item.label" :unit="'(cm)'" :range="UnderwearSize" :value="item.value" @change="change(item,$event)" v-if="item.field == 'briefsSize'"></picker-default>
 93                         
 94                     </block>
 95                     <view class="line-lg"></view>
 96                 </view>
 97                 <view class="babies-info-box" v-for="(baby,index) in babies" :key="index" v-show="showBabies">
 98                     <title-bar :title="'宝贝的信息'+(index+1)" :icon="'/static/account/baby-icon.png'">
 99                         <template v-slot:btns>
100                             <view class="text-red margin-right-sm" @click="deleteForBaby(index)">删除宝贝</view>
101                         </template>
102                     </title-bar>
103                     <block v-for="(item,itemIndex) in baby" :key="item.id">
104                         <input-text :title="item.label" type="number" :placeholder="'请输入' + item.label" :value="item.value" @input="changBaby(index,itemIndex,$event)" :field="item.field" v-if="item.field == 'phone'"></input-text>
105                         <input-text :title="item.label" type="text" :placeholder="'请输入' + item.label" :value="item.value" @input="changBaby(index,itemIndex,$event)" :field="item.field" v-if="item.field == 'realname'"></input-text>
106                         <picker-date :end="NowDate" :title="item.label" :placeholder="'请输入' + item.label" :value="item.value" @change="changBaby(index,itemIndex,$event)" v-if="item.field == 'birthday'"></picker-date>
107                         <picker-range-key :title="item.label" :range="Gender" :value="item.value" @change="changBaby(index,itemIndex,$event)" v-if="item.field == 'gender'"></picker-range-key>
108                         <picker-default :title="item.label" :range="BabyHeightRange" :value="item.value" @change="changBaby(index,itemIndex,$event)" v-if="item.field == 'stature'"></picker-default>
109                         <picker-multi-selector :title="item.label" :range="BraSize" :value="item.value" @change="changBaby(index,itemIndex,$event)"  v-if="item.field == 'braSize'"></picker-multi-selector>
110                         <picker-default :title="item.label"  :unit="'(cm)'" :range="UnderwearSize" :value="item.value" @change="changBaby(index,itemIndex,$event)" v-if="item.field == 'briefsSize'"></picker-default>
111                     </block>
112                     <view class="line"></view>
113                 </view>
114                 <view class="add-box" v-show="showBabies&&needAddBaby">
115                     <view class="add-btn text-red flex justify-center align-center">
116                         <view class="inline-flex justify-center align-center" @click="addBaby">
117                             <image src="/static/account/addcircle-icon.png" class="add-circle" mode="aspectFit"></image>
118                             <text>新增我的宝贝</text>
119                         </view>
120                     </view>
121                     <view class="add-tip text-center">
122                         {{addBabyDesc}}
123                     </view>
124                 </view>
125                 <view class="submit-btn flex justify-center align-center" v-if="!loading">
126                     <button class="cu-btn round lg bg-red" form-type="submit">提交</button>
127                 </view>
128             </form> 
129         </view>
130         
131         <home-btn></home-btn>
132     </view>
133 </template>
134 
135 <script>
136     import homeBtn from '@/pages/components/float-button/home.vue'
137     import titleBar from './components/title-bar.vue'
138     import inputText from './components/input-text.vue'
139     import pickerRangeKey from './components/picker-range-key.vue'
140     import pickerDefault from './components/picker-default.vue'
141     import pickerDate from './components/picker-date.vue'
142     import pickerMultiSelector from './components/picker-multiSelector.vue'
143     import {getNowDate,debounce,abnormalprompt} from '@/common/index.js'
144     import {mapState,mapActions,mapMutations} from "vuex"
145     function checkPhone(phone){
146         return (/^1(3|4|5|6|7|8|9)d{9}$/.test(phone)); 
147     }
148     const NowDate = getNowDate()
149     const Selects=[{
150             type:1,
151             icon:"", ///static/account/my-icon.png
152             name:"我的信息"
153         },{
154             type:2,
155             icon:"",//"/static/account/honey-icon.png",
156             name:"我的TA"
157         },{
158             type:3,
159             icon:"/static/account/baby-icon.png",
160             name:"宝贝的信息"
161         }]
162     // const Gender = ['','男', '女']
163     const Gender = [{key:1,name:"男"},{key:2,name:"女"}]
164     const MaritalStatus = ["","未婚","已婚"]
165     const BirthStatus = ["","未生育","已生育"]
166     const HeightRange = ["156~160cm","161-165cm","166-170cm","171-175cm","176-180cm","181-185cm","其他"]
167     const BabyHeightRange = ["80~90cm","91~100cm","101~110cm","111~120cm","121~130cm","131~140cm","141~150cm","151~160cm","161~170cm"]
168     const BraSize=[["70","75","80","85","其他"],["A","B","C","D","其他"]]
169     const UnderwearSize = ["根据腰围测量","64","70","76","82","90","96","102","108","其他"]
170     const WearSize = ["155","160","165","170","175","180","185","其他"]
171     let BabyDefaultInfo = []
172     export default{
173         components:{
174             titleBar,
175             inputText,
176             pickerRangeKey,
177             pickerDefault,
178             pickerDate,
179             pickerMultiSelector,
180             homeBtn
181         },
182         data(){
183             return {
184                 NowDate,
185                 Selects,
186                 Gender,
187                 MaritalStatus,
188                 BirthStatus,
189                 HeightRange,
190                 BraSize,
191                 UnderwearSize,
192                 WearSize,
193                 BabyHeightRange,
194                 my:[],
195                 honey:[],
196                 babies:[],
197                 hasInfos:[],// 新人礼信息,不可修改
198                 needAddBaby:false,
199                 addBabyDesc:"(如有多个宝贝,可增加宝贝信息,爱慕儿童优惠券最多领取3张)",
200                 defaultSelected:1,
201                 selected:[],
202                 loading:true,
203                 myGender:"", // 显示 我的性别 
204                 honeyGender:"" // 显示 我的Ta性别 
205             }
206         },
207         computed:{
208             ...mapState("login",["userInfo","isDisabledUser"]),
209             ...mapState("accoutBaseInfo",["configs","myInfo","babyInfo","honeyInfo"]),
210             showHoney(){
211                 return this.selected.indexOf(2) >=0 // 
212             },
213             showBabies(){
214                 return this.selected.indexOf(3) >=0
215             },
216             showMy(){
217                 return this.selected.indexOf(1) >=0
218             },
219             showMyBraSize(){
220                 const myGender = this.my.filter(z=>z.field == "gender")
221                 const myBraSize = this.my.filter(z=>z.field == "braSize")
222                 if(myGender&&myGender.length>0){
223                     if(myGender[0].value === 0){ //
224                         if(myBraSize&&myBraSize.length>0){
225                             myBraSize[0].required = false
226                         }
227                         return false
228                     }else if(myGender[0].value === 1){
229                         if(myBraSize&&myBraSize.length>0){
230                             myBraSize[0].required = true
231                         }
232                     }
233                 }
234                 return true
235             },
236             showHoneyBraSize(){
237                 const honeyGender = this.honey.filter(z=>z.field == "gender")
238                 const honeyBraSize = this.honey.filter(z=>z.field == "braSize")
239                 if(honeyGender&&honeyGender.length>0){
240                     if(honeyGender[0].value === 0){ //
241                         if(honeyBraSize&&honeyBraSize.length>0){
242                             honeyBraSize[0].required = false
243                         }
244                         return false
245                     }else if(honeyGender[0].value === 1){
246                         if(honeyBraSize&&honeyBraSize.length>0){
247                             honeyBraSize[0].required = true
248                         }
249                     }
250                 }
251                 return true
252             }
253         },
254         async created() {
255             this.loading = true
256             await this.getConfig()
257             let response =  await this.getBaseInfoContent()
258             if(response.code == 200){
259                 this.formatContent()
260             }
261             this.loading = false
262         },
263         methods:{
264             ...mapActions('accoutBaseInfo',['getBaseInfoConfig','getBaseInfoContent','editMyInfo','saveHoney','saveBaby','deleteBaby']),
265             ...mapMutations('accoutBaseInfo',['GETCONFIGS']),
266             ...mapActions('login',['getMyInfo']),
267             submitEdit:debounce(async function(){
268                 if(this.isDisabledUser){
269                     abnormalprompt()
270                     return
271                 }
272                 try{
273                     uni.showLoading({
274                         title:"正在保存",
275                         mask:true
276                     })
277                     let {my,honey,babies,showHoney,showBabies,showMy} = this
278                     let requestMyData = {}
279                     let requestHoneyData = {}
280                     let requestBabiesData = []
281                     let strategy = {
282                         hasEmptyField:function(data,infoName){
283                             let result = data.filter(z=>z.required&&(!z.value||z.value===-1)&& z.value !==0).length > 0
284                             if(result){
285                                 uni.hideLoading()
286                                 uni.showToast({
287                                     title:"请完善"+infoName+"内容",
288                                     icon:"none",
289                                     duration:2000
290                                 })
291                                 return true
292                             }
293                             return false
294                         },
295                         phone:function(phone,infoName){
296                             if(phone.length>0&&phone[0].value&&!checkPhone(phone[0].value)){
297                                 uni.hideLoading()
298                                 uni.showToast({
299                                     title: infoName +phone[0].label + "格式错误",
300                                     icon:"none",
301                                     duration:2000
302                                 }); 
303                                 return false
304                             }
305                             return true
306                         },
307                         realname:function(realname){
308                             if(realname.length>0&&realname[0].value&&/d/g.test(realname[0].value)){
309                                 uni.showToast({
310                                     title:infoName + realname[0].label + "格式不正确",
311                                     icon:"none"
312                                 })
313                                 return false
314                             }
315                             return true
316                         }
317                     }
318                     let request_strategy = {
319                         braSize:function(item){
320                             if(typeof item.value != "string"){
321                                 let value = item.value?item.value.join(','):''
322                                 return value
323                             }
324                             return item.value
325                         },
326                         briefsSize:function(item){
327                             let value = (item.value==0||item.value)?item.value.toString():''
328                             return value
329                         },
330                         gender:function(item){
331                             let value = Gender[item.value]?Gender[item.value].key:0
332                             return value
333                         },
334                         stature:function(item,HeightRange){
335                             let value = HeightRange[item.value]?item.value:null
336                             return value
337                         }
338                     }
339                     // 我的信息
340                     if(showMy){
341                         if(strategy['hasEmptyField'](my,"我的信息")){
342                             return
343                         }    
344                         const phone = my.filter(z=>z.field == "phone")
345                         if(!strategy['phone'](phone,"我的信息")){
346                             return
347                         }
348                         const realname = my.filter(z=>z.field == "realname")
349                         if(!strategy['realname'](realname,"我的信息")){
350                             return
351                         }
352                         // 获取我的信息请求参数
353                         my.forEach(item=>{
354                             if(item.field == 'braSize'||item.field == 'briefsSize'){
355                                 item.value = request_strategy[item.field](item)
356                             }
357                             requestMyData[item.field] = item.value
358                             if(item.field == 'gender'||item.field == 'stature'){
359                                 requestMyData[item.field] = request_strategy[item.field](item,HeightRange)
360                             }
361                         })
362                     }
363                     // 我的TA
364                     if(showHoney){
365                         if(strategy['hasEmptyField'](honey,"我的TA")){
366                             return
367                         }
368                         const phone = honey.filter(z=>z.field == "phone")
369                         if(!strategy['phone'](phone,"我的TA")){
370                             return
371                         }
372                         const realname = honey.filter(z=>z.field == "realname")
373                         if(!strategy['realname'](realname,"我的TA")){
374                             return
375                         }
376                         // 获取我的TA请求参数
377                         honey.forEach(item=>{
378                             if(item.field == 'braSize'||item.field == 'briefsSize'){
379                                 item.value = request_strategy[item.field](item)
380                             }
381                             requestHoneyData[item.field] = item.value
382                             if(item.field == 'gender'||item.field == 'stature'){
383                                 requestHoneyData[item.field] = request_strategy[item.field](item,HeightRange)
384                             }
385                         })
386                     }
387                     // 我的宝贝
388                     if(showBabies){
389                         for(let i=0;i<babies.length;i++){
390                             const baby = babies[i]
391                             if(strategy['hasEmptyField'](baby,"我的宝贝")){
392                                 return
393                             }
394                             const phone = baby.filter(z=>z.field == "phone")
395                             if(!strategy['phone'](phone,"我的宝贝"+(i+1))){
396                                 return
397                             }
398                             const realname = baby.filter(z=>z.field == "realname")
399                             if(!strategy['realname'](realname,"我的宝贝")){
400                                 return
401                             }
402                         }
403                         // 获取我的宝贝请求参数
404                         babies.forEach(baby=>{
405                             let data = {}
406                             baby.forEach(item=>{
407                                 if(item.field == 'braSize'||item.field == 'briefsSize'){
408                                     item.value = request_strategy[item.field](item)
409                                 }
410                                 data[item.field] = item.value
411                                 if(item.field == 'gender'||item.field == 'stature'){
412                                     data[item.field] = request_strategy[item.field](item,BabyHeightRange)
413                                 }
414                             })
415                             requestBabiesData.push(data)
416                         })
417                     }
418                      // console.log(requestMyData,requestHoneyData,requestBabiesData)
419                     // let configs = [...this.configs]
420                     let fullSuccess = true
421                     if(showMy){
422                         let response = await this.editMyInfo({...requestMyData})
423                         // if(response.code == 200){
424                         //     configs.filter(z=>z.type == 1)[0].receive = true
425                         //     this.GETCONFIGS({configs})
426                         // }else{
427                         //     fullSuccess=false
428                         // }
429                         if(response.code != 200){
430                             fullSuccess=false
431                         }
432                     }
433                     if(showHoney){
434                         let response = await this.saveHoney({...requestHoneyData})
435                         // if(response.code = 200){
436                         //     // configs.filter(z=>z.type == 2)[0].receive = true
437                         //     // this.GETCONFIGS({configs})
438                         // }else{
439                         //     fullSuccess=false
440                         // }
441                         if(response.code != 200){
442                             fullSuccess=false
443                         }
444                     }
445                     if(showBabies){
446                         let response = await this.saveBaby(requestBabiesData)
447                         if(response.code == 200){
448                             // configs.filter(z=>z.type == 3)[0].receive = true
449                             // this.GETCONFIGS({configs})
450                             let res =  await this.getBaseInfoContent()
451                             if(res.code == 200){
452                                 this.formatContent()
453                             }
454                         }else{
455                             fullSuccess=false
456                         }
457                     }
458                     if(fullSuccess){
459                         // 个人资料
460                         await this.getConfig()
461                         // 更新用户积分
462                         this.getMyInfo({}) 
463                         uni.showToast({
464                             title:"保存成功",
465                             icon:"none",
466                             mask:true
467                         })
468                     }
469                     
470                 }catch(e){
471                     console.log(e)
472                     uni.showToast({
473                         title:"保存失败",
474                         icon:"none"
475                     })
476                 }
477             },200),
478             async getConfig(){
479                 let response = await this.getBaseInfoConfig({})
480                 if(response.code == 200){
481                     let configs = response.data.map(item=>{
482                         const {type} = item
483                         // 1:我的信息 2:我的ta. 3:我的宝贝 4 添加我的宝贝
484                         if(type<4){
485                             if(item.couponList&&item.couponList.length>0){
486                                 const {couponAmount,couponNum,subheading,couponName} = item.couponList[0]
487                                 item.coupon = {
488                                     discount:couponAmount,
489                                     tip: `¥${couponAmount} 【${couponName}】`
490                                 }
491                             }
492                             const select = Selects.filter(z=>z.type == type)[0]
493                             item.icon = select.icon
494                             item.name = select.name
495                         }
496                         if(type == 3){
497                             this.needAddBaby = item.isAddBaby,
498                             this.addBabyDesc = item.addBabyDesc
499                         }
500                         return item
501                     })
502                     this.GETCONFIGS({configs})
503                     if(this.configs.length>0){
504                         this.defaultSelected = this.configs[0].type
505                         this.selected.push(this.defaultSelected)
506                     }
507                 }
508             },
509             // 去使用优惠券,跳转到外部小程序
510             goMiniProgram(){
511                 uni.navigateToMiniProgram({
512                     appId:'wx203ab2d5cb638d1d',
513                     path:'/pages/index/index'
514                 })
515             },
516             // 格式化填写内容
517             formatContent(){
518                 let _this = this
519                 let strategy = {
520                     braSize:function(info,field){
521                         let value = typeof info[field] ==="string"&&info[field]?info[field].split(','):undefined
522                         return value
523                     },
524                     gender:function(info,field){
525                         let value = typeof info[field] ==="number"?info[field] - 1:-1
526                         return value
527                     },
528                     stature:function(info,field){
529                         let value = typeof info[field] ==="number"&&info[field]>=0?info[field]: -1
530                         return value 
531                     },
532                     briefsSize:function(info,field){
533                         let fieldValue = -1
534                         let value = typeof info[field] !== "undefined"&&info[field]>=0?info[field]: -1
535                         return value
536                     }
537                 }
538                 this.configs.forEach(config=>{
539                     const {type,fieldConfig} = config
540                     switch(type){
541                         case 1: //我的信息
542                             _this.my= []
543                             fieldConfig.forEach(item=>{
544                                 let my = {}
545                                 const {field,fieldName,required} = item
546                                 if(typeof strategy[field] === "function"){
547                                     _this.myInfo[field] = strategy[field](_this.myInfo,field)
548                                 }
549                                 if(field=='gender'){
550                                     _this.getGenderHoneyIcon(_this.myInfo[field],type)
551                                 }
552                                 my= {
553                                     value: _this.myInfo[field],
554                                     label: fieldName,
555                                     required,
556                                     field
557                                 }
558                                 _this.my.push(my)
559                             })
560                         break;
561                         case 2: //我的TA
562                             _this.honey = []
563                             fieldConfig.forEach(item=>{ 
564                                 let honey = {}
565                                 const {field,fieldName,required} = item
566                                 if(typeof strategy[field] === "function"){
567                                     _this.honeyInfo[field] = strategy[field](_this.honeyInfo,field)
568                                 }
569                                 if(field=='gender'){
570                                     _this.getGenderHoneyIcon(_this.honeyInfo[field],type)
571                                 }
572                                 honey = {
573                                     value: _this.honeyInfo[field],
574                                     label: fieldName,
575                                     required,
576                                     field
577                                 }
578                                 _this.honey.push(honey)
579                             })
580                             // honey id
581                             const idField = "id"
582                             _this.honey.push({
583                                 value: _this.honeyInfo[idField],
584                                 label: idField,
585                                 required:false,
586                                 field:idField
587                             })
588                         break;
589                         case 3://宝贝的信息
590                             let babyInfo = {..._this.babyInfo}
591                             _this.babies = []
592                             for(const key in babyInfo){
593                                 const baby = babyInfo[key]
594                                 let babies = []
595                                 let oneBaby = {}
596                                 fieldConfig.forEach(item=>{
597                                     const {field,fieldName,required} = item
598                                     if(typeof strategy[field] === "function"){
599                                         baby[field] = strategy[field](baby,field)
600                                     }
601                                     oneBaby = {
602                                         value: baby[field],
603                                         label: fieldName,
604                                         required,
605                                         field
606                                     }
607                                     babies.push(oneBaby)
608                                 })
609                                 // baby id
610                                 const idField = "id"
611                                 babies.push({
612                                     value: baby[idField],
613                                     label: idField,
614                                     required:false,
615                                     field:idField
616                                 },{id:new Date().getTime()})
617                                 _this.babies = [..._this.babies,[...babies]]
618                             }
619                             // 新增宝贝字段
620                             BabyDefaultInfo = []
621                             fieldConfig.forEach(item=>{
622                                 const {field,fieldName,required} = item
623                                 let value = ""
624                                 if(field == 'gender'||field == 'stature'){
625                                     value = -1
626                                 }
627                                 BabyDefaultInfo.push({
628                                     value: value,
629                                     label: fieldName,
630                                     required,
631                                     field
632                                 })
633                             })
634                         break;
635                         case 4:
636                             fieldConfig.forEach(item=>{
637                                 let hasInfo = {}
638                                 const {field,fieldName,required} = item
639                                 let value = _this.myInfo[field]
640                                 if(field == "gender"){
641                                     value = Gender[value]
642                                 }
643                                 hasInfo = {
644                                     value: value,
645                                     label: fieldName,
646                                     required,
647                                     field
648                                 }
649                                 _this.hasInfos.push(hasInfo)
650                             })
651                         break;
652                         default:
653                         break;
654                     }
655                 })
656                 
657             },
658             // 添加宝贝
659             addBaby(){
660                 const itemConfig = JSON.parse(JSON.stringify(BabyDefaultInfo))
661                 this.babies.push([...itemConfig,{id:new Date().getTime()}])
662             },
663             // 删除宝贝信息
664             deleteForBaby(index){
665                 const idField = this.babies[index].filter(z=>z.field == "id")
666                 let hasId = idField.length>0
667                 if(hasId){
668                     let _this = this
669                     uni.showModal({
670                         title:"确定删除?",
671                         async success(res) {
672                             if(res.confirm){
673                                 let response = await _this.deleteBaby({
674                                     babyId:idField[0].value
675                                 })
676                                 if(response.code == 200){
677                                     _this.delBaby(index)
678                                     uni.showToast({
679                                         title:"已删除",
680                                         icon:"none"
681                                     })
682                                 }
683                             }
684                         }
685                     })
686                 }else{
687                     this.delBaby(index)
688                 }
689             },
690             delBaby(index){
691                 this.babies.splice(index,1)
692                 if(this.babies.length==0){
693                     this.toggle(3)
694                 }
695             },
696             // 切换
697             toggle(current){
698                 if(current == this.defaultSelected){
699                     return
700                 }
701                 const selected = [...this.selected]
702                 const index = selected.indexOf(current);
703                 if( index>-1){
704                     selected.splice(index,1)
705                 }else{
706                     selected.push(current)
707                     uni.showToast({
708                         title:"下滑可填写信息",
709                         icon:"none"
710                     })
711                     if(current == 3 && this.babies.length == 0){
712                         this.addBaby()
713                     }
714                 }
715                 this.selected = selected
716             },
717             getGenderHoneyIcon(value,type){
718                 let _this = this
719                 Gender.forEach(gender=>{
720                     if(gender.key == value + 1){
721                         if(type == 2){
722                             _this.honeyGender = gender.name
723                         }else if(type ==1){
724                             _this.myGender = gender.name
725                         }
726                     }
727                 })
728                 let honeyConfig = _this.configs.filter(z=>z.type==type)[0]
729                 let isBoyIcon
730                 if(type == 2){
731                     isBoyIcon = (_this.honeyGender=='男'||(_this.myGender=='女'&&!_this.honeyGender))
732                 }else if(type ==1){
733                     isBoyIcon = _this.myGender == "男"
734                 }
735                 honeyConfig.icon = isBoyIcon?"/static/account/honey-icon.png":"/static/account/my-icon.png"
736                 return 
737             },
738             changeHoneyGender(item,e){
739                 let _this = this
740                 const type = 2
741                 this.getGenderHoneyIcon(e.value,type)
742                 item.value = e.value
743             },
744             change(item,e){
745                 if(item.field === 'realname'){
746                     item.value = e.value.replace(/d/g,"")
747                 }else if(item.field === 'phone'){
748                     item.value = e.value.replace(/D/g,"")
749                 }else{
750                     item.value = e.value
751                 }
752             },
753             changBaby(index,itemIndex,e){
754                 let item = this.babies[index][itemIndex]
755                 this.change(item,e)
756             }
757             // ,
758             // input(option,e){
759             //     let options = option.split('.')
760             //     this[options[0]][options[1]] = e.value
761             // }
762         }
763     }
764 </script>
765 
766 <style lang="scss" scoped>
767     
768     .add-circle{
769          28upx;
770         height: 28upx;
771         margin-right: 10upx;
772     }
773     .add-box{
774         padding-bottom: 44upx;
775         background-color: #F9F9F9;
776     }
777     .submit-btn{
778         padding: 45upx 0 77upx 0;
779         background-color: #F9F9F9;
780         .cu-btn{
781             380upx;
782             height:88upx;
783             background:linear-gradient(-50deg,rgba(213,27,71,1),rgba(244,50,96,1));
784             box-shadow:0upx 15upx 40upx 0upx rgba(98,0,23,0.16);
785             &::after{
786                 border- 0;
787             }
788         }
789     }
790     .add-btn{
791         font-size: 26upx;
792         font-weight:400;
793         color: #EC2C5A;
794         padding: 32upx 0;
795     }
796     .add-tip{
797         font-size:24upx;
798         font-weight:400;
799         color: #999999;
800     }
801     .border-bm{
802         border-bottom: 2upx solid #F9F9F9;
803     }
804     .line{
805         background-color: #F9F9F9;
806          100%;
807         height: 20upx;
808     }
809     .line-lg{
810         100%;
811         height:80upx;
812         background-color:#F9F9F9;
813     }
814     .select-box{
815         background-color: #F9F9F9;
816         overflow: hidden;
817         .options{
818             padding: 18upx 30upx;
819             padding-bottom: 46upx;
820             .item{
821                 overflow: hidden;
822                 .left{
823                     188upx;
824                     height:124upx;
825                     background:rgba(255,255,255,1);
826                     border:1upx solid rgba(238,238,238,1);
827                     border-radius:20upx;
828                     overflow: hidden;
829                     margin-right: 16upx;
830                     position: relative;
831                     .icon{
832                         38upx;
833                         height:40upx;
834                         margin-bottom: 13upx;
835                         image{
836                              100%;
837                             height: 100%;
838                         }
839                     }
840                     .name{
841                         font-size:24upx;
842                         font-weight:400;
843                         color: #2C3850;
844                     }
845                     .uncheck-icon,
846                     .check-icon{
847                         position: absolute;
848                         left: 0;
849                         top: 0;
850                          44upx;
851                         height: 44upx;
852                         display: none;
853                         image{
854                              100%;
855                             height: 100%;
856                         }
857                     }
858                     .uncheck-icon{
859                         display: block;
860                     }
861                 }
862                 .right{
863                     488upx;
864                     height:124upx;
865                     background-color:rgba(187,63,89,0.6);
866                     border-radius:20upx;
867                     overflow: hidden;
868                     padding: 14rpx 24upx 14rpx 36upx;
869                     color: #FEFFFE;
870                     position: relative;
871                     &.bg-red{
872                         background-color: #BB3F59;
873                     }
874                     .get-icon{
875                          84upx;
876                         height: 66upx;
877                         position: absolute;
878                         top: 0;
879                         right: 280upx;
880                     }
881                     .info{
882                         // padding-bottom: 22upx;
883                         .num{
884                             font-size:34upx;
885                             font-weight:400;
886                         }
887                         .text{
888                             font-size:24upx;
889                             font-family:PingFang SC;
890                             font-weight:400;
891                         }
892                     }
893                     .tips{
894                         font-size:18upx;
895                         font-weight:400;
896                         color: #FEFFFE;
897                     }
898                 }
899                 &.current{
900                     .right{
901                         background-color: #BB3F59;
902                     }
903                     .check-icon{
904                         display: block;
905                     }
906                     .uncheck-icon{
907                         display: none;
908                     }
909                 }
910             }
911         }
912     }
913 </style>

8、最终效果

原文地址:https://www.cnblogs.com/kitty-blog/p/14043676.html