如何解决如何实现可重用的 vuetify 对话框
我想用 vuetify 创建一个可重用的 v-dialog, 我创建了 BaseModal:
<v-dialog
v-model="inputVal"
:hide-overlay="overlay"
:max-width="width"
>
<v-card>
<v-toolbar flat>
<v-btn color="black" dark icon right @click="closeModal">
<v-icon>mdi-close</v-icon>
</v-btn>
<v-spacer></v-spacer>
<v-toolbar-title id="toolbar-title">{{ title }}</v-toolbar-title>
</v-toolbar>
<v-card-title class="headline">
<!--Card Title-->
</v-card-title>
<v-card-text>
<slot name="content"></slot>
</v-card-text>
</v-card>
</v-dialog>
InputVal 作为计算和 dataBindingName 作为道具:
computed: {
inputVal: {
get() {
return this.dataBindingName;
},set(val) {
this.$emit("input",val);
}
}
},props: {
dataBindingName: {
Boolean,required: false
},}
我在另一个组件中调用这个基本组件,如下所示:
<modal-simple
:dataBindingName="dataBindingName"
title="Nouveau"
width="418"
>
<template v-slot:content>
<add-time-sheet-form />
</template>
</modal-simple>
我现在的问题是如何正确实现 closeModal 以及如何在内部实现关闭模态并打开新模态的按钮
解决方法
第 1 部分。模态组件。
注意不要不要使用 v-model="dialog"。如前所述in this answer,您需要将其替换为:value 和@input。
此外,您不应该直接改变 dialog 道具,这就是为什么您需要在需要关闭模态时发出 close-dialog 事件。
<template>
<v-dialog
:value="dialog"
@input="$emit('input',$event)"
max-width="500px"
persistent
>
<v-card>
<v-card-title>
... dialog header ...
</v-card-title>
<v-card-text>
... dialog content ...
</v-card-text>
<v-card-actions>
<v-spacer />
<v-btn @click="close">
Close
</v-btn>
</v-card-actions>
</v-card>
</v-dialog>
</template>
<script>
export default {
props: {
editedId: Number,dialog: Boolean,},methods: {
close() {
this.$emit("close-dialog");
},};
</script>
第 2 部分。父组件。
假设您想在添加或编辑实体时使用您的组件。
您需要实现两个方法:addItem 和 editItem 来打开您的对话框。您还需要传递额外的实体道具(在我的示例中为 editedId)、带有 sync modifier 的 dialog 道具和 close-dialog 事件处理程序这是从模态组件发出的。
<template>
<div>
<v-toolbar flat color="white">
<v-spacer />
<edit-modal
:edited-id="editedId"
:dialog.sync="dialog"
@close-dialog="
editedId = null;
dialog = false;
"
/>
<v-btn color="primary" dark class="mb-2" @click="addItem">
Add entity
</v-btn>
</v-toolbar>
<v-data-table :items="items" :headers="headers">
<template v-slot:item="props">
<tr>
<td>{{ props.item.name }}</td>
<td class="justify-center text-center">
<v-icon small class="mr-2" @click="editItem(props.item)">
edit
</v-icon>
</td>
</tr>
</template>
</v-data-table>
</div>
</template>
<script>
import Dialog from "./ReusableDialog";
export default {
components: {
"edit-modal": Dialog,data() {
return {
items: [
... some items ...
],headers: [
... some headers ...
],editedId: null,dialog: false,};
},methods: {
addItem() {
this.dialog = true;
},editItem(item) {
this.editedId = item.id;
this.dialog = true;
},};
</script>
第 3 部分。修改模态以自动重新打开。
在这个例子中,模态组件会自动重新打开,直到 editedId 不会被设置。
在模态组件中:
...
close() {
this.$emit("close-dialog");
if (this.editedId === null) {
this.$emit("open-dialog");
}
},...
在父组件中:
...
<edit-modal
... some props ...
@open-dialog="
editedId = 999;
dialog = true;
"
/>
...
有一个 codesandbox with working example。
,这是我使用 Composition API
插件 + provide/inject
的实现:
https://gist.github.com/wobsoriano/1e63708d7771c34f835c0f6e3c5e731a
您只需要在提供的要点中使用 DialogProvider
组件包装模板组件,如下所示:
<template>
<v-app>
<v-main>
<v-container>
<DialogProvider>
<Nuxt />
</DialogProvider>
</v-container>
</v-main>
</v-app>
</template>
<script lang="ts">
import { defineComponent } from '@nuxtjs/composition-api';
import DialogProvider from '~/components/DialogProvider.vue';
export default defineComponent({
components: {
DialogProvider,}
});
</script>
然后您可以使用 useDialog
可组合在任何地方显示确认对话框:
<script lang="ts">
import { defineComponent } from '@nuxtjs/composition-api';
import { useDialog } from '~/composables';
export default defineComponent({
setup() {
const createConfirmDialog = useDialog();
const handleDelete = async () => {
try {
const shouldProceed = await createConfirmDialog(
'Confirm','Delete this post?',{ width: 300 }
);
if (shouldProceed) {
// delete post
}
} catch (_e) {}
};
return {
handleDelete
};
},});
</script>
它也对 TypeScript 友好。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。