自定义确认组件未在 vue.js 中的 v-menu 内打开

问题描述 投票:0回答:1

每当单击标题上的任何按钮时,我都会尝试显示确认组件。每当我单击除使用 v 菜单的下拉列表之外的其他元素时,它都会打开。

应用程序.vue

<template>
  {{isConfirmDialogVisible}}
  <div class="header">
    <div class="left-menus">
      <div
        v-for="(item, index) in items"
        :key="index"
        class="menu"
        style="background-color: red; gap: 10px; padding: 10px"
        @click="opendialog()"
      >
        {{ item.title }}
      </div>
    </div>
    <v-menu open-on-hover transition="slide-y-transition">
      <template #activator="{ props }">
        <div style="cursor: pointer">
          <v-icon v-bind="props">mdi-menu-down</v-icon>
        </div>
      </template>

      <v-list>
        <v-list-item
          v-for="(item, index) in userOptions"
          :key="index"
          class="dropdown"
          @click="opendialog()"
        >
          <v-list-item-title>{{ item.title }}</v-list-item-title>
        </v-list-item>
      </v-list>
    </v-menu>
    <Confirmation
      v-model="isConfirmDialogVisible"
      v-if="isConfirmDialogVisible"
      action-button="submit"
      action-button-left="cancle"
      action-button-right="confirm"
    >
      <div style="font-size: 20px">Are you sure?</div>
    </Confirmation>
  </div>
</template>

<script>
  import { ref } from 'vue'
  import Confirmation from './Confirmation.vue'

  const isConfirmDialogVisible = ref(false)

  const userOptions = ref([{ title: 'Logout' }, { title: 'Setting' }])

  const opendialog = () => {
    isConfirmDialogVisible.value = true
  }

  export default {
    components: {
      Confirmation,
    },
    data: () => ({
      items: [
        { title: 'Click Me' },
        { title: 'Click Me' },
        { title: 'Click Me' },
        { title: 'Click Me 2' },
      ],

      opendialog,
      isConfirmDialogVisible,
      userOptions,
    }),
  }
</script>

<style>
  .header .left-menus {
    display: flex;
    align-items: center;
    gap: 16px;
  }
</style>

确认.vue

<template>
  <v-dialog v-model="dialogVisible" persistent activator="parent" width="auto">
    <div class="dialog_container">
      <v-card>
        <div class="card-components">
          <div class="warning_image"></div>
          <v-card-text>
            <slot></slot>
          </v-card-text>
          <v-card-actions>
            <v-btn class="back" @click="closeDialog"
              >{{ actionButtonLeft }}</v-btn
            >
            <v-btn @click="confirmSelection" class="confirm-submit">
              {{ actionButtonRight}}
            </v-btn>
          </v-card-actions>
        </div>
      </v-card>
    </div>
  </v-dialog>
</template>
<script>
  import { ref } from 'vue'

  export default {
    props: {
      modelValue: Boolean,
      actionButton: {
        type: String,
        required: true,
      },
      actionButtonRight: {
        type: String,
        required: true,
      },
      actionButtonLeft: {
        type: String,
        required: false,
        default: 'cancel',
      },
    },

    emits: ['update:modelValue', 'confirmAction'],
    setup(props, { emit }) {
      const dialogVisible = ref(false)
      const closeDialog = () => {
        dialogVisible.value = false
        emit('update:modelValue', false)
      }
      const confirmSelection = () => {
        closeDialog()
        emit('confirmAction')
      }

      const returnBack = () => {
        closeDialog()
      }

      const handleOutsideClick = event => {
        console.log(event)
      }

      return {
        dialogVisible,
        closeDialog,
        returnBack,
        confirmSelection,
        handleOutsideClick,
      }
    },
  }
</script>

<style scoped>
  .card-components {
    display: flex;
    flex-direction: column;
    gap: 24px;
  }

  .dialog_container {
    height: 225px;
    width: 648px;
  }
  .v-card {
    padding: 16px 24px 24px 24px;
  }
  .v-card-text {
    padding: 0;
  }
  .warning_image {
    display: flex;
    width: 100%;
    justify-content: center;
  }

  .v-card-actions {
    min-height: 0;
    padding: 0;
    display: flex;
    justify-content: flex-end;
  }
  .v-card-actions .v-btn {
    border: 1px solid #9ca3af;
    color: #9ca3af;
    width: 140px;
    justify-content: center;
    align-items: center;
    border-radius: 4px;
  }

  .v-card-actions .confirm-submit {
    color: white;
    border: 1px solid #41a1e0;
    background: #41a1e0;
  }
</style>

每当单击标题上的任何按钮时,我都会尝试显示确认组件。每当我单击除使用 v 菜单的下拉列表之外的其他元素时,它都会打开。

javascript vue.js frontend nuxt.js vuetify.js
1个回答
0
投票

在Confirmation.vue中,VDialog依赖父组件变得可见:

<template>
  <v-dialog v-model="dialogVisible" activator="parent">
  ...
</template>
<script setup>
  const dialogVisible = ref(false)
  ...
</script>

因此,当确认组件变得可见时,VDialog 将显示对话框并更新

dialogVisible

由于某种原因,当 VMenu 可见时这不起作用。相反,使用组件的

modelValue
来触发对话框,无论如何这更有意义。有几种方法可以做到这一点,一种是在观察者中设置
dialogVisible

setup(props, { emit }) {
  const dialogVisible = ref(false)
  watchEffect(() => dialogVisible.value = props.modelValue)

这是在游乐场

© www.soinside.com 2019 - 2024. All rights reserved.