tn-action-sheet.vue 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202
  1. <template>
  2. <view v-if="value" class="tn-action-sheet-class tn-action-sheet">
  3. <tn-popup
  4. v-model="value"
  5. mode="bottom"
  6. length="auto"
  7. :popup="false"
  8. :borderRadius="borderRadius"
  9. :maskCloseable="maskCloseable"
  10. :safeAreaInsetBottom="safeAreaInsetBottom"
  11. :zIndex="elZIndex"
  12. @close="close"
  13. >
  14. <!-- 提示信息 -->
  15. <view
  16. v-if="tips.text"
  17. class="tn-action-sheet__tips tn-border-solid-bottom"
  18. :style="[tipsStyle]"
  19. >
  20. {{tips.text}}
  21. </view>
  22. <!-- 按钮列表 -->
  23. <block v-for="(item, index) in list" :key="index">
  24. <view
  25. class="tn-action-sheet__item tn-text-ellipsis"
  26. :class="[ index < list.length - 1 ? 'tn-border-solid-bottom' : '']"
  27. :style="[itemStyle(index)]"
  28. hover-class="tn-hover-class"
  29. :hover-stay-time="150"
  30. @tap="itemClick(index)"
  31. @touchmove.stop.prevent
  32. >
  33. <text>{{item.text}}</text>
  34. <text v-if="item.subText" class="tn-action-sheet__item__subtext tn-text-ellipsis">{{item.subText}}</text>
  35. </view>
  36. </block>
  37. <!-- 取消按钮 -->
  38. <block v-if="cancelBtn">
  39. <view class="tn-action-sheet__cancel--gab"></view>
  40. <view
  41. class="tn-action-sheet__cancel tn-action-sheet__item"
  42. hover-class="tn-hover-class"
  43. :hover-stay-time="150"
  44. @tap="close"
  45. >{{cancelText}}</view>
  46. </block>
  47. </tn-popup>
  48. </view>
  49. </template>
  50. <script>
  51. export default {
  52. name: 'tn-action-sheet',
  53. props: {
  54. // 通过v-model控制弹出和收起
  55. value: {
  56. type: Boolean,
  57. default: false
  58. },
  59. // 按钮文字数组,可以自定义颜色和字体大小
  60. // return [{
  61. // text: '确定',
  62. // subText: '这是一个确定按钮',
  63. // color: '',
  64. // fontSize: '',
  65. // disabled: true
  66. // }]
  67. list: {
  68. type: Array,
  69. default() {
  70. return []
  71. }
  72. },
  73. // 顶部提示文字
  74. tips: {
  75. type: Object,
  76. default() {
  77. return {
  78. text: '',
  79. color: '',
  80. fontSize: 26
  81. }
  82. }
  83. },
  84. // 弹出的顶部圆角值
  85. borderRadius: {
  86. type: Number,
  87. default: 0
  88. },
  89. // 点击遮罩可以关闭
  90. maskCloseable: {
  91. type: Boolean,
  92. default: true
  93. },
  94. // 底部取消按钮
  95. cancelBtn: {
  96. type: Boolean,
  97. default: true
  98. },
  99. // 底部取消按钮的文字
  100. cancelText: {
  101. type: String,
  102. default: '取消'
  103. },
  104. // 开启底部安全区域
  105. // 在iPhoneX机型底部添加一定的内边距
  106. safeAreaInsetBottom: {
  107. type: Boolean,
  108. default: false
  109. },
  110. // z-index值
  111. zIndex: {
  112. type: Number,
  113. default: 0
  114. }
  115. },
  116. computed: {
  117. // 顶部提示样式
  118. tipsStyle() {
  119. let style = {}
  120. if (this.tips.color) style.color = this.tips.color
  121. if (this.tips.fontSize) style.fontSize = this.tips.fontSize + 'rpx'
  122. return style
  123. },
  124. // 操作项目的样式
  125. itemStyle() {
  126. return (index) => {
  127. let style = {}
  128. if (this.list[index].color) style.color = this.list[index].color
  129. if (this.list[index].fontSize) style.fontSize = this.list[index].fontSize + 'rpx'
  130. // 选项被禁用的样式
  131. if (this.list[index].disabled) style.color = '#AAAAAA'
  132. return style
  133. }
  134. },
  135. elZIndex() {
  136. return this.zIndex ? this.zIndex : this.$t.zIndex.popup
  137. }
  138. },
  139. methods: {
  140. // 点击取消按钮
  141. close() {
  142. // 发送input事件,并不会作用于父组件,而是要设置组件内部通过props传递的value参数
  143. this.popupClose();
  144. this.$emit('close');
  145. },
  146. // 关闭弹窗
  147. popupClose() {
  148. this.$emit('input', false)
  149. },
  150. // 点击对应的item
  151. itemClick(index) {
  152. // 如果是禁用项则不进行操作
  153. if (this.list[index].disabled) return
  154. this.$emit('click', index)
  155. this.popupClose()
  156. }
  157. }
  158. }
  159. </script>
  160. <style lang="scss" scoped>
  161. .tn-action-sheet {
  162. &__tips {
  163. font-size: 26rpx;
  164. text-align: center;
  165. padding: 34rpx 0;
  166. line-height: 1;
  167. color: $tn-content-color;
  168. }
  169. &__item {
  170. display: flex;
  171. flex-direction: column;
  172. align-items: center;
  173. justify-content: center;
  174. font-size: 32rpx;
  175. padding: 34rpx 0;
  176. &__subtext {
  177. font-size: 24rpx;
  178. color: $tn-content-color;
  179. margin-top: 20rpx;
  180. }
  181. }
  182. &__cancel {
  183. color: $tn-font-color;
  184. &--gab {
  185. height: 12rpx;
  186. background-color: #eaeaec;
  187. }
  188. }
  189. }
  190. </style>