|
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216 |
- <template>
- <view @click="modalClick" :class="[value ? 'show' : '', type === 'bottom' ? 'bottom-modal' : '']" class="cu-modal">
- <!-- 图片弹出窗口 -->
- <view v-if="type === 'img'" class="cu-dialog">
- <view
- :style="{ backgroundImage: 'url(' + img + ')', height: '200px' }"
- class="bg-img"
- style="position: relative;"
- >
- <view @tap="close" class="action text-white" style="position: absolute;top: 10px;right: 10px;">
- <l-icon type="close" />
- </view>
- </view>
- <view class="cu-bar bg-white"><view @tap="close" class="action margin-0 flex-sub solid-left">关闭</view></view>
- </view>
-
- <!-- 单选弹出窗口 -->
- <view v-else-if="type === 'radio'" @tap.stop class="cu-dialog">
- <radio-group @change="radioChange" class="block">
- <view class="cu-list menu text-left">
- <view v-for="(item, index) of range" :key="index" class="cu-item">
- <label class="flex justify-between align-center flex-sub">
- <view class="flex-sub">{{ objectMode ? item[textField] : item }}</view>
- <radio
- :checked="radioIndex === index ? true : false"
- :value="objectMode ? item[valueField] : item"
- :class="radioIndex === index ? 'checked' : ''"
- class="round"
- ></radio>
- </label>
- </view>
- </view>
- </radio-group>
- </view>
-
- <!-- 多选弹出窗口 -->
- <view v-else-if="type === 'checkbox'" @tap.stop class="cu-dialog">
- <view class="cu-bar bg-white">
- <view @tap="close(0)" class="action text-blue">取消</view>
- <view v-if="!readonly" @tap="close(1)" class="action text-green">确定</view>
- </view>
- <view class="grid col-3 padding-sm">
- <view v-for="(item, index) in range" :key="index" class="padding-xs">
- <button
- @tap="chooseCheckbox(index)"
- :class="checkboxIndex.includes(index) ? 'bg-orange' : 'line-orange'"
- class="cu-btn orange lg block"
- >
- {{ objectMode ? item[textField] : item }}
- </button>
- </view>
- </view>
- </view>
-
- <!-- 普通/对话/底部弹出窗口 -->
- <view v-else class="cu-dialog">
- <view :class="[type === 'bottom' ? '' : 'justify-end pading-left']" class="cu-bar bg-white">
- <!-- 普通/对话弹出窗口 -->
- <template v-if="type === 'default' || type === 'confirm'">
- <view class="content">
- <slot name="title">{{ title }}</slot>
- </view>
- <view @tap="close" class="action"><l-icon type="close" color="red" /></view>
- </template>
-
- <!-- 底部弹出窗口 -->
- <template v-if="type === 'bottom'">
- <slot name="action">
- <l-button @click="close" class="action padding-lr" line="red">取消</l-button>
- <view class="action padding-lr">{{ title }}</view>
- </slot>
- </template>
- </view>
-
- <view class="padding">
- <slot>{{ content }}</slot>
- </view>
-
- <!-- 对话弹出窗口的操作区 -->
- <template v-if="type === 'confirm'">
- <view class="cu-bar bg-white justify-end padding-right">
- <view class="action">
- <button @tap="close(0)" class="cu-btn line-green text-green">取消</button>
- <button @tap="close(1)" class="cu-btn bg-green margin-left">确定</button>
- </view>
- </view>
- </template>
- </view>
- </view>
- </template>
-
- <script>
- export default {
- name: 'l-modal',
-
- props: {
- title: {},
- content: {},
- value: {},
- type: { default: 'default' },
- img: {},
- range: { default: () => [] },
- radio: {},
- checkbox: {},
- readonly: {},
- textField: { default: 'text' },
- valueField: { default: 'value' }
- },
-
- data() {
- return {
- radioIndex: undefined,
- checkboxIndex: []
- }
- },
-
- created() {
- this.init()
- },
-
- methods: {
- init() {
- if (this.type === 'radio') {
- this.radioIndex = this.objectMode
- ? this.range.findIndex(t => t[this.valueField] === this.radio)
- : this.range.indexOf(this.radio)
- } else if (this.type === 'checkbox' && Array.isArray(this.checkbox)) {
- this.checkboxIndex = this.checkbox.reduce(
- (a, b) =>
- a.concat(this.objectMode ? this.range.findIndex(t => t[this.valueField] === b) : this.range.indexOf(b)),
- []
- )
- }
- },
-
- close(arg) {
- this.$emit('input', false)
- this.$emit('close', false)
-
- if (typeof arg === 'number') {
- this.$emit(['cancel', 'ok'][arg])
- }
-
- if (this.type === 'checkbox') {
- if (arg === 0) {
- this.checkboxIndex = this.checkbox
- } else {
- const checkboxValue = this.checkboxIndex.reduce(
- (a, b) => a.concat(this.objectMode ? this.range[b][this.valueField] : this.range[b]),
- []
- )
-
- this.$emit('checkboxChange', checkboxValue)
- this.$emit('checkboxIndex', this.checkboxIndex)
- }
- }
-
- if (typeof arg === 'number') {
- this.$emit(['cancel', 'ok'][arg])
- }
- },
-
- modalClick() {
- if (this.type === 'radio' || this.type === 'checkbox') {
- this.close()
- }
- },
-
- radioChange(e) {
- if (this.readonly) {
- return
- }
-
- this.radioIndex = this.objectMode
- ? this.range.findIndex(t => t[this.valueField] === e.detail.value)
- : this.range.indexOf(e.detail.value)
- this.$emit(
- 'radioChange',
- this.objectMode ? this.range[this.radioIndex][this.valueField] : this.range[this.radioIndex]
- )
- this.$emit('radioIndex', this.radioIndex)
- },
-
- chooseCheckbox(index) {
- if (this.readonly) {
- return
- }
-
- if (this.checkboxIndex.includes(index)) {
- this.checkboxIndex = this.checkboxIndex.filter(t => t !== index)
- } else {
- this.checkboxIndex.push(index)
- }
-
- const checkboxValue = this.checkboxIndex.reduce(
- (a, b) => a.concat(this.objectMode ? this.range[b][this.valueField] : this.range[b]),
- []
- )
- }
- },
-
- watch: {
- value(newVal) {
- if (newVal) {
- this.init()
- }
- }
- },
-
- computed: {
- objectMode() {
- return typeof this.range[0] === 'object'
- }
- }
- }
- </script>
|