wd-curtain.vue 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172
  1. <template>
  2. <view class="wd-curtain-wrapper">
  3. <wd-popup
  4. v-model="modelValue"
  5. transition="zoom-in"
  6. position="center"
  7. :close-on-click-modal="closeOnClickModal"
  8. :hide-when-close="hideWhenClose"
  9. :z-index="zIndex"
  10. :root-portal="rootPortal"
  11. @before-enter="beforeenter"
  12. @enter="enter"
  13. @after-enter="afterenter"
  14. @before-leave="beforeleave"
  15. @leave="leave"
  16. @after-leave="afterleave"
  17. @close="close"
  18. @click-modal="clickModal"
  19. :custom-class="`wd-curtain ${customClass}`"
  20. :custom-style="customStyle"
  21. >
  22. <view class="wd-curtain__content">
  23. <image
  24. :src="src"
  25. class="wd-curtain__content-img"
  26. :style="imgStyle"
  27. :show-menu-by-longpress="showMenuByLongpress"
  28. @click="clickImage"
  29. @error="imgErr"
  30. @load="imgLoad"
  31. ></image>
  32. <slot name="close">
  33. <wd-icon
  34. name="close-outline"
  35. :custom-class="`wd-curtain__content-close ${closePosition} ${customCloseClass}`"
  36. :custom-style="customCloseStyle"
  37. @click="close"
  38. />
  39. </slot>
  40. </view>
  41. </wd-popup>
  42. </view>
  43. </template>
  44. <script lang="ts">
  45. export default {
  46. name: 'wd-curtain',
  47. options: {
  48. virtualHost: true,
  49. addGlobalClass: true,
  50. styleIsolation: 'shared'
  51. }
  52. }
  53. </script>
  54. <script lang="ts" setup>
  55. import wdIcon from '../wd-icon/wd-icon.vue'
  56. import wdPopup from '../wd-popup/wd-popup.vue'
  57. import { computed, ref, watch } from 'vue'
  58. import { curtainProps } from './types'
  59. const props = defineProps(curtainProps)
  60. const emit = defineEmits([
  61. 'beforeenter',
  62. 'enter',
  63. 'afterenter',
  64. 'beforeleave',
  65. 'leave',
  66. 'afterleave',
  67. 'close',
  68. 'closed',
  69. 'click-modal',
  70. 'load',
  71. 'error',
  72. 'click',
  73. 'update:modelValue'
  74. ])
  75. const modelValue = ref(props.modelValue || props.value)
  76. watch(
  77. () => props.modelValue,
  78. (newVal) => {
  79. modelValue.value = newVal
  80. }
  81. )
  82. watch(
  83. () => props.value,
  84. (newVal) => {
  85. modelValue.value = newVal
  86. }
  87. )
  88. watch(modelValue, (newVal) => {
  89. emit('update:modelValue', newVal)
  90. if (!newVal) {
  91. emit('close')
  92. }
  93. })
  94. const imgSucc = ref<boolean>(true)
  95. const imgScale = ref<number>(1)
  96. const imgStyle = computed(() => {
  97. let style = ''
  98. if (props.width) {
  99. style += `width: ${props.width}px ;`
  100. style += `height: ${props.width / imgScale.value}px`
  101. }
  102. return style
  103. })
  104. function beforeenter() {
  105. emit('beforeenter')
  106. }
  107. function enter() {
  108. emit('enter')
  109. }
  110. function afterenter() {
  111. emit('afterenter')
  112. }
  113. function beforeleave() {
  114. emit('beforeleave')
  115. }
  116. function leave() {
  117. emit('leave')
  118. }
  119. function afterleave() {
  120. emit('afterleave')
  121. emit('closed')
  122. }
  123. function close() {
  124. modelValue.value = false
  125. }
  126. function clickModal() {
  127. emit('click-modal')
  128. }
  129. function imgLoad(event: any) {
  130. const { height, width } = event.detail
  131. imgScale.value = width / height
  132. imgSucc.value = true
  133. emit('load')
  134. }
  135. function imgErr() {
  136. imgSucc.value = false
  137. emit('error')
  138. }
  139. function clickImage() {
  140. if (props.to) {
  141. uni.navigateTo({
  142. url: props.to
  143. })
  144. }
  145. emit('click')
  146. if (props.closeOnClick) {
  147. close()
  148. }
  149. }
  150. </script>
  151. <style lang="scss" scoped>
  152. @import './index.scss';
  153. </style>