guangchao.xu | 070005a | 2020-12-07 09:56:40 +0800 | [diff] [blame^] | 1 | <template> |
| 2 | <u-popup mode="bottom" :border-radius="borderRadius" :popup="false" v-model="value" :maskCloseAble="maskCloseAble" |
| 3 | length="auto" :safeAreaInsetBottom="safeAreaInsetBottom" @close="popupClose" :z-index="uZIndex"> |
| 4 | <view class="u-tips u-border-bottom" v-if="tips.text" :style="[tipsStyle]"> |
| 5 | {{tips.text}} |
| 6 | </view> |
| 7 | <block v-for="(item, index) in list" :key="index"> |
| 8 | <view |
| 9 | @touchmove.stop.prevent |
| 10 | @tap="itemClick(index)" |
| 11 | :style="[itemStyle(index)]" |
| 12 | class="u-action-sheet-item u-line-1" |
| 13 | :class="[index < list.length - 1 ? 'u-border-bottom' : '']" |
| 14 | :hover-stay-time="150" |
| 15 | > |
| 16 | <text>{{item.text}}</text> |
| 17 | <text class="u-action-sheet-item__subtext u-line-1" v-if="item.subText">{{item.subText}}</text> |
| 18 | </view> |
| 19 | </block> |
| 20 | <view class="u-gab" v-if="cancelBtn"> |
| 21 | </view> |
| 22 | <view @touchmove.stop.prevent class="u-actionsheet-cancel u-action-sheet-item" hover-class="u-hover-class" |
| 23 | :hover-stay-time="150" v-if="cancelBtn" @tap="close">{{cancelText}}</view> |
| 24 | </u-popup> |
| 25 | </template> |
| 26 | |
| 27 | <script> |
| 28 | /** |
| 29 | * actionSheet 操作菜单 |
| 30 | * @description 本组件用于从底部弹出一个操作菜单,供用户选择并返回结果。本组件功能类似于uni的uni.showActionSheetAPI,配置更加灵活,所有平台都表现一致。 |
| 31 | * @tutorial https://www.uviewui.com/components/actionSheet.html |
| 32 | * @property {Array<Object>} list 按钮的文字数组,见官方文档示例 |
| 33 | * @property {Object} tips 顶部的提示文字,见官方文档示例 |
| 34 | * @property {String} cancel-text 取消按钮的提示文字 |
| 35 | * @property {Boolean} cancel-btn 是否显示底部的取消按钮(默认true) |
| 36 | * @property {Number String} border-radius 弹出部分顶部左右的圆角值,单位rpx(默认0) |
| 37 | * @property {Boolean} mask-close-able 点击遮罩是否可以关闭(默认true) |
| 38 | * @property {Boolean} safe-area-inset-bottom 是否开启底部安全区适配(默认false) |
| 39 | * @property {Number String} z-index z-index值(默认1075) |
| 40 | * @property {String} cancel-text 取消按钮的提示文字 |
| 41 | * @event {Function} click 点击ActionSheet列表项时触发 |
| 42 | * @event {Function} close 点击取消按钮时触发 |
| 43 | * @example <u-action-sheet :list="list" @click="click" v-model="show"></u-action-sheet> |
| 44 | */ |
| 45 | export default { |
| 46 | name: "u-action-sheet", |
| 47 | props: { |
| 48 | // 点击遮罩是否可以关闭actionsheet |
| 49 | maskCloseAble: { |
| 50 | type: Boolean, |
| 51 | default: true |
| 52 | }, |
| 53 | // 按钮的文字数组,可以自定义颜色和字体大小,字体单位为rpx |
| 54 | list: { |
| 55 | type: Array, |
| 56 | default () { |
| 57 | // 如下 |
| 58 | // return [{ |
| 59 | // text: '确定', |
| 60 | // color: '', |
| 61 | // fontSize: '' |
| 62 | // }] |
| 63 | return []; |
| 64 | } |
| 65 | }, |
| 66 | // 顶部的提示文字 |
| 67 | tips: { |
| 68 | type: Object, |
| 69 | default () { |
| 70 | return { |
| 71 | text: '', |
| 72 | color: '', |
| 73 | fontSize: '26' |
| 74 | } |
| 75 | } |
| 76 | }, |
| 77 | // 底部的取消按钮 |
| 78 | cancelBtn: { |
| 79 | type: Boolean, |
| 80 | default: true |
| 81 | }, |
| 82 | // 是否开启底部安全区适配,开启的话,会在iPhoneX机型底部添加一定的内边距 |
| 83 | safeAreaInsetBottom: { |
| 84 | type: Boolean, |
| 85 | default: false |
| 86 | }, |
| 87 | // 通过双向绑定控制组件的弹出与收起 |
| 88 | value: { |
| 89 | type: Boolean, |
| 90 | default: false |
| 91 | }, |
| 92 | // 弹出的顶部圆角值 |
| 93 | borderRadius: { |
| 94 | type: [String, Number], |
| 95 | default: 0 |
| 96 | }, |
| 97 | // 弹出的z-index值 |
| 98 | zIndex: { |
| 99 | type: [String, Number], |
| 100 | default: 0 |
| 101 | }, |
| 102 | // 取消按钮的文字提示 |
| 103 | cancelText: { |
| 104 | type: String, |
| 105 | default: '取消' |
| 106 | } |
| 107 | }, |
| 108 | computed: { |
| 109 | // 顶部提示的样式 |
| 110 | tipsStyle() { |
| 111 | let style = {}; |
| 112 | if (this.tips.color) style.color = this.tips.color; |
| 113 | if (this.tips.fontSize) style.fontSize = this.tips.fontSize + 'rpx'; |
| 114 | return style; |
| 115 | }, |
| 116 | // 操作项目的样式 |
| 117 | itemStyle() { |
| 118 | return (index) => { |
| 119 | let style = {}; |
| 120 | if (this.list[index].color) style.color = this.list[index].color; |
| 121 | if (this.list[index].fontSize) style.fontSize = this.list[index].fontSize + 'rpx'; |
| 122 | // 选项被禁用的样式 |
| 123 | if (this.list[index].disabled) style.color = '#c0c4cc'; |
| 124 | return style; |
| 125 | } |
| 126 | }, |
| 127 | uZIndex() { |
| 128 | // 如果用户有传递z-index值,优先使用 |
| 129 | return this.zIndex ? this.zIndex : this.$u.zIndex.popup; |
| 130 | } |
| 131 | }, |
| 132 | methods: { |
| 133 | // 点击取消按钮 |
| 134 | close() { |
| 135 | // 发送input事件,并不会作用于父组件,而是要设置组件内部通过props传递的value参数 |
| 136 | // 这是一个vue发送事件的特殊用法 |
| 137 | this.popupClose(); |
| 138 | this.$emit('close'); |
| 139 | }, |
| 140 | // 弹窗关闭 |
| 141 | popupClose() { |
| 142 | this.$emit('input', false); |
| 143 | }, |
| 144 | // 点击某一个item |
| 145 | itemClick(index) { |
| 146 | // disabled的项禁止点击 |
| 147 | if(this.list[index].disabled) return; |
| 148 | this.$emit('click', index); |
| 149 | this.$emit('input', false); |
| 150 | } |
| 151 | } |
| 152 | } |
| 153 | </script> |
| 154 | |
| 155 | <style lang="scss" scoped> |
| 156 | @import "../../libs/css/style.components.scss"; |
| 157 | |
| 158 | .u-tips { |
| 159 | font-size: 26rpx; |
| 160 | text-align: center; |
| 161 | padding: 34rpx 0; |
| 162 | line-height: 1; |
| 163 | color: $u-tips-color; |
| 164 | } |
| 165 | |
| 166 | .u-action-sheet-item { |
| 167 | @include vue-flex;; |
| 168 | line-height: 1; |
| 169 | justify-content: center; |
| 170 | align-items: center; |
| 171 | font-size: 32rpx; |
| 172 | padding: 34rpx 0; |
| 173 | flex-direction: column; |
| 174 | } |
| 175 | |
| 176 | .u-action-sheet-item__subtext { |
| 177 | font-size: 24rpx; |
| 178 | color: $u-tips-color; |
| 179 | margin-top: 20rpx; |
| 180 | } |
| 181 | |
| 182 | .u-gab { |
| 183 | height: 12rpx; |
| 184 | background-color: rgb(234, 234, 236); |
| 185 | } |
| 186 | |
| 187 | .u-actionsheet-cancel { |
| 188 | color: $u-main-color; |
| 189 | } |
| 190 | </style> |