modal.vue 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269
  1. <template>
  2. <view @touchmove.stop.prevent>
  3. <view class="tui-modal-box" :style="{width:width,padding:padding,borderRadius:radius,background:bgcolor}" :class="[(fadein || show)?'tui-modal-normal':'tui-modal-scale',show?'tui-modal-show':'']">
  4. <view v-if="!custom">
  5. <view class="tui-modal-title" v-if="title">{{title}}</view>
  6. <!-- <view class="tui-modal-content" :class="[title?'':'tui-mtop']"> -->
  7. <view class="tui-modal-content">
  8. <block v-if="content">
  9. <div :style="{color:color,fontSize:size+'rpx'}">{{content}}</div>
  10. </block>
  11. <block v-else>
  12. <slot name="content"></slot>
  13. </block>
  14. </view>
  15. <view class="tui-modalBtn-box" :class="[button.length!=2?'tui-flex-column':'']">
  16. <block v-for="(item,index) in button" :key="index">
  17. <button class="tui-modal-btn" :class="['tui-primary'+(item.plain?'-outline':''),button.length!=2?'tui-btn-width':'',button.length>2?'tui-mbtm':'',shape=='circle'?'tui-circle-btn':'']"
  18. :hover-class="'tui-'+(item.plain?'outline':'primary')+'-hover'" :data-index="index" @tap="handleClick">{{item.text || "确定"}}</button>
  19. </block>
  20. </view>
  21. </view>
  22. <view v-else>
  23. <slot></slot>
  24. </view>
  25. </view>
  26. <view class="tui-modal-mask" :class="[show?'tui-mask-show':'']" @tap="handleClickCancel"></view>
  27. </view>
  28. </template>
  29. <script>
  30. export default {
  31. name: 'tuiModal',
  32. props: {
  33. // 是否显示
  34. show: {
  35. type: Boolean,
  36. default: false
  37. },
  38. width: {
  39. type: String,
  40. default: '84%'
  41. },
  42. padding: {
  43. type: String,
  44. default: '40rpx 30rpx'
  45. },
  46. radius: {
  47. type: String,
  48. default: '24rpx'
  49. },
  50. // 标题
  51. title: {
  52. type: String,
  53. default: ''
  54. },
  55. // 内容
  56. content: {
  57. type: String,
  58. default: ''
  59. },
  60. // 内容字体颜色
  61. color: {
  62. type: String,
  63. default: '#999'
  64. },
  65. // 背景颜色
  66. bgcolor: {
  67. type: String,
  68. default: '#fff'
  69. },
  70. // 内容字体大小 rpx
  71. size: {
  72. type: Number,
  73. default: 28
  74. },
  75. // 形状 circle, square
  76. shape: {
  77. type: String,
  78. default: 'square'
  79. },
  80. button: {
  81. type: Array,
  82. default: function() {
  83. return [{
  84. text: '取消',
  85. plain: true // 是否空心
  86. }, {
  87. text: '确定',
  88. plain: false
  89. }]
  90. }
  91. },
  92. // 点击遮罩 是否可关闭
  93. maskClosable: {
  94. type: Boolean,
  95. default: true
  96. },
  97. // 自定义弹窗内容
  98. custom: {
  99. type: Boolean,
  100. default: false
  101. },
  102. // 淡入效果,自定义弹框插入input输入框时传true
  103. fadein: {
  104. type: Boolean,
  105. default: false
  106. }
  107. },
  108. data() {
  109. return {
  110. }
  111. },
  112. methods: {
  113. handleClick(e) {
  114. if (!this.show) return
  115. const dataset = e.currentTarget.dataset
  116. this.$emit('click', {
  117. index: Number(dataset.index)
  118. })
  119. },
  120. handleClickCancel() {
  121. if (!this.maskClosable) return
  122. this.$emit('cancel')
  123. }
  124. }
  125. }
  126. </script>
  127. <style lang="scss" scoped>
  128. .tui-modal-box {
  129. position: fixed;
  130. left: 50%;
  131. top: 50%;
  132. margin: auto;
  133. background: #fff;
  134. z-index: 998;
  135. transition: all 0.3s ease-in-out;
  136. opacity: 0;
  137. box-sizing: border-box;
  138. visibility: hidden;
  139. }
  140. .tui-modal-scale {
  141. transform: translate(-50%, -50%) scale(0);
  142. }
  143. .tui-modal-normal {
  144. transform: translate(-50%, -50%) scale(1);
  145. }
  146. .tui-modal-show {
  147. opacity: 1;
  148. visibility: visible;
  149. }
  150. .tui-modal-mask {
  151. position: fixed;
  152. top: 0;
  153. left: 0;
  154. right: 0;
  155. bottom: 0;
  156. background: rgba(0, 0, 0, 0.6);
  157. z-index: 996;
  158. transition: all 0.3s ease-in-out;
  159. opacity: 0;
  160. visibility: hidden;
  161. }
  162. .tui-mask-show {
  163. visibility: visible;
  164. opacity: 1;
  165. }
  166. .tui-modal-title {
  167. text-align: center;
  168. font-size: 40rpx;
  169. color: #333;
  170. }
  171. .tui-modal-content {
  172. text-align: center;
  173. // color: #999;
  174. font-size: 24rpx;
  175. padding-top: 50rpx;
  176. padding-bottom: 60rpx;
  177. }
  178. .tui-mtop {
  179. margin-top: 30rpx;
  180. }
  181. .tui-mbtm {
  182. margin-bottom: 30rpx;
  183. }
  184. .tui-modalBtn-box {
  185. width: 100%;
  186. display: flex;
  187. align-items: center;
  188. justify-content: space-between
  189. }
  190. .tui-flex-column {
  191. flex-direction: column;
  192. }
  193. .tui-modal-btn {
  194. width: 46%;
  195. height: 90rpx;
  196. line-height: 90rpx;
  197. position: relative;
  198. border-radius: 4rpx;
  199. font-size: 32rpx;
  200. overflow: visible;
  201. margin-left: 0;
  202. margin-right: 0;
  203. }
  204. .tui-modal-btn::after {
  205. content: "";
  206. position: absolute;
  207. width: 200%;
  208. height: 200%;
  209. -webkit-transform-origin: 0 0;
  210. transform-origin: 0 0;
  211. -webkit-transform: scale(0.5, 0.5);
  212. transform: scale(0.5, 0.5);
  213. left: 0;
  214. top: 0;
  215. border-radius: 4rpx;
  216. }
  217. .tui-btn-width {
  218. width: 80% !important;
  219. }
  220. .tui-primary {
  221. background: $mainColor;
  222. color: #fff;
  223. }
  224. .tui-primary-hover {
  225. background: #4a67d6;
  226. color: #e5e5e5;
  227. }
  228. .tui-primary-outline {
  229. color: $mainColor;
  230. background: none;
  231. }
  232. .tui-primary-outline::after {
  233. border: 1px solid $mainColor;
  234. }
  235. .tui-outline-hover {
  236. opacity: 0.6;
  237. }
  238. .tui-circle-btn {
  239. border-radius: 40rpx !important;
  240. }
  241. .tui-circle-btn::after {
  242. border-radius: 80rpx !important;
  243. }
  244. </style>