tui-modal.vue 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407
  1. <template>
  2. <view class="tui-modal__container" :class="[show ? 'tui-modal-show' : '']" :style="{zIndex:zIndex}" @touchmove.stop.prevent>
  3. <view
  4. class="tui-modal-box"
  5. :style="{ width: width, padding: padding, borderRadius: radius, backgroundColor: backgroundColor,zIndex:zIndex+1 }"
  6. :class="[fadeIn || show ? 'tui-modal-normal' : 'tui-modal-scale', show ? 'tui-modal-show' : '']"
  7. >
  8. <view v-if="!custom">
  9. <view class="tui-modal-title" v-if="title">{{ title }}</view>
  10. <view class="tui-modal-content" :class="[title ? '' : 'tui-mtop']" :style="{ color: color, fontSize: size + 'rpx' }">{{ content }}</view>
  11. <view class="tui-modalBtn-box" :class="[button.length != 2 ? 'tui-flex-column' : '']">
  12. <block v-for="(item, index) in button" :key="index">
  13. <button
  14. class="tui-modal-btn"
  15. :class="[
  16. 'tui-' + (item.type || 'primary') + (item.plain ? '-outline' : ''),
  17. button.length != 2 ? 'tui-btn-width' : '',
  18. button.length > 2 ? 'tui-mbtm' : '',
  19. shape == 'circle' ? 'tui-circle-btn' : ''
  20. ]"
  21. :hover-class="'tui-' + (item.plain ? 'outline' : item.type || 'primary') + '-hover'"
  22. :data-index="index"
  23. @tap="handleClick"
  24. >
  25. {{ item.text || '确定' }}
  26. </button>
  27. </block>
  28. </view>
  29. </view>
  30. <view v-else><slot></slot></view>
  31. </view>
  32. <view class="tui-modal-mask" :class="[show ? 'tui-mask-show' : '']" :style="{zIndex:maskZIndex}" @tap="handleClickCancel"></view>
  33. </view>
  34. </template>
  35. <script>
  36. export default {
  37. name: 'tuiModal',
  38. props: {
  39. //是否显示
  40. show: {
  41. type: Boolean,
  42. default: false
  43. },
  44. width: {
  45. type: String,
  46. default: '84%'
  47. },
  48. backgroundColor: {
  49. type: String,
  50. default: '#fff'
  51. },
  52. padding: {
  53. type: String,
  54. default: '40rpx 64rpx'
  55. },
  56. radius: {
  57. type: String,
  58. default: '24rpx'
  59. },
  60. //标题
  61. title: {
  62. type: String,
  63. default: ''
  64. },
  65. //内容
  66. content: {
  67. type: String,
  68. default: ''
  69. },
  70. //内容字体颜色
  71. color: {
  72. type: String,
  73. default: '#999'
  74. },
  75. //内容字体大小 rpx
  76. size: {
  77. type: Number,
  78. default: 28
  79. },
  80. //形状 circle, square
  81. shape: {
  82. type: String,
  83. default: 'square'
  84. },
  85. button: {
  86. type: Array,
  87. default: function() {
  88. return [
  89. {
  90. text: '取消',
  91. type: 'red',
  92. plain: true //是否空心
  93. },
  94. {
  95. text: '确定',
  96. type: 'red',
  97. plain: false
  98. }
  99. ];
  100. }
  101. },
  102. //点击遮罩 是否可关闭
  103. maskClosable: {
  104. type: Boolean,
  105. default: true
  106. },
  107. //淡入效果,自定义弹框插入input输入框时传true
  108. fadeIn: {
  109. type: Boolean,
  110. default: false
  111. },
  112. //自定义弹窗内容
  113. custom: {
  114. type: Boolean,
  115. default: false
  116. },
  117. //容器z-index
  118. zIndex:{
  119. type: Number,
  120. default: 9997
  121. },
  122. //mask z-index
  123. maskZIndex:{
  124. type: Number,
  125. default: 9990
  126. }
  127. },
  128. data() {
  129. return {};
  130. },
  131. methods: {
  132. handleClick(e) {
  133. if (!this.show) return;
  134. const dataset = e.currentTarget.dataset;
  135. this.$emit('click', {
  136. index: Number(dataset.index)
  137. });
  138. },
  139. handleClickCancel() {
  140. if (!this.maskClosable) return;
  141. this.$emit('cancel');
  142. }
  143. }
  144. };
  145. </script>
  146. <style scoped>
  147. .tui-modal__container {
  148. width: 100%;
  149. height: 100%;
  150. position: fixed;
  151. left: 0;
  152. top: 0;
  153. display: flex;
  154. align-items: center;
  155. justify-content: center;
  156. visibility: hidden;
  157. }
  158. .tui-modal-box {
  159. position: relative;
  160. opacity: 0;
  161. visibility: hidden;
  162. box-sizing: border-box;
  163. transition: all 0.3s ease-in-out;
  164. }
  165. .tui-modal-scale {
  166. transform: scale(0);
  167. }
  168. .tui-modal-normal {
  169. transform: scale(1);
  170. }
  171. .tui-modal-show {
  172. opacity: 1;
  173. visibility: visible;
  174. }
  175. .tui-modal-mask {
  176. position: fixed;
  177. top: 0;
  178. left: 0;
  179. right: 0;
  180. bottom: 0;
  181. background-color: rgba(0, 0, 0, 0.6);
  182. transition: all 0.3s ease-in-out;
  183. opacity: 0;
  184. visibility: hidden;
  185. }
  186. .tui-mask-show {
  187. visibility: visible;
  188. opacity: 1;
  189. }
  190. .tui-modal-title {
  191. text-align: center;
  192. font-size: 34rpx;
  193. color: #333;
  194. padding-top: 20rpx;
  195. font-weight: bold;
  196. }
  197. .tui-modal-content {
  198. text-align: center;
  199. color: #999;
  200. font-size: 28rpx;
  201. padding-top: 20rpx;
  202. padding-bottom: 60rpx;
  203. }
  204. .tui-mtop {
  205. margin-top: 30rpx;
  206. }
  207. .tui-mbtm {
  208. margin-bottom: 30rpx;
  209. }
  210. .tui-modalBtn-box {
  211. width: 100%;
  212. display: flex;
  213. align-items: center;
  214. justify-content: space-between;
  215. }
  216. .tui-flex-column {
  217. flex-direction: column;
  218. }
  219. .tui-modal-btn {
  220. width: 46%;
  221. height: 68rpx;
  222. line-height: 68rpx;
  223. position: relative;
  224. border-radius: 10rpx;
  225. font-size: 26rpx;
  226. overflow: visible;
  227. margin-left: 0;
  228. margin-right: 0;
  229. }
  230. .tui-modal-btn::after {
  231. content: ' ';
  232. position: absolute;
  233. width: 200%;
  234. height: 200%;
  235. -webkit-transform-origin: 0 0;
  236. transform-origin: 0 0;
  237. transform: scale(0.5, 0.5) translateZ(0);
  238. left: 0;
  239. top: 0;
  240. border-radius: 20rpx;
  241. z-index: 2;
  242. }
  243. .tui-btn-width {
  244. width: 80% !important;
  245. }
  246. .tui-primary {
  247. background: #5677fc;
  248. color: #fff;
  249. }
  250. .tui-primary-hover {
  251. background: #4a67d6;
  252. color: #e5e5e5;
  253. }
  254. .tui-primary-outline {
  255. color: #5677fc;
  256. background: transparent;
  257. }
  258. .tui-primary-outline::after {
  259. border: 1px solid #5677fc;
  260. }
  261. .tui-danger {
  262. background: #ed3f14;
  263. color: #fff;
  264. }
  265. .tui-danger-hover {
  266. background: #d53912;
  267. color: #e5e5e5;
  268. }
  269. .tui-danger-outline {
  270. color: #ed3f14;
  271. background: transparent;
  272. }
  273. .tui-danger-outline::after {
  274. border: 1px solid #ed3f14;
  275. }
  276. .tui-red {
  277. background: #e41f19;
  278. color: #fff;
  279. }
  280. .tui-red-hover {
  281. background: #c51a15;
  282. color: #e5e5e5;
  283. }
  284. .tui-red-outline {
  285. color: #e41f19;
  286. background: transparent;
  287. }
  288. .tui-red-outline::after {
  289. border: 1px solid #e41f19;
  290. }
  291. .tui-warning {
  292. background: #ff7900;
  293. color: #fff;
  294. }
  295. .tui-warning-hover {
  296. background: #e56d00;
  297. color: #e5e5e5;
  298. }
  299. .tui-warning-outline {
  300. color: #ff7900;
  301. background: transparent;
  302. }
  303. .tui-warning-outline::after {
  304. border: 1px solid #ff7900;
  305. }
  306. .tui-green {
  307. background: #19be6b;
  308. color: #fff;
  309. }
  310. .tui-green-hover {
  311. background: #16ab60;
  312. color: #e5e5e5;
  313. }
  314. .tui-green-outline {
  315. color: #19be6b;
  316. background: transparent;
  317. }
  318. .tui-green-outline::after {
  319. border: 1px solid #19be6b;
  320. }
  321. .tui-white {
  322. background: #fff;
  323. color: #333;
  324. }
  325. .tui-white-hover {
  326. background: #f7f7f9;
  327. color: #666;
  328. }
  329. .tui-white-outline {
  330. color: #333;
  331. background: transparent;
  332. }
  333. .tui-white-outline::after {
  334. border: 1px solid #333;
  335. }
  336. .tui-gray {
  337. background: #ededed;
  338. color: #999;
  339. }
  340. .tui-gray-hover {
  341. background: #d5d5d5;
  342. color: #898989;
  343. }
  344. .tui-gray-outline {
  345. color: #999;
  346. background: transparent;
  347. }
  348. .tui-gray-outline::after {
  349. border: 1px solid #999;
  350. }
  351. .tui-outline-hover {
  352. opacity: 0.6;
  353. }
  354. .tui-circle-btn {
  355. border-radius: 40rpx !important;
  356. }
  357. .tui-circle-btn::after {
  358. border-radius: 80rpx !important;
  359. }
  360. </style>