tn-modal.vue 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246
  1. <template>
  2. <view v-if="value" class="tn-modal-class tn-modal">
  3. <tn-popup
  4. v-model="value"
  5. mode="center"
  6. :popup="false"
  7. :borderRadius="radius"
  8. :width="width"
  9. :zoom="zoom"
  10. :safeAreaInsetBottom="safeAreaInsetBottom"
  11. :maskCloseable="maskCloseable"
  12. :zIndex="zIndex"
  13. :closeBtn="showCloseBtn"
  14. @close="close"
  15. >
  16. <!-- 内容 -->
  17. <view
  18. class="tn-modal__box"
  19. :class="[
  20. backgroundColorClass
  21. ]"
  22. :style="[boxStyle]"
  23. >
  24. <!-- 不是自定义弹框内容 -->
  25. <view v-if="!custom">
  26. <view class="tn-modal__box__title" v-if="title && title !== ''">{{ title }}</view>
  27. <view
  28. class="tn-modal__box__content"
  29. :class="[
  30. fontColorClass,
  31. contentClass
  32. ]"
  33. :style="contentStyle"
  34. >{{ content }}</view>
  35. <view v-if="button && button.length" class="tn-modal__box__btn-box" :class="[button.length != 2 ? 'tn-flex-direction-column' : '']">
  36. <block v-for="(item, index) in button" :key="index">
  37. <tn-button
  38. width="100%"
  39. height="68rpx"
  40. :fontSize="26"
  41. :backgroundColor="item.backgroundColor || ''"
  42. :fontColor="item.fontColor || ''"
  43. :plain="item.plain || false"
  44. :shape="item.shape || 'round'"
  45. :class="[
  46. button.length > 2 ? 'tn-margin-bottom' : ''
  47. ]"
  48. @click="handleClick(index)"
  49. :style="{
  50. width: button.length != 2 ? '80%' : '46%'
  51. }"
  52. >
  53. {{ item.text }}
  54. </tn-button>
  55. </block>
  56. </view>
  57. </view>
  58. <view v-else>
  59. <slot></slot>
  60. </view>
  61. </view>
  62. </tn-popup>
  63. </view>
  64. </template>
  65. <script>
  66. import componentsColorMixin from '../../libs/mixin/components_color.js'
  67. export default {
  68. mixins: [componentsColorMixin],
  69. name: 'tn-modal',
  70. props: {
  71. // 显示控制
  72. value: {
  73. type: Boolean,
  74. default: false
  75. },
  76. // 弹框宽度
  77. width: {
  78. type: String,
  79. default: '84%'
  80. },
  81. // 内边距
  82. padding: {
  83. type: String,
  84. default: ''
  85. },
  86. // 圆角
  87. radius: {
  88. type: Number,
  89. default: 12
  90. },
  91. // 标题
  92. title: {
  93. type: String,
  94. default: ''
  95. },
  96. // 内容
  97. content: {
  98. type: String,
  99. default: ''
  100. },
  101. // 按钮内容 设置参数与button组件的参数一致
  102. // {
  103. // text: '确定',
  104. // backgroundColor: 'red',
  105. // fontColor: 'white',
  106. // plain: true,
  107. // shape: ''
  108. // }
  109. button: {
  110. type: Array,
  111. default: () => {
  112. return []
  113. }
  114. },
  115. safeAreaInsetBottom: {
  116. type: Boolean,
  117. default: false
  118. },
  119. // 点击遮罩是否可以关闭
  120. maskCloseable: {
  121. type: Boolean,
  122. default: true
  123. },
  124. // 是否显示右上角关闭按钮
  125. showCloseBtn: {
  126. type: Boolean,
  127. default: false
  128. },
  129. // 放大动画
  130. zoom: {
  131. type: Boolean,
  132. default: true
  133. },
  134. // 自定义弹框内容
  135. custom: {
  136. type: Boolean,
  137. default: false
  138. },
  139. // 弹框的z-index
  140. zIndex: {
  141. type: Number,
  142. default: 0
  143. }
  144. },
  145. computed: {
  146. boxStyle() {
  147. let style = {}
  148. if (this.padding) {
  149. style.padding = this.padding
  150. }
  151. if (this.backgroundColorStyle) {
  152. style.backgroundColor = this.backgroundColorStyle
  153. }
  154. return style
  155. },
  156. contentClass() {
  157. let clazz = ''
  158. if (this.title) {
  159. clazz += ' tn-margin-top'
  160. } else {
  161. clazz += ' tn-modal__box__content--no-title'
  162. }
  163. return clazz
  164. },
  165. contentStyle() {
  166. let style = {}
  167. if (this.fontSize) {
  168. style.fontSize = this.fontSize + this.fontUnit
  169. }
  170. if (this.fontColorStyle) {
  171. style.color = this.fontColorStyle
  172. }
  173. return style
  174. },
  175. },
  176. data() {
  177. return {
  178. }
  179. },
  180. methods: {
  181. // 处理按钮点击事件
  182. handleClick(index) {
  183. if (!this.value) return
  184. this.$emit("click", {
  185. index: Number(index)
  186. })
  187. },
  188. // 处理关闭事件
  189. close() {
  190. this.$emit("cancel")
  191. this.$emit('input', false)
  192. }
  193. }
  194. }
  195. </script>
  196. <style lang="scss" scoped>
  197. .tn-modal {
  198. &__box {
  199. position: relative;
  200. box-sizing: border-box;
  201. background-color: #FFFFFF;
  202. padding: 40rpx 64rpx;
  203. &__title {
  204. text-align: center;
  205. font-size: 34rpx;
  206. color: #333;
  207. padding-top: 20rpx;
  208. font-weight: bold;
  209. }
  210. &__content {
  211. text-align: center;
  212. padding-bottom: 30rpx;
  213. color: $tn-font-color;
  214. font-size: 28rpx;
  215. &--no-title {
  216. padding-bottom: 0rpx !important;
  217. }
  218. }
  219. &__btn-box {
  220. width: 100%;
  221. display: flex;
  222. align-items: center;
  223. justify-content: space-between;
  224. }
  225. &__content ~ &__btn-box {
  226. margin-top: 30rpx;
  227. }
  228. }
  229. }
  230. </style>