【问题标题】:How to make 2 Quasar toggle button groups mutually exclusive?如何使 2 个 Quasar 切换按钮组互斥?
【发布时间】:2021-09-14 12:33:17
【问题描述】:

我们有使用 Quasar 组件框架的 Vue.js 应用程序。

屏幕截图如下:

不正确的大小写:

正确大小写:

我需要唯一一个应该处于活动状态的切换按钮组,百分比或标准数量。注意有一系列切换按钮组。

我编写的代码产生了不正确的情况。如下所示:

<template>
  <q-dialog v-model="show" no-backdrop-dismiss full-width>
    <q-card>
      <q-card-section class="row items-center">
        <div class="text-h6 tip-color">Tip</div>
        <q-space />
        <q-btn icon="close" flat round dense v-close-popup @click="cancel" />
      </q-card-section>
      <q-card-section style="max-height: 50vh" class="scroll set-border">
        <div class="q-gutter-md">
          <q-card v-for="({ master }, index) in items" :key="master.id">
            <div class="row">
              <div class="col-3 flex justify-center items-center">
                <Avatar
                  :src="master.employer_avatar"
                  :size="50"
                  no-default-spinner
                />
                <span class="q-ml-md text-caption text-secondary">
                  {{ getEmployerName(master) }}
                </span>
              </div>
              <div class="col">
                <q-card-section>
                  <q-btn-toggle
                    v-model="togglePercentPayments[index]"
                    toggle-color="primary"
                    :options="percentPayments"
                    spread
                    @input="getFullTip"
                  />
                </q-card-section>
                <q-card-section>
                  <q-btn-toggle
                    v-model="toggleStandardPayments[index]"
                    toggle-color="primary"
                    :options="standardPayments"
                    spread
                    @input="getFullTip"
                  />
                </q-card-section>
              </div>
            </div>
          </q-card>
        </div>
      </q-card-section>
      <q-card-section>
        <div><strong>Summary:</strong> {{ total }}</div>
        <div>
          <strong>Tip:</strong> {{ getFullTip() ? getFullTip() : 0 }}
        </div>
      </q-card-section>
      <q-card-actions align="right" class="text-primary q-pt-none">
        <q-btn flat label="Cancel" @click="cancel" />
        <q-btn flat label="Pay" @click="pay" />
      </q-card-actions>
    </q-card>
  </q-dialog>
</template>

<script>
const percentPayments = [
  { label: '5%', value: 5 },
  { label: '10%', value: 10 },
  { label: '15%', value: 15 },
]

const standardPayments = [
  { label: '100', value: 100 },
  { label: '200', value: 200 },
  { label: '500', value: 500 },
]

export default {
  props: {
    showModal: {
      type: Boolean,
      default: false,
    },
    items: {
      type: Array,
      default: () => [],
    },
    total: {
      type: Number,
      default: 0,
    },
  },
  data: function() {
    return {
      show: false,
      togglePercentPayments: new Array(this.items.length).fill(null),
      toggleStandardPayments: new Array(this.items.length).fill(null),
      percentPayments,
      standardPayments,
    }
  },
  watch: {
    showModal(newVal) {
      this.show = newVal
    },
  },
  methods: {
    getEmployerName(master) {
      return `${master?.first_name ?? ''} ${master?.last_name[0] ?? ''}.`
    },
    getPercentage(total, percent) {
      return (total / 100) * percent
    },
    getFullTip() {
      let standardSum = 0
      for (const standardPayment of this.toggleStandardPayments) {
        standardSum += standardPayment
      }

      let percentageSum = 0
      for (const percentagePayment of this.togglePercentPayments) {
        const percent = this.getPercentage(this.total, percentagePayment)
        percentageSum += percent
      }

      return standardSum + percentageSum
    },
    pay() {
      this.$emit('pay', this.getFullTip())
      this.clear()
    },
    cancel() {
      this.$emit('cancel')
      this.clear()
    },
    clear() {
      this.togglePercentPayments = new Array(this.items.length).fill(null)
      this.toggleStandardPayments = new Array(this.items.length).fill(null)
    },
  },
}
</script>

<style scoped>
.set-border {
  border: 1px solid gainsboro;
}
.tip-color {
  color: rgb(4, 171, 171);
}
</style>

如何使 2 个 Quasar 切换按钮组互斥?

【问题讨论】:

    标签: javascript vue.js quasar-framework


    【解决方案1】:

    如果有人需要,这就是解决方案。 Quasar 技术支持的人帮助了我。

    <template>
      <q-dialog v-model="show" no-backdrop-dismiss full-width>
        <q-card>
          <q-card-section class="row items-center">
            <div class="text-h6 tip-color">Tip</div>
            <q-space />
            <q-btn icon="close" flat round dense v-close-popup @click="cancel" />
          </q-card-section>
          <q-card-section style="max-height: 50vh" class="scroll set-border">
            <div class="q-gutter-md">
              <q-card v-for="({ master }, index) in items" :key="master.id">
                <div class="row">
                  <div class="col-3 flex justify-center items-center">
                    <Avatar
                      :src="master.employer_avatar"
                      :size="50"
                      no-default-spinner
                    />
                    <span class="q-ml-md text-caption text-secondary">
                      {{ getEmployerName(master) }}
                    </span>
                  </div>
                  <div class="col">
                    <q-card-section>
                      <q-btn-toggle
                        v-model="togglePayments[index]"
                        toggle-color="primary"
                        :options="percentPayments"
                        spread
                        @input="getTotalTip"
                      />
                    </q-card-section>
                    <q-card-section>
                      <q-btn-toggle
                        v-model="togglePayments[index]"
                        toggle-color="primary"
                        :options="standardPayments"
                        spread
                        @input="getTotalTip"
                      />
                    </q-card-section>
                  </div>
                </div>
              </q-card>
            </div>
          </q-card-section>
          <q-card-section>
            <div><strong>Summary:</strong> {{ total }}</div>
            <div>
              <strong>Tip:</strong> {{ getTotalTip() ? getTotalTip() : 0 }}
            </div>
          </q-card-section>
          <q-card-actions align="right" class="text-primary q-pt-none">
            <q-btn flat label="Cancel" @click="cancel" />
            <q-btn flat label="Pay" @click="pay" />
          </q-card-actions>
        </q-card>
      </q-dialog>
    </template>
    
    <script>
    import { axiosInstance } from 'src/boot/axios'
    import { api } from 'src/api'
    
    const percentPayments = [
      { label: '5%', value: 0.05 },
      { label: '10%', value: 0.1 },
      { label: '15%', value: 0.2 },
    ]
    
    const standardPayments = [
      { label: '100', value: 100 },
      { label: '200', value: 200 },
      { label: '500', value: 500 },
    ]
    
    export default {
      props: {
        showModal: {
          type: Boolean,
          default: false,
        },
        items: {
          type: Array,
          default: () => [],
        },
        total: {
          type: Number,
          default: 0,
        },
        orderId: {
          type: Number,
          required: true,
        },
      },
      data: function() {
        return {
          show: false,
          togglePayments: new Array(this.items.length).fill(0.0),
          percentPayments,
          standardPayments,
        }
      },
      watch: {
        showModal(newVal) {
          this.show = newVal
        },
      },
      methods: {
        getEmployerName(master) {
          return `${master?.first_name ?? ''} ${master?.last_name[0] ?? ''}.`
        },
        getValue(value, amount) {
          const floatValue = Number.parseFloat(value)
          if (floatValue > 1) {
            return floatValue
          }
          return floatValue * amount
        },
        getTotalTip() {
          let totalTip = 0
          for (const tip of this.togglePayments) {
            totalTip += this.getValue(tip, this.total)
          }
    
          return totalTip
        },
        async pay() {
          try {
            const response = await axiosInstance.post(api.payments.all, {
              reason_type: 'order',
              reason_id: this.orderId,
              amount: this.total + this.getTotalTip(),
            })
            this.$store.commit('booking/setCreatedPayment', response.data.data)
            this.$router.push({ name: 'Payment' })
          } catch (e) {
            console.info(e)
          }
        },
        cancel() {
          this.$emit('cancel')
          this.clear()
        },
        clear() {
          this.togglePercentPayments = new Array(this.items.length).fill(0.0)
          this.toggleStandardPayments = new Array(this.items.length).fill(0.0)
        },
      },
    }
    </script>
    
    <style scoped>
    .set-border {
      border: 1px solid gainsboro;
    }
    .tip-color {
      color: rgb(4, 171, 171);
    }
    </style>
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-06-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-03-17
      相关资源
      最近更新 更多