You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Vue3+Vuetify3中V-dialog子组件模态框异常问题求助

Vue3 + Vuetify3 封装V-dialog子组件无法正常工作

在Vue3和Vuetify3环境下封装V-dialog为独立子组件作为模态框使用,但组件无法正常工作,怀疑子组件props更新时未同步到父组件。已尝试Vue2/Vuetify2语法、:show.sync,均无效。

父组件调用代码

<VehiclesNoteModal
  :id="this.id"
  v-model="noteModal.show"
  :noteFetch="noteFetch"
></VehiclesNoteModal>

子组件代码

<template>
  <v-dialog v-model="this.modelValue" width="500">
    <v-card>
      <v-toolbar title="Unos napomene"></v-toolbar>
      <v-card-text>
        <v-form @submit.prevent="submit" ref="frm">
          <v-text-field
            variant="solo"
            v-model="item.noteTitle"
            label="Naslov"
            :rules="[this.$required]"
          ></v-text-field>
          <v-textarea
            variant="solo"
            v-model="item.note"
            label="Napomena"
            :rules="[this.$required, this.$max(150)]"
            no-resize
            counter="150"
          ></v-textarea>
          <v-card-actions class="justify-space-between">
            <v-spacer></v-spacer>
            <v-btn
              type="submit"
              variant="elevated"
              color="#306bac"
              class="btnAdd mr-3"
              ><v-icon size="20px" class="mdi mdi-plus"></v-icon> Dodaj</v-btn
            >
            <v-btn
              variant="elevated"
              @click.prevent="this.$emit('update:modelValue', false)"
            >
              <v-icon size="25px" color="#306bac">mdi mdi-close</v-icon>
              Zatvori</v-btn
            >
          </v-card-actions>
        </v-form>
      </v-card-text>
    </v-card>
  </v-dialog>
</template>

<script>
import axios from "axios";

export default {
  props: {
    modelValue: Boolean, // Change the prop name to modelValue
    id: {
      required: true,
    },
    noteFetch: {
      required: true,
      type: Function,
    },
  },
  data() {
    return {
      item: {
        noteTitle: null,
        note: null,
        vehicleId: this.id,
      },
    };
  },
  methods: {
    submit() {
      axios
        .post(this.$API_BASE_URL + "/vehicles/notes/add", this.item)
        .then((response) => {
          console.log(response);
          this.noteFetch();
          this.$emit("update:modelValue", false); // Emit the update:modelValue event
        });
    },
  },
};
</script>
<style scoped>
.btnAdd {
  color: white;
}
.v-toolbar {
  background-color: white;
}
</style>

问题排查与修复

你的代码存在几个核心问题导致组件失效,逐一修复即可:

1. 模板中错误使用this

Vue3模板里不需要(也不允许)用this访问props、data或方法,直接引用名称即可:

  • 将<v-dialog v-model="this.modelValue"改为<v-dialog v-model="isOpen"(后续会处理双向绑定)
  • 将:rules="[this.$required]"改为:rules="[$required]"
  • 将@click.prevent="this.$emit('update:modelValue', false)"改为@click.prevent="$emit('update:modelValue', false)"

2. 处理V-dialog的双向绑定

Vuetify的v-dialog会内部修改绑定值,但props是只读的,不能直接绑定modelValue。需要在子组件声明本地变量,同步modelValue的变化:

<template>
  <v-dialog v-model="isOpen" width="500">
    <!-- 其余模板内容保持不变 -->
  </v-dialog>
</template>

<script>
export default {
  props: {
    modelValue: Boolean,
    // 其他props不变
  },
  data() {
    return {
      isOpen: this.modelValue,
      item: {
        noteTitle: null,
        note: null,
        vehicleId: this.id,
      },
    };
  },
  watch: {
    // 监听父组件传来的modelValue,同步到本地变量
    modelValue(newVal) {
      this.isOpen = newVal;
    },
    // 监听本地变量变化,通知父组件更新
    isOpen(newVal) {
      this.$emit('update:modelValue', newVal);
    }
  },
  // 其余方法不变
};
</script>

3. 同步id prop的变化

当前item.vehicleId仅在组件初始化时赋值,父组件id变化时子组件不会更新,添加watch监听:

watch: {
  id(newId) {
    this.item.vehicleId = newId;
  },
  // 之前的modelValue和isOpen监听保留
}

4. 父组件移除多余的this

父组件模板里同样不需要this,将:id="this.id"改为:id="id"。

内容的提问来源于stack exchange,提问作者Dragan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.11 23:55:25