uni-popup.js 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397
  1. "use strict";
  2. const common_vendor = require("../../../../common/vendor.js");
  3. const _sfc_main = {
  4. name: "uniPopup",
  5. components: {},
  6. emits: ["change", "maskClick"],
  7. props: {
  8. // 开启动画
  9. animation: {
  10. type: Boolean,
  11. default: true
  12. },
  13. // 弹出层类型,可选值,top: 顶部弹出层;bottom:底部弹出层;center:全屏弹出层
  14. // message: 消息提示 ; dialog : 对话框
  15. type: {
  16. type: String,
  17. default: "center"
  18. },
  19. // maskClick
  20. isMaskClick: {
  21. type: Boolean,
  22. default: null
  23. },
  24. // TODO 2 个版本后废弃属性 ,使用 isMaskClick
  25. maskClick: {
  26. type: Boolean,
  27. default: null
  28. },
  29. backgroundColor: {
  30. type: String,
  31. default: "none"
  32. },
  33. safeArea: {
  34. type: Boolean,
  35. default: true
  36. },
  37. maskBackgroundColor: {
  38. type: String,
  39. default: "rgba(0, 0, 0, 0.4)"
  40. },
  41. borderRadius: {
  42. type: String
  43. }
  44. },
  45. watch: {
  46. /**
  47. * 监听type类型
  48. */
  49. type: {
  50. handler: function(type) {
  51. if (!this.config[type])
  52. return;
  53. this[this.config[type]](true);
  54. },
  55. immediate: true
  56. },
  57. isDesktop: {
  58. handler: function(newVal) {
  59. if (!this.config[newVal])
  60. return;
  61. this[this.config[this.type]](true);
  62. },
  63. immediate: true
  64. },
  65. /**
  66. * 监听遮罩是否可点击
  67. * @param {Object} val
  68. */
  69. maskClick: {
  70. handler: function(val) {
  71. this.mkclick = val;
  72. },
  73. immediate: true
  74. },
  75. isMaskClick: {
  76. handler: function(val) {
  77. this.mkclick = val;
  78. },
  79. immediate: true
  80. },
  81. // H5 下禁止底部滚动
  82. showPopup(show) {
  83. }
  84. },
  85. data() {
  86. return {
  87. duration: 300,
  88. ani: [],
  89. showPopup: false,
  90. showTrans: false,
  91. popupWidth: 0,
  92. popupHeight: 0,
  93. config: {
  94. top: "top",
  95. bottom: "bottom",
  96. center: "center",
  97. left: "left",
  98. right: "right",
  99. message: "top",
  100. dialog: "center",
  101. share: "bottom"
  102. },
  103. maskClass: {
  104. position: "fixed",
  105. bottom: 0,
  106. top: 0,
  107. left: 0,
  108. right: 0,
  109. backgroundColor: "rgba(0, 0, 0, 0.4)"
  110. },
  111. transClass: {
  112. backgroundColor: "transparent",
  113. borderRadius: this.borderRadius || "0",
  114. position: "fixed",
  115. left: 0,
  116. right: 0
  117. },
  118. maskShow: true,
  119. mkclick: true,
  120. popupstyle: "top"
  121. };
  122. },
  123. computed: {
  124. getStyles() {
  125. let res = { backgroundColor: this.bg };
  126. if (this.borderRadius || "0") {
  127. res = Object.assign(res, { borderRadius: this.borderRadius });
  128. }
  129. return res;
  130. },
  131. isDesktop() {
  132. return this.popupWidth >= 500 && this.popupHeight >= 500;
  133. },
  134. bg() {
  135. if (this.backgroundColor === "" || this.backgroundColor === "none") {
  136. return "transparent";
  137. }
  138. return this.backgroundColor;
  139. }
  140. },
  141. mounted() {
  142. const fixSize = () => {
  143. const {
  144. windowWidth,
  145. windowHeight,
  146. windowTop,
  147. safeArea,
  148. screenHeight,
  149. safeAreaInsets
  150. } = common_vendor.index.getWindowInfo();
  151. this.popupWidth = windowWidth;
  152. this.popupHeight = windowHeight + (windowTop || 0);
  153. if (safeArea && this.safeArea) {
  154. this.safeAreaInsets = screenHeight - safeArea.bottom;
  155. } else {
  156. this.safeAreaInsets = 0;
  157. }
  158. };
  159. fixSize();
  160. },
  161. // TODO vue3
  162. unmounted() {
  163. this.setH5Visible();
  164. },
  165. activated() {
  166. this.setH5Visible(!this.showPopup);
  167. },
  168. deactivated() {
  169. this.setH5Visible(true);
  170. },
  171. created() {
  172. if (this.isMaskClick === null && this.maskClick === null) {
  173. this.mkclick = true;
  174. } else {
  175. this.mkclick = this.isMaskClick !== null ? this.isMaskClick : this.maskClick;
  176. }
  177. if (this.animation) {
  178. this.duration = 300;
  179. } else {
  180. this.duration = 0;
  181. }
  182. this.messageChild = null;
  183. this.clearPropagation = false;
  184. this.maskClass.backgroundColor = this.maskBackgroundColor;
  185. },
  186. methods: {
  187. setH5Visible(visible = true) {
  188. },
  189. /**
  190. * 公用方法,不显示遮罩层
  191. */
  192. closeMask() {
  193. this.maskShow = false;
  194. },
  195. /**
  196. * 公用方法,遮罩层禁止点击
  197. */
  198. disableMask() {
  199. this.mkclick = false;
  200. },
  201. // TODO nvue 取消冒泡
  202. clear(e) {
  203. e.stopPropagation();
  204. this.clearPropagation = true;
  205. },
  206. open(direction) {
  207. if (this.showPopup) {
  208. return;
  209. }
  210. let innerType = ["top", "center", "bottom", "left", "right", "message", "dialog", "share"];
  211. if (!(direction && innerType.indexOf(direction) !== -1)) {
  212. direction = this.type;
  213. }
  214. if (!this.config[direction]) {
  215. common_vendor.index.__f__("error", "at uni_modules/uni-popup/components/uni-popup/uni-popup.vue:310", "缺少类型:", direction);
  216. return;
  217. }
  218. this[this.config[direction]]();
  219. this.$emit("change", {
  220. show: true,
  221. type: direction
  222. });
  223. },
  224. close(type) {
  225. this.showTrans = false;
  226. this.$emit("change", {
  227. show: false,
  228. type: this.type
  229. });
  230. clearTimeout(this.timer);
  231. this.timer = setTimeout(() => {
  232. this.showPopup = false;
  233. }, 300);
  234. },
  235. // TODO 处理冒泡事件,头条的冒泡事件有问题 ,先这样兼容
  236. touchstart() {
  237. this.clearPropagation = false;
  238. },
  239. onTap() {
  240. if (this.clearPropagation) {
  241. this.clearPropagation = false;
  242. return;
  243. }
  244. this.$emit("maskClick");
  245. if (!this.mkclick)
  246. return;
  247. this.close();
  248. },
  249. /**
  250. * 顶部弹出样式处理
  251. */
  252. top(type) {
  253. this.popupstyle = this.isDesktop ? "fixforpc-top" : "top";
  254. this.ani = ["slide-top"];
  255. this.transClass = {
  256. position: "fixed",
  257. left: 0,
  258. right: 0,
  259. backgroundColor: this.bg,
  260. borderRadius: this.borderRadius || "0"
  261. };
  262. if (type)
  263. return;
  264. this.showPopup = true;
  265. this.showTrans = true;
  266. this.$nextTick(() => {
  267. this.showPoptrans();
  268. if (this.messageChild && this.type === "message") {
  269. this.messageChild.timerClose();
  270. }
  271. });
  272. },
  273. /**
  274. * 底部弹出样式处理
  275. */
  276. bottom(type) {
  277. this.popupstyle = "bottom";
  278. this.ani = ["slide-bottom"];
  279. this.transClass = {
  280. position: "fixed",
  281. left: 0,
  282. right: 0,
  283. bottom: 0,
  284. paddingBottom: this.safeAreaInsets + "px",
  285. backgroundColor: this.bg,
  286. borderRadius: this.borderRadius || "0"
  287. };
  288. if (type)
  289. return;
  290. this.showPoptrans();
  291. },
  292. /**
  293. * 中间弹出样式处理
  294. */
  295. center(type) {
  296. this.popupstyle = "center";
  297. this.ani = ["fade"];
  298. this.transClass = {
  299. position: "fixed",
  300. display: "flex",
  301. flexDirection: "column",
  302. bottom: 0,
  303. left: 0,
  304. right: 0,
  305. top: 0,
  306. justifyContent: "center",
  307. alignItems: "center",
  308. borderRadius: this.borderRadius || "0"
  309. };
  310. if (type)
  311. return;
  312. this.showPoptrans();
  313. },
  314. left(type) {
  315. this.popupstyle = "left";
  316. this.ani = ["slide-left"];
  317. this.transClass = {
  318. position: "fixed",
  319. left: 0,
  320. bottom: 0,
  321. top: 0,
  322. backgroundColor: this.bg,
  323. borderRadius: this.borderRadius || "0",
  324. display: "flex",
  325. flexDirection: "column"
  326. };
  327. if (type)
  328. return;
  329. this.showPoptrans();
  330. },
  331. right(type) {
  332. this.popupstyle = "right";
  333. this.ani = ["slide-right"];
  334. this.transClass = {
  335. position: "fixed",
  336. bottom: 0,
  337. right: 0,
  338. top: 0,
  339. backgroundColor: this.bg,
  340. borderRadius: this.borderRadius || "0",
  341. display: "flex",
  342. flexDirection: "column"
  343. };
  344. if (type)
  345. return;
  346. this.showPoptrans();
  347. },
  348. showPoptrans() {
  349. this.$nextTick(() => {
  350. this.showPopup = true;
  351. this.showTrans = true;
  352. });
  353. }
  354. }
  355. };
  356. if (!Array) {
  357. const _easycom_uni_transition2 = common_vendor.resolveComponent("uni-transition");
  358. _easycom_uni_transition2();
  359. }
  360. const _easycom_uni_transition = () => "../../../uni-transition/components/uni-transition/uni-transition.js";
  361. if (!Math) {
  362. _easycom_uni_transition();
  363. }
  364. function _sfc_render(_ctx, _cache, $props, $setup, $data, $options) {
  365. return common_vendor.e({
  366. a: $data.showPopup
  367. }, $data.showPopup ? common_vendor.e({
  368. b: $data.maskShow
  369. }, $data.maskShow ? {
  370. c: common_vendor.o($options.onTap),
  371. d: common_vendor.p({
  372. name: "mask",
  373. ["mode-class"]: "fade",
  374. styles: $data.maskClass,
  375. duration: $data.duration,
  376. show: $data.showTrans
  377. })
  378. } : {}, {
  379. e: common_vendor.s($options.getStyles),
  380. f: common_vendor.n($data.popupstyle),
  381. g: common_vendor.o((...args) => $options.clear && $options.clear(...args)),
  382. h: common_vendor.o($options.onTap),
  383. i: common_vendor.p({
  384. ["mode-class"]: $data.ani,
  385. name: "content",
  386. styles: $data.transClass,
  387. duration: $data.duration,
  388. show: $data.showTrans
  389. }),
  390. j: common_vendor.o((...args) => $options.touchstart && $options.touchstart(...args)),
  391. k: common_vendor.n($data.popupstyle),
  392. l: common_vendor.n($options.isDesktop ? "fixforpc-z-index" : "")
  393. }) : {});
  394. }
  395. const Component = /* @__PURE__ */ common_vendor._export_sfc(_sfc_main, [["render", _sfc_render]]);
  396. wx.createComponent(Component);
  397. //# sourceMappingURL=../../../../../.sourcemap/mp-weixin/uni_modules/uni-popup/components/uni-popup/uni-popup.js.map