index.vue 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202
  1. <template>
  2. <van-dialog
  3. v-if="!destroyed"
  4. get-container="body"
  5. close-on-click-overlay
  6. overlay-class="tabbar-home-pop-screen"
  7. :show-confirm-button="false"
  8. class="tabbar-home-dialog"
  9. v-model="show"
  10. @close="close"
  11. >
  12. <AppIcon name="close" @click.stop="close" />
  13. <div
  14. class="container"
  15. :style="{
  16. width: getStyle.width,
  17. height: getStyle.height
  18. }"
  19. @click.stop="openAD"
  20. >
  21. <AdSvga
  22. v-if="isSvgaType"
  23. :style="{
  24. width: getStyle.width,
  25. height: getStyle.height
  26. }"
  27. :svga-link="config.pic"
  28. />
  29. <van-image
  30. v-else
  31. :id="config.name"
  32. :src="config.pic"
  33. :width="getStyle.width"
  34. :height="getStyle.height"
  35. />
  36. </div>
  37. </van-dialog>
  38. </template>
  39. <script>
  40. import { Icon, Image, Dialog } from 'vant'
  41. import { AppIcon } from '@/ui'
  42. import AdSvga from '@/components/ad/svga-support'
  43. import { openLinkOfAd, px2px } from '@/utils'
  44. export default {
  45. name: 'AdPopScreen',
  46. components: {
  47. [AppIcon.name]: AppIcon,
  48. [AdSvga.name]: AdSvga,
  49. [Dialog.Component.name]: Dialog.Component,
  50. [Image.name]: Image,
  51. [Icon.name]: Icon
  52. },
  53. props: {
  54. // 缓存 Key, 未传递则不缓存
  55. cacheKey: {
  56. type: String,
  57. default: ''
  58. },
  59. beforeOpen: Function,
  60. // 过期规则 today 今天23:59:59 或 时间戳
  61. expires: {
  62. type: [String, Number],
  63. default: 'today'
  64. },
  65. // 广告配置
  66. config: {
  67. type: Object,
  68. default() {
  69. return {
  70. pic: '',
  71. link: '',
  72. name: '首屏广告',
  73. extend: {
  74. width: '',
  75. height: '',
  76. type: ''
  77. }
  78. }
  79. }
  80. }
  81. },
  82. computed: {
  83. isSvgaType() {
  84. return this.config?.pic?.indexOf('.svga') !== -1
  85. },
  86. getStyle() {
  87. return {
  88. width: px2px(this.config?.extend?.width || 311),
  89. height: px2px(this.config?.extend?.height || 440)
  90. }
  91. }
  92. },
  93. /**
  94. * 初始化数据
  95. * @typedef {object} FullScreen 初始化数据
  96. * @property {boolean} destroyed 是否需要初始化组件
  97. * @property {boolean} show 是否显示遮罩
  98. */
  99. /**
  100. * 初始化数据函数
  101. * @returns FullScreen
  102. */
  103. data: () => ({
  104. destroyed: true,
  105. show: false
  106. }),
  107. created() {
  108. const toDayShow = this.$storage.get(this.cacheKey, false)
  109. if (!toDayShow) {
  110. this.destroyed = false
  111. } else {
  112. this.initNextDialog()
  113. this.$emit('destroyed')
  114. }
  115. },
  116. mounted() {
  117. this.loadSuccess()
  118. },
  119. methods: {
  120. initNextDialog() {
  121. this.$nextTick(() => {
  122. this.$emit('initNext')
  123. })
  124. },
  125. loadSuccess() {
  126. this.show = true
  127. this.$emit('load')
  128. },
  129. /**
  130. * 关闭弹窗
  131. * @param type -关闭事件是否由点击关闭弹窗触发的
  132. */
  133. close(type = true) {
  134. this.show = false
  135. this.destroyed = true
  136. if (this.cacheKey) {
  137. this.$storage.set(this.cacheKey, true, {
  138. expires: this.expires
  139. })
  140. }
  141. this.initNextDialog()
  142. this.$emit('close', type)
  143. },
  144. async openAD() {
  145. if (this.beforeOpen) {
  146. const prevent = await this.beforeOpen()
  147. // 返回 true 可以继续往下走,返回 false 阻止跳转
  148. if (!prevent) {
  149. return
  150. }
  151. }
  152. this.close(false)
  153. openLinkOfAd({
  154. link: this.config.link,
  155. title: this.config.name,
  156. type: this.config.extend.type
  157. })
  158. }
  159. }
  160. }
  161. </script>
  162. <style lang="scss">
  163. .tabbar-home-pop-screen {
  164. background: rgba(0, 0, 0, 0.5);
  165. z-index: 3001 !important;
  166. }
  167. </style>
  168. <style scoped lang="scss">
  169. ::v-deep {
  170. .van-dialog__content {
  171. display: flex;
  172. align-items: center;
  173. justify-content: center;
  174. }
  175. }
  176. .tabbar-home-dialog {
  177. z-index: 3002 !important;
  178. overflow: unset;
  179. background: transparent;
  180. }
  181. .container {
  182. position: relative;
  183. border-radius: 8px;
  184. overflow: hidden;
  185. }
  186. .van-image {
  187. max-width: 100%;
  188. }
  189. .icon-close {
  190. pointer-events: none;
  191. position: absolute;
  192. top: -28px - 16px;
  193. right: 0;
  194. font-size: 28px;
  195. color: #fff;
  196. }
  197. </style>