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.
 
 
 
 
 
 

217 rivejä
6.3 KiB

  1. <template>
  2. <view @click="modalClick" :class="[value ? 'show' : '', type === 'bottom' ? 'bottom-modal' : '']" class="cu-modal">
  3. <!-- 图片弹出窗口 -->
  4. <view v-if="type === 'img'" class="cu-dialog">
  5. <view
  6. :style="{ backgroundImage: 'url(' + img + ')', height: '200px' }"
  7. class="bg-img"
  8. style="position: relative;"
  9. >
  10. <view @tap="close" class="action text-white" style="position: absolute;top: 10px;right: 10px;">
  11. <l-icon type="close" />
  12. </view>
  13. </view>
  14. <view class="cu-bar bg-white"><view @tap="close" class="action margin-0 flex-sub solid-left">关闭</view></view>
  15. </view>
  16. <!-- 单选弹出窗口 -->
  17. <view v-else-if="type === 'radio'" @tap.stop class="cu-dialog">
  18. <radio-group @change="radioChange" class="block">
  19. <view class="cu-list menu text-left">
  20. <view v-for="(item, index) of range" :key="index" class="cu-item">
  21. <label class="flex justify-between align-center flex-sub">
  22. <view class="flex-sub">{{ objectMode ? item[textField] : item }}</view>
  23. <radio
  24. :checked="radioIndex === index ? true : false"
  25. :value="objectMode ? item[valueField] : item"
  26. :class="radioIndex === index ? 'checked' : ''"
  27. class="round"
  28. ></radio>
  29. </label>
  30. </view>
  31. </view>
  32. </radio-group>
  33. </view>
  34. <!-- 多选弹出窗口 -->
  35. <view v-else-if="type === 'checkbox'" @tap.stop class="cu-dialog">
  36. <view class="cu-bar bg-white">
  37. <view @tap="close(0)" class="action text-blue">取消</view>
  38. <view v-if="!readonly" @tap="close(1)" class="action text-green">确定</view>
  39. </view>
  40. <view class="grid col-3 padding-sm">
  41. <view v-for="(item, index) in range" :key="index" class="padding-xs">
  42. <button
  43. @tap="chooseCheckbox(index)"
  44. :class="checkboxIndex.includes(index) ? 'bg-orange' : 'line-orange'"
  45. class="cu-btn orange lg block"
  46. >
  47. {{ objectMode ? item[textField] : item }}
  48. </button>
  49. </view>
  50. </view>
  51. </view>
  52. <!-- 普通/对话/底部弹出窗口 -->
  53. <view v-else class="cu-dialog">
  54. <view :class="[type === 'bottom' ? '' : 'justify-end pading-left']" class="cu-bar bg-white">
  55. <!-- 普通/对话弹出窗口 -->
  56. <template v-if="type === 'default' || type === 'confirm'">
  57. <view class="content">
  58. <slot name="title">{{ title }}</slot>
  59. </view>
  60. <view @tap="close" class="action"><l-icon type="close" color="red" /></view>
  61. </template>
  62. <!-- 底部弹出窗口 -->
  63. <template v-if="type === 'bottom'">
  64. <slot name="action">
  65. <l-button @click="close" class="action padding-lr" line="red">取消</l-button>
  66. <view class="action padding-lr">{{ title }}</view>
  67. </slot>
  68. </template>
  69. </view>
  70. <view class="padding">
  71. <slot>{{ content }}</slot>
  72. </view>
  73. <!-- 对话弹出窗口的操作区 -->
  74. <template v-if="type === 'confirm'">
  75. <view class="cu-bar bg-white justify-end padding-right">
  76. <view class="action">
  77. <button @tap="close(0)" class="cu-btn line-green text-green">取消</button>
  78. <button @tap="close(1)" class="cu-btn bg-green margin-left">确定</button>
  79. </view>
  80. </view>
  81. </template>
  82. </view>
  83. </view>
  84. </template>
  85. <script>
  86. export default {
  87. name: 'l-modal',
  88. props: {
  89. title: {},
  90. content: {},
  91. value: {},
  92. type: { default: 'default' },
  93. img: {},
  94. range: { default: () => [] },
  95. radio: {},
  96. checkbox: {},
  97. readonly: {},
  98. textField: { default: 'text' },
  99. valueField: { default: 'value' }
  100. },
  101. data() {
  102. return {
  103. radioIndex: undefined,
  104. checkboxIndex: []
  105. }
  106. },
  107. created() {
  108. this.init()
  109. },
  110. methods: {
  111. init() {
  112. if (this.type === 'radio') {
  113. this.radioIndex = this.objectMode
  114. ? this.range.findIndex(t => t[this.valueField] === this.radio)
  115. : this.range.indexOf(this.radio)
  116. } else if (this.type === 'checkbox' && Array.isArray(this.checkbox)) {
  117. this.checkboxIndex = this.checkbox.reduce(
  118. (a, b) =>
  119. a.concat(this.objectMode ? this.range.findIndex(t => t[this.valueField] === b) : this.range.indexOf(b)),
  120. []
  121. )
  122. }
  123. },
  124. close(arg) {
  125. this.$emit('input', false)
  126. this.$emit('close', false)
  127. if (typeof arg === 'number') {
  128. this.$emit(['cancel', 'ok'][arg])
  129. }
  130. if (this.type === 'checkbox') {
  131. if (arg === 0) {
  132. this.checkboxIndex = this.checkbox
  133. } else {
  134. const checkboxValue = this.checkboxIndex.reduce(
  135. (a, b) => a.concat(this.objectMode ? this.range[b][this.valueField] : this.range[b]),
  136. []
  137. )
  138. this.$emit('checkboxChange', checkboxValue)
  139. this.$emit('checkboxIndex', this.checkboxIndex)
  140. }
  141. }
  142. if (typeof arg === 'number') {
  143. this.$emit(['cancel', 'ok'][arg])
  144. }
  145. },
  146. modalClick() {
  147. if (this.type === 'radio' || this.type === 'checkbox') {
  148. this.close()
  149. }
  150. },
  151. radioChange(e) {
  152. if (this.readonly) {
  153. return
  154. }
  155. this.radioIndex = this.objectMode
  156. ? this.range.findIndex(t => t[this.valueField] === e.detail.value)
  157. : this.range.indexOf(e.detail.value)
  158. this.$emit(
  159. 'radioChange',
  160. this.objectMode ? this.range[this.radioIndex][this.valueField] : this.range[this.radioIndex]
  161. )
  162. this.$emit('radioIndex', this.radioIndex)
  163. },
  164. chooseCheckbox(index) {
  165. if (this.readonly) {
  166. return
  167. }
  168. if (this.checkboxIndex.includes(index)) {
  169. this.checkboxIndex = this.checkboxIndex.filter(t => t !== index)
  170. } else {
  171. this.checkboxIndex.push(index)
  172. }
  173. const checkboxValue = this.checkboxIndex.reduce(
  174. (a, b) => a.concat(this.objectMode ? this.range[b][this.valueField] : this.range[b]),
  175. []
  176. )
  177. }
  178. },
  179. watch: {
  180. value(newVal) {
  181. if (newVal) {
  182. this.init()
  183. }
  184. }
  185. },
  186. computed: {
  187. objectMode() {
  188. return typeof this.range[0] === 'object'
  189. }
  190. }
  191. }
  192. </script>