综合办公系统
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

uv-modal.vue 6.6KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245
  1. <template>
  2. <uv-popup
  3. ref="modalPopup"
  4. mode="center"
  5. :zoom="zoom"
  6. :zIndex="zIndex"
  7. :customStyle="{
  8. borderRadius: '6px',
  9. overflow: 'hidden',
  10. marginTop: `-${$uv.addUnit(negativeTop)}`
  11. }"
  12. :closeOnClickOverlay="closeOnClickOverlay"
  13. :safeAreaInsetBottom="false"
  14. :duration="400"
  15. @change="popupChange"
  16. >
  17. <view
  18. class="uv-modal"
  19. :style="{
  20. width: $uv.addUnit(width),
  21. }"
  22. >
  23. <text
  24. class="uv-modal__title"
  25. v-if="title"
  26. >{{ title }}</text>
  27. <view
  28. class="uv-modal__content"
  29. :style="{
  30. paddingTop: `${title ? 12 : 25}px`
  31. }"
  32. >
  33. <slot>
  34. <text
  35. class="uv-modal__content__text"
  36. :style="[
  37. {
  38. textAlign: align
  39. },
  40. nvueStyle,
  41. $uv.addStyle(textStyle)
  42. ]"
  43. >{{ content }}</text>
  44. </slot>
  45. </view>
  46. <slot name="confirmButton">
  47. <uv-line></uv-line>
  48. <view
  49. v-if="showConfirmButton || showCancelButton"
  50. class="uv-modal__button-group"
  51. :style="{
  52. flexDirection: buttonReverse ? 'row-reverse' : 'row'
  53. }"
  54. >
  55. <view
  56. class="uv-modal__button-group__wrapper uv-modal__button-group__wrapper--cancel"
  57. :hover-stay-time="150"
  58. hover-class="uv-modal__button-group__wrapper--hover"
  59. :class="[showCancelButton && !showConfirmButton && 'uv-modal__button-group__wrapper--only-cancel']"
  60. v-if="showCancelButton"
  61. @tap="cancelHandler"
  62. >
  63. <text
  64. class="uv-modal__button-group__wrapper__text"
  65. :style="{
  66. color: cancelColor
  67. }"
  68. >{{ cancelText }}</text>
  69. </view>
  70. <uv-line
  71. direction="column"
  72. v-if="showConfirmButton && showCancelButton"
  73. ></uv-line>
  74. <view
  75. class="uv-modal__button-group__wrapper uv-modal__button-group__wrapper--confirm"
  76. :hover-stay-time="150"
  77. hover-class="uv-modal__button-group__wrapper--hover"
  78. :class="[!showCancelButton && showConfirmButton && 'uv-modal__button-group__wrapper--only-confirm']"
  79. v-if="showConfirmButton"
  80. @tap="confirmHandler"
  81. >
  82. <uv-loading-icon v-if="loading"></uv-loading-icon>
  83. <text
  84. v-else
  85. class="uv-modal__button-group__wrapper__text"
  86. :style="{
  87. color: confirmColor
  88. }"
  89. >{{ confirmText }}</text>
  90. </view>
  91. </view>
  92. </slot>
  93. </view>
  94. </uv-popup>
  95. </template>
  96. <script>
  97. import mpMixin from '@/uni_modules/uv-ui-tools/libs/mixin/mpMixin.js'
  98. import mixin from '@/uni_modules/uv-ui-tools/libs/mixin/mixin.js'
  99. import props from './props.js';
  100. /**
  101. * Modal 模态框
  102. * @description 弹出模态框,常用于消息提示、消息确认、在当前页面内完成特定的交互操作。
  103. * @tutorial https://www.uvui.cn/components/modul.html
  104. * @property {String} title 标题内容
  105. * @property {String} content 模态框内容,如传入slot内容,则此参数无效
  106. * @property {String} confirmText 确认按钮的文字 (默认 '确认' )
  107. * @property {String} cancelText 取消按钮的文字 (默认 '取消' )
  108. * @property {Boolean} showConfirmButton 是否显示确认按钮 (默认 true )
  109. * @property {Boolean} showCancelButton 是否显示取消按钮 (默认 false )
  110. * @property {String} confirmColor 确认按钮的颜色 (默认 '#2979ff' )
  111. * @property {String} cancelColor 取消按钮的颜色 (默认 '#606266' )
  112. * @property {Boolean} buttonReverse 对调确认和取消的位置 (默认 false )
  113. * @property {Boolean} zoom 是否开启缩放模式 (默认 true )
  114. * @property {Boolean} asyncClose 是否异步关闭,只对确定按钮有效,见上方说明 (默认 false )
  115. * @property {Boolean} closeOnClickOverlay 是否允许点击遮罩关闭该组件 (默认 true )
  116. * @property {String | Number} negativeTop 往上偏移的值,给一个负的margin-top,往上偏移,避免和键盘重合的情况,单位任意,数值则默认为px单位 (默认 0 )
  117. * @property {String | Number} width modal宽度,不支持百分比,可以数值,px,rpx单位 (默认 '650rpx' )
  118. * @property {String} align 文本对齐方式 (默认'left')
  119. * @property {String | Object} textStyle 文本扩展样式
  120. * @event {Function} confirm 点击确认按钮时触发
  121. * @event {Function} cancel 点击取消按钮时触发
  122. * @event {Function} close 点击遮罩关闭出发,closeOnClickOverlay为true有效
  123. * @example <uv-modal ref="modalPopup" title="title" content="content"></uv-modal>
  124. */
  125. export default {
  126. name: 'uv-modal',
  127. mixins: [mpMixin, mixin, props],
  128. data() {
  129. return {
  130. loading: false
  131. }
  132. },
  133. computed: {
  134. nvueStyle() {
  135. const style = {};
  136. // 避免nvue中不能换行的问题
  137. // #ifdef APP-NVUE
  138. style.width = this.$uv.addUnit(this.$uv.getPx(this.width) - 50,'px');
  139. // #endif
  140. return style;
  141. }
  142. },
  143. methods: {
  144. open() {
  145. this.$refs.modalPopup.open();
  146. if (this.loading) this.loading = false;
  147. },
  148. close() {
  149. this.$refs.modalPopup.close();
  150. },
  151. popupChange(e) {
  152. if(!e.show) this.$emit('close');
  153. },
  154. // 点击确定按钮
  155. confirmHandler() {
  156. if(!this.loading) {
  157. this.$emit('confirm');
  158. }
  159. // 如果配置了异步关闭,将按钮值为loading状态
  160. if (this.asyncClose) {
  161. this.loading = true;
  162. } else {
  163. this.close();
  164. }
  165. },
  166. // 点击取消按钮
  167. cancelHandler() {
  168. this.$emit('cancel');
  169. this.close();
  170. },
  171. closeLoading() {
  172. this.$nextTick(()=>{
  173. this.loading = false;
  174. })
  175. }
  176. }
  177. }
  178. </script>
  179. <style lang="scss" scoped>
  180. @import '@/uni_modules/uv-ui-tools/libs/css/components.scss';
  181. @import '@/uni_modules/uv-ui-tools/libs/css/color.scss';
  182. $uv-modal-border-radius: 6px;
  183. .uv-modal {
  184. width: 650rpx;
  185. border-radius: $uv-modal-border-radius;
  186. overflow: hidden;
  187. &__title {
  188. font-size: 16px;
  189. font-weight: bold;
  190. color: $uv-content-color;
  191. text-align: center;
  192. padding-top: 25px;
  193. }
  194. &__content {
  195. padding: 12px 25px 25px 25px;
  196. @include flex;
  197. justify-content: center;
  198. &__text {
  199. line-height: 48rpx;
  200. font-size: 15px;
  201. color: $uv-content-color;
  202. flex: 1;
  203. }
  204. }
  205. &__button-group {
  206. @include flex;
  207. height: 48px;
  208. &__wrapper {
  209. flex: 1;
  210. @include flex;
  211. justify-content: center;
  212. align-items: center;
  213. height: 48px;
  214. &--confirm,
  215. &--only-cancel {
  216. border-bottom-right-radius: $uv-modal-border-radius;
  217. }
  218. &--cancel,
  219. &--only-confirm {
  220. border-bottom-left-radius: $uv-modal-border-radius;
  221. }
  222. &--hover {
  223. background-color: $uv-bg-color;
  224. }
  225. &__text {
  226. color: $uv-content-color;
  227. font-size: 16px;
  228. text-align: center;
  229. }
  230. }
  231. }
  232. }
  233. </style>