index.js 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238
  1. import baseComponent from '../helpers/baseComponent'
  2. import classNames from '../helpers/libs/classNames'
  3. import styleToCssString from '../helpers/libs/styleToCssString'
  4. import { safeAreaProps } from '../helpers/mixins/safeAreaBehavior'
  5. import { $wuxBackdrop } from '../index'
  6. baseComponent({
  7. externalClasses: [
  8. 'wux-content-class',
  9. 'wux-header-class',
  10. 'wux-body-class',
  11. 'wux-footer-class',
  12. 'wux-close-class',
  13. ],
  14. properties: {
  15. prefixCls: {
  16. type: String,
  17. value: 'wux-popup',
  18. },
  19. animationPrefixCls: {
  20. type: String,
  21. value: 'wux-animate',
  22. },
  23. title: {
  24. type: String,
  25. value: '',
  26. },
  27. content: {
  28. type: String,
  29. value: '',
  30. },
  31. extra: {
  32. type: String,
  33. value: '',
  34. },
  35. position: {
  36. type: String,
  37. value: 'center',
  38. observer: 'getTransitionName',
  39. },
  40. wrapStyle: {
  41. type: [String, Object],
  42. value: '',
  43. observer(newVal) {
  44. this.updateStyle(newVal, 'popupWrapStyle')
  45. },
  46. },
  47. containerStyle: {
  48. type: [String, Object],
  49. value: '',
  50. observer(newVal) {
  51. this.updateStyle(newVal, 'popupContainerStyle')
  52. },
  53. },
  54. contentStyle: {
  55. type: [String, Object],
  56. value: '',
  57. observer(newVal) {
  58. this.updateStyle(newVal, 'popupContentStyle')
  59. },
  60. },
  61. bodyStyle: {
  62. type: [String, Object],
  63. value: '',
  64. observer(newVal) {
  65. this.updateStyle(newVal, 'popupBodyStyle')
  66. },
  67. },
  68. closable: {
  69. type: Boolean,
  70. value: false,
  71. },
  72. mask: {
  73. type: Boolean,
  74. value: true,
  75. },
  76. maskClosable: {
  77. type: Boolean,
  78. value: true,
  79. },
  80. visible: {
  81. type: Boolean,
  82. value: false,
  83. observer: 'setPopupVisible',
  84. },
  85. zIndex: {
  86. type: Number,
  87. value: 1000,
  88. },
  89. hasHeader: {
  90. type: Boolean,
  91. value: true,
  92. },
  93. hasFooter: {
  94. type: Boolean,
  95. value: true,
  96. },
  97. mountOnEnter: {
  98. type: Boolean,
  99. value: true,
  100. },
  101. unmountOnExit: {
  102. type: Boolean,
  103. value: true,
  104. },
  105. ...safeAreaProps,
  106. },
  107. data: {
  108. transitionName: '',
  109. popupVisible: false,
  110. popupWrapStyle: '',
  111. popupContainerStyle: '',
  112. popupContentStyle: '',
  113. popupBodyStyle: '',
  114. },
  115. computed: {
  116. classes: ['prefixCls, position', function(prefixCls, position) {
  117. const wrap = classNames(`${prefixCls}-position`, {
  118. [`${prefixCls}-position--${position}`]: position,
  119. })
  120. const content = `${prefixCls}__content`
  121. const hd = `${prefixCls}__hd`
  122. const title = `${prefixCls}__title`
  123. const bd = `${prefixCls}__bd`
  124. const ft = `${prefixCls}__ft`
  125. const extra = `${prefixCls}__extra`
  126. const close = `${prefixCls}__close`
  127. const x = `${prefixCls}__close-x`
  128. return {
  129. wrap,
  130. content,
  131. hd,
  132. title,
  133. bd,
  134. ft,
  135. extra,
  136. close,
  137. x,
  138. }
  139. }],
  140. },
  141. methods: {
  142. updateStyle(value, key) {
  143. const newVal = styleToCssString(value)
  144. if (this.data[key] !== newVal) {
  145. this.setData({
  146. [key]: newVal,
  147. })
  148. }
  149. },
  150. /**
  151. * 点击关闭按钮事件
  152. */
  153. close() {
  154. this.triggerEvent('close')
  155. },
  156. /**
  157. * 点击蒙层事件
  158. */
  159. onMaskClick() {
  160. if (this.data.maskClosable) {
  161. this.close()
  162. }
  163. },
  164. /**
  165. * 开始展示前触发
  166. */
  167. onEnter() {
  168. this.triggerEvent('show')
  169. },
  170. /**
  171. * 完全展示后触发
  172. */
  173. onEntered() {
  174. this.triggerEvent('showed')
  175. },
  176. /**
  177. * 完全关闭后触发
  178. */
  179. onExited() {
  180. this.triggerEvent('closed')
  181. },
  182. /**
  183. * 获取过渡的类名
  184. */
  185. getTransitionName(value = this.data.position) {
  186. const { animationPrefixCls } = this.data
  187. let transitionName = ''
  188. switch (value) {
  189. case 'top':
  190. transitionName = `${animationPrefixCls}--slideInDown`
  191. break
  192. case 'right':
  193. transitionName = `${animationPrefixCls}--slideInRight`
  194. break
  195. case 'bottom':
  196. transitionName = `${animationPrefixCls}--slideInUp`
  197. break
  198. case 'left':
  199. transitionName = `${animationPrefixCls}--slideInLeft`
  200. break
  201. default:
  202. transitionName = `${animationPrefixCls}--fadeIn`
  203. break
  204. }
  205. this.setData({ transitionName })
  206. },
  207. /**
  208. * 设置 popup 组件的显示隐藏
  209. */
  210. setPopupVisible(popupVisible) {
  211. if (this.data.popupVisible !== popupVisible) {
  212. this.setData({ popupVisible })
  213. this.setBackdropVisible(popupVisible)
  214. }
  215. },
  216. /**
  217. * 设置 backdrop 组件的显示隐藏
  218. */
  219. setBackdropVisible(visible) {
  220. if (this.data.mask && this.$wuxBackdrop) {
  221. this.$wuxBackdrop[visible ? 'retain' : 'release']()
  222. }
  223. },
  224. },
  225. created() {
  226. if (this.data.mask) {
  227. this.$wuxBackdrop = $wuxBackdrop('#wux-backdrop', this)
  228. }
  229. },
  230. attached() {
  231. this.setPopupVisible(this.data.visible)
  232. this.getTransitionName()
  233. },
  234. })