| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270 |
- <template>
- <view class="popup" v-show="show">
- <view class="bg" @tap="cancelMultiple"></view>
- <view class="selectMultiple" :animation="animationData">
- <view class="multipleBody">
- <view class="title">
- <view class="close" @tap="cancelMultiple">
- 取消
- </view>
- <view class="title-label">
- 请选择
- </view>
- <view class="confirm" @tap="confirmMultiple">
- 确定
- </view>
- </view>
- <!-- 单选 -->
- <view class="list" v-if="!isMultiSelect && list.length">
- <picker-view :value="selectValue" @change="onSingleChange" class="picker-view" indicator-style="height: 80rpx;">
- <picker-view-column>
- <view class="picker-item" v-for="(item, index) in list" :key="index" style="font-size: 32rpx;">{{item.label}}</view>
- </picker-view-column>
- </picker-view>
- </view>
- <!-- 多选 -->
- <view class="list" v-if="isMultiSelect && list.length">
- <scroll-view class="diet-list" :scroll-y="true">
- <view v-for="(item, index) in list" :class="['item', item.selected ? 'checked' : '']" @tap="onChange(index, item)">
- <view class="empty-box" style="width: 32rpx;height: 32rpx;"></view>
- <span style="font-size: 32rpx;">{{item.label}}</span>
- <icon v-show="item.selected" type="success_no_circle" size="16" color="#2D8DFF"/>
- <view v-show="!item.selected" class="empty-box" style="width: 32rpx;height: 32rpx;"></view>
- </view>
- </scroll-view>
- </view>
- </view>
- </view>
- </view>
- </template>
- <script>
- export default {
- name:"custom-multi-select",
- data() {
- return {
- selectValue: [0],
- // 选中值
- value: [],
- // 选中列表
- selected: [],
- // 列表数据
- list: [],
- originList: [],
- // 出场动画
- animationData: {},
- };
- },
- props: {
- // 是否显示
- show: {
- type: Boolean,
- default: false
- },
- //数据列表
- columns: {
- type: Array,
- default: []
- },
- // 默认选中
- defaultIndex: {
- type: Array,
- default: [],
- },
- isMultiSelect: {
- type: Boolean,
- default: true
- },
- },
- watch: {
- // 监听是否显示
- show(val) {
- if(val) {
- this.openMultiple();
- }
- }
- },
- methods: {
- onSingleChange(e){
- console.log(this.selectValue)
- this.value = [];
- this.selected = [];
- let item = this.list[e.detail.value[0]]
- if(!item){
- return
- }
- this.value.push(item.value.toString());
- this.selected.push({
- label: item.label,
- value: item.value,
- });
- },
- // 列点击事件
- onChange(index, item) {
- // 单选
- if (!this.isMultiSelect) {
-
- }
- // 是否已选中
- if(this.value.indexOf(item.value.toString()) >= 0) {
- this.list[index].selected = false;
- } else {
- this.list[index].selected = true;
- }
-
- // 筛选已勾选数据
- this.value = [];
- this.selected = [];
- this.list.forEach((col_item, col_index) => {
- if(col_item.selected) {
- this.value.push(col_item.value.toString());
- this.selected.push({
- label: col_item.label,
- value: col_item.value,
- });
- }
- });
- this.$emit("change", {selected: this.selected, value: this.value});
- },
- // 弹出框开启触发事件
- openMultiple() {
- // 初始化列表数据,默认勾选数据
- this.value = this.defaultIndex;
- this.columns.forEach((item, index) => {
- this.$set(item, "selected", false);
- if(this.value.indexOf(item.value.toString()) >= 0) {
- item.selected = true;
- }
- });
- this.originList = Object.assign([], this.columns);
- this.list = JSON.parse(JSON.stringify(this.originList))
- // 弹出动画
- this.openAnimation();
- },
- // 确认
- confirmMultiple() {
- this.$emit("confirm", {selected: this.selected, value: this.value});
- },
- // 关闭/取消
- cancelMultiple() {
- this.$emit("cancel");
- },
- // 展开动画
- openAnimation() {
- var animation = uni.createAnimation()
- animation.translate(0, 300).step({ duration: 0 });
- this.animationData = animation.export();
- this.$nextTick(() => {
- animation.translate(0, 0).step({ duration: 300, timingFunction: 'ease' });
- this.animationData = animation.export()
- })
- },
- }
- }
- </script>
- <style scoped lang="scss">
- .popup {
- width: 100%;
- height: 100vh;
- position: fixed;
- z-index: 99999;
- left: 0;
- bottom: 0;
-
- ::-webkit-scrollbar{
- display: none;
- }
-
- .bg {
- width: 100%;
- height: 100%;
- background-color: rgba(black, .5);
- }
- }
- .selectMultiple {
- width: 100%;
- position: absolute;
- left: 0;
- bottom: 0;
- background-color: white;
- border-top-left-radius: 20rpx;
- border-top-right-radius: 20rpx;
-
- .multipleBody {
- width: 100%;
- box-sizing: border-box;
-
- .title {
- padding: 0 20rpx;
- height: 80rpx;
- font-size: 28rpx;
- display: flex;
- justify-content: space-between;
- align-items: center; /* 添加这一行 */
- box-sizing: border-box;
- border-bottom: 2rpx solid rgba(#999, 0.5);
- margin-bottom: 20rpx;
-
- .close {
- color: $uni-text-color-grey;
- }
-
- .title-label{
- color: $uni-text-color;
- }
-
- .confirm {
- color: $uni-user-selected;
- }
- }
-
- .list {
- width: 100%;
- height: 600rpx;
- position: relative;
-
- .picker-view{
- height: 600rpx;
-
- .picker-item {
- line-height: 80rpx;
- text-align: center;
- }
- }
-
- .diet-list {
- height: 600rpx;
-
- .item {
- width: 100%;
- height: 80rpx;
- font-size: 32rpx;
- display: flex;
- align-items: center;
- justify-content: space-between;
-
- span {
- flex: 1;
-
- text-align: center;
- overflow: hidden;
- display: -webkit-box;
- -webkit-box-orient:vertical;
- -webkit-line-clamp:1;
- }
- .icon{
- height: 80rpx;
- }
- &.checked {
- color: #2D8DFF;
- }
- &:last-child {
- border-bottom: none;
- }
- }
- }
- }
- }
- }
- </style>
|