因为微信原生picker组件不能修改样式,就自己用picker-view封装了一个
直接上代码
<!-- components/picker/picker.wxml -->
<input placeholder="{{placeholder}}" value="{{value}}" disabled="{{true}}" bindtap="showPicker" />
<view class="mask" wx:if="{{showPicker}}" bindtap="close">
<view class="picker" animation="{{animationData}}">
<view class="picker-header">
<button bindtap="cancel" class="cancal">取消</button>
<button bindtap="confirm" class="confirm">确定</button>
</view>
<picker-view bindchange="change" value="{{selectValues}}" class='pickerView' indicator-style="height: 50px;" style="width: 100%; height: 300px;">
<picker-view-column wx:if="{{!multiSelect}}">
<view wx:for="{{options}}" wx:key="index" style="line-height: 50px;text-align:center">
{{label?item[label]:item}}
</view>
</picker-view-column>
<picker-view-column wx:if="{{multiSelect}}" wx:for="{{options}}" wx:for-item="option" wx:key="index">
<view wx:for="{{option}}" wx:key="index" style="line-height: 50px;text-align:center">
{{label?item[label]:item}}
</view>
</picker-view-column>
</picker-view>
</view>
</view>
添加validate和validatePass字段是因为项目有一个需求是需要先完成某个选择才可以继续(如果有更好的方法请大家指教)
// components/picker/picker.js
Component({
behaviors: ['wx://form-field'],
/**
* 组件的属性列表
*/
properties: {
validate: {
type: Boolean,
value: false
},
placeholder: {
type: String,
value: '请选择'
},
multiSelect: {
type: Boolean,
value: false
},
label: String,
options: Array,
value: String,
validatePass: {
type: Boolean,
value: false
},
title: String
},
/**
* 组件的初始数据
*/
data: {
// value: '',
showPicker: false,
selectValue: 0,
selectValues: null
},
/**
* 组件的方法列表
*/
methods: {
showPicker() {
// 用that取代this,防止不必要的情况发生
var that = this;
// 创建一个动画实例
var animation = wx.createAnimation({
// 动画持续时间
duration: 500,
// 定义动画效果,当前是匀速
timingFunction: 'ease'
})
// 将该变量赋值给当前动画
that.animation = animation
// 先在y轴偏移,然后用step()完成一个动画
animation.translateY(200).step()
// 用setData改变当前动画
that.setData({
// 通过export()方法导出数据
animationData: animation.export(),
})
// 设置setTimeout来改变y轴偏移量,实现有感觉的滑动
setTimeout(function () {
animation.translateY(0).step()
that.setData({
animationData: animation.export()
})
}, 50)
if (this.data.validate) {
if (this.data.validatePass) {
this.setData({
showPicker: !this.data.showPicker
})
} else {
wx.showToast({
title: this.data.title,
icon: 'none',
image: '',
duration: 1500,
mask: false,
})
}
} else {
this.setData({
showPicker: !this.data.showPicker
})
}
this.triggerEvent("show");
},
preventTouchMove: function () { },
cancel() {
this.setData({
// value: this.data.value,
showPicker: false
})
let detail = {
value: this.data.selectValue
}
this.triggerEvent("cancel", detail);
},
confirm() {
let arr = []
//默认选中第一项
if(!this.data.selectValues) {
if (this.data.multiSelect) {
let opt = this.data.options
for (let i = 0; i < opt.length; i++) {
arr.push(0)
}
this.data.selectValue = arr
} else {
arr.push(0)
}
console.log(arr)
} else {
arr = this.data.selectValues
}
let selectValue = this.data.selectValue
this.setData({
value: selectValue,
selectValue: selectValue,
selectValues: arr,
showPicker: false
})
let detail = {
value: selectValue
}
this.triggerEvent("confirm", detail);
},
change(e) {
console.log(e)
let values = e.detail.value
this.data.selectValue = this.data.multiSelect? values: values[0]
this.data.selectValues = values
},
}
})
/* components/picker/picker.wxss */
.mask {
position: fixed;
left: 0;
right: 0;
bottom: 0;
top: 0;
z-index: 9999;
background: rgba(0, 0, 0, .4);
transition: all .4s ease-in-out 0;
pointer-events: none;
opacity: 1;
pointer-events: auto
}
.picker {
position: absolute;
width: 100%;
height: 600rpx;
bottom: 0;
left: 0;
background: #fff;
display: flex;
flex-direction: column;
transition: all .4s ease-in-out 0;
}
.picker-header {
height: 20%;
box-sizing: border-box;
display: flex;
justify-content: space-between;
align-items: center;
border-bottom: 1px solid #eeeeee;
height: 100rpx;
padding: 0 20rpx;
}
.cancal {
font-size: 16px;
font-weight: 400;
color: rgba(51, 51, 51, 1);
}
.confirm {
font-size: 16px;
font-weight: 400;
color: rgba(31, 200, 207, 1) !important;
}
button {
background: inherit;
border: none;
margin: 0;
}
button:after {
border-radius: 0rpx;
border: none;
}
使用示例
<v-picker validate="{{true}}" validatePass="{{validatePass}}" title="请先选择设备类型" bind:show="showProductPicker" data-index="{{index}}" bind:confirm="productIdChange" placeholder="请选择产品类型" value="{{item.productName}}" options="{{productIds}}" label="productName"></v-picker>
showProductPicker() {
if (!!this.data.form2.deviceTypeId || this.data.form2.deviceTypeId !== '') {
this.setData({
validatePass: true
})
} else {
this.setData({
validatePass: false
})
}
},