如何使用 vuetify 的选项卡而不是按钮触发 vuetify 对话框
How to trigger vuetify dialog with vuetify's tab instead of a button
我正在尝试使用 vuetify 的选项卡触发 vuetify 对话框。我不确定如何实现。我有两个组件,Tabs.vue 和 Dialog.vue。
来自 vuetify,Tabs.vue 组件是:
<template>
<v-card>
<v-tabs
v-model="tab"
background-color="deep-purple accent-4"
centered
dark
icons-and-text
>
<v-tabs-slider></v-tabs-slider>
<v-tab href="#tab-1">
Recents
<v-icon>mdi-phone</v-icon>
</v-tab>
<v-tab href="#tab-2">
Favorites
<v-icon>mdi-heart</v-icon>
</v-tab>
<v-tab href="#tab-3">
Nearby
<v-icon>mdi-account-box</v-icon>
</v-tab>
</v-tabs>
<v-tabs-items v-model="tab">
<v-tab-item
v-for="i in 3"
:key="i"
:value="'tab-' + i"
>
<v-card flat>
<v-card-text>{{ text }}</v-card-text>
</v-card>
</v-tab-item>
</v-tabs-items>
</v-card>
</template>
对话框组件是:
<template>
<v-row justify="center">
<v-dialog
v-model="dialog"
persistent
max-width="600px"
>
<template v-slot:activator="{ on, attrs }">
<v-btn
color="primary"
dark
v-bind="attrs"
v-on="on"
>
Open Dialog
</v-btn>
</template>
<v-card>
<v-card-title>
<span class="headline">User Profile</span>
</v-card-title>
<v-card-text>
<v-container>
<v-row>
<v-col
cols="12"
sm="6"
md="4"
>
<v-text-field
label="Legal first name*"
required
></v-text-field>
</v-col>
<v-col
cols="12"
sm="6"
md="4"
>
<v-text-field
label="Legal middle name"
hint="example of helper text only on focus"
></v-text-field>
</v-col>
<v-col
cols="12"
sm="6"
md="4"
>
<v-text-field
label="Legal last name*"
hint="example of persistent helper text"
persistent-hint
required
></v-text-field>
</v-col>
<v-col cols="12">
<v-text-field
label="Email*"
required
></v-text-field>
</v-col>
<v-col cols="12">
<v-text-field
label="Password*"
type="password"
required
></v-text-field>
</v-col>
<v-col
cols="12"
sm="6"
>
<v-select
:items="['0-17', '18-29', '30-54', '54+']"
label="Age*"
required
></v-select>
</v-col>
<v-col
cols="12"
sm="6"
>
<v-autocomplete
:items="['Skiing', 'Ice hockey', 'Soccer', 'Basketball', 'Hockey', 'Reading', 'Writing', 'Coding', 'Basejump']"
label="Interests"
multiple
></v-autocomplete>
</v-col>
</v-row>
</v-container>
<small>*indicates required field</small>
</v-card-text>
<v-card-actions>
<v-spacer></v-spacer>
<v-btn
color="blue darken-1"
text
@click="dialog = false"
>
Close
</v-btn>
<v-btn
color="blue darken-1"
text
@click="dialog = false"
>
Save
</v-btn>
</v-card-actions>
</v-card>
</v-dialog>
</v-row>
</template>
请注意,我直接从 vuetify 复制了每个组件。如您所见,为了触发对话框,vuetify 给出了使用 Dialog.vue 组件内的按钮的示例,我将再次粘贴下面的那部分代码:
<template v-slot:activator="{ on, attrs }">
<v-btn
color="primary"
dark
v-bind="attrs"
v-on="on"
>
Open Dialog
</v-btn>
</template>
它正在使用 v-slot:activator
触发对话框。但是,我不确定如何使用 Tabs.vue 中的选项卡之一来触发来自 Dialogs.vue 的对话框。谢谢
我为你做了一个CodeSandbox。如果这是你想要的,我会在之后解释我所做的。 Check here
好的...
首先让我们检查一下您的结构。
您将 Dialog.vue
包装在它自己的组件中,这意味着您现在需要从外部切换 Dialog On/Off 机制,即 parent(Tabs.vue
).
Tabs.vue
<template>
<v-card>
<v-tabs
background-color="deep-purple accent-4"
centered
dark
icons-and-text
>
<v-tabs-slider></v-tabs-slider>
<v-tab href="#tab-1" @change="toggleDialog('recents')">
Recents
<v-icon>mdi-phone</v-icon>
</v-tab>
<v-tab href="#tab-2" @change="toggleDialog('favorites')">
Favorites
<v-icon>mdi-heart</v-icon>
</v-tab>
<v-tab href="#tab-3" @change="toggleDialog('nearby')">
Nearby
<v-icon>mdi-account-box</v-icon>
</v-tab>
</v-tabs>
<v-tabs-items>
<v-tab-item v-for="i in 3" :key="i" :value="'tab-' + i">
<v-card flat>
<v-card-text>{{ text }}</v-card-text>
</v-card>
</v-tab-item>
</v-tabs-items>
<Dialog <--------------------------- ADDING component Dialog.vue
:show-dialog="dialog" <----------- PROP the On/Off logic
:tab-controll="tabControll" <----- PROP the "which tab is selected"
@close-dialog="dialog = false" <-- TOGGLE Off on "close" button
@save-dialog="dialog = false" <--- TOGGLE Off on "save" button
/>
</v-card>
</template>
<script>
import Dialog from "@/components/Dialog";
export default {
components: {
Dialog,
},
data() {
return {
tab: 0,
dialog: false, <--------- CONTROLLS the On/Off mechanism inside Dialog.vue
tabControll: "None Tab",<- CONTROLLS which tab is selected in Dialog.vue
text: "some text i guess",
};
},
methods: {
toggleDialog(tab) {
this.tabControll = tab;
this.dialog = true;
},
},
};
</script>
<style>
</style>
每个 v-tab
都有自己的 changed
事件,这就是为什么你需要在每个 v-tab
.
上收听它
<v-tabs
background-color="deep-purple accent-4"
centered
dark
icons-and-text
>
<v-tabs-slider></v-tabs-slider>
<v-tab href="#tab-1" @change="toggleDialog('recents')"> <------- @change
Recents
<v-icon>mdi-phone</v-icon>
</v-tab>
<v-tab href="#tab-2" @change="toggleDialog('favorites')"> <------- @change
Favorites
<v-icon>mdi-heart</v-icon>
</v-tab>
<v-tab href="#tab-3" @change="toggleDialog('nearby')"> <------- @change
Nearby
<v-icon>mdi-account-box</v-icon>
</v-tab>
</v-tabs>
现在让我们看看 toggleDialog
函数
methods: {
toggleDialog(tab) {
this.tabControll = tab;
this.dialog = true;
},
},
它什么都不做,然后将 data
中的 dialog
切换为 true 并设置 tabControll
让 Dialog.vue
知道单击了哪个选项卡。
Dialog.vue
现在我们准备Dialog.vue
来处理外部控制的行为。
<template>
<v-row justify="center">
<v-dialog v-model="dialog" persistent max-width="600px"> <--------- HERE
<v-card>
<v-card-title>
<span class="headline">User Profile - {{ tabControll }}</span>
</v-card-title>
<v-card-text>
<v-container>
<v-row>
<v-col cols="12" sm="6" md="4">
<v-text-field label="Legal first name*" required></v-text-field>
</v-col>
<v-col cols="12" sm="6" md="4">
<v-text-field
label="Legal middle name"
hint="example of helper text only on focus"
></v-text-field>
</v-col>
<v-col cols="12" sm="6" md="4">
<v-text-field
label="Legal last name*"
hint="example of persistent helper text"
persistent-hint
required
></v-text-field>
</v-col>
<v-col cols="12">
<v-text-field label="Email*" required></v-text-field>
</v-col>
<v-col cols="12">
<v-text-field
label="Password*"
type="password"
required
></v-text-field>
</v-col>
<v-col cols="12" sm="6">
<v-select
:items="['0-17', '18-29', '30-54', '54+']"
label="Age*"
required
></v-select>
</v-col>
<v-col cols="12" sm="6">
<v-autocomplete
:items="[
'Skiing',
'Ice hockey',
'Soccer',
'Basketball',
'Hockey',
'Reading',
'Writing',
'Coding',
'Basejump',
]"
label="Interests"
multiple
></v-autocomplete>
</v-col>
</v-row>
</v-container>
<small>*indicates required field</small>
</v-card-text>
<v-card-actions>
<v-spacer></v-spacer>
<v-btn color="blue darken-1" text @click="$emit('close-dialog')">
Close
</v-btn>
<v-btn color="blue darken-1" text @click="$emit('save-dialog')">
Save
</v-btn>
</v-card-actions>
</v-card>
</v-dialog>
</v-row>
</template>
<script>
export default {
data() {
return {
dialog: this.showDialog,
};
},
watch: {
showDialog: function () {
this.dialog = this.showDialog;
},
},
props: {
showDialog: {
type: Boolean,
default: false,
},
tabControll: {
type: String,
default: "none",
},
},
};
</script>
<style>
</style>
我们保持一致并且我们不在我们的 v-model="dialog"
中使用 showDialog
道具,否则我们会收到警告,我们在不知道 parent 的情况下改变道具(Tabs.vue
)
<v-dialog v-model="dialog" persistent max-width="600px">
相反,我们将传入的 prop 数据绑定到我们的 dialog
内部数据
data() {
return {
dialog: this.showDialog,
};
},
现在我们不从外部改变道具,我们只是复制从 Tabs.vue
处理的对话框的状态
如果您现在单击选项卡,事件会将此 showDialog
切换为 true,这会将数据中的 dialog
也更改为 true 并显示对话框。
到目前为止一切顺利...现在我们需要再次关闭对话框的功能。
正如我多次说过的,改变道具是一件坏事,我们触发 $emit 并告诉 Tabs.vue
再次关闭对话框。
<v-btn color="blue darken-1" text @click="$emit('close-dialog')">
Close
</v-btn>
<v-btn color="blue darken-1" text @click="$emit('save-dialog')">
Save
</v-btn>
回到
Tabs.vue
我们监听那些自定义事件并切换 dialog = false
就在这里
<Dialog
:show-dialog="dialog"
:tab-controll="tabControll"
@close-dialog="dialog = false" <-- TOGGLE Off on "close" button
@save-dialog="dialog = false" <--- TOGGLE Off on "save" button
/>
我正在尝试使用 vuetify 的选项卡触发 vuetify 对话框。我不确定如何实现。我有两个组件,Tabs.vue 和 Dialog.vue。
来自 vuetify,Tabs.vue 组件是:
<template>
<v-card>
<v-tabs
v-model="tab"
background-color="deep-purple accent-4"
centered
dark
icons-and-text
>
<v-tabs-slider></v-tabs-slider>
<v-tab href="#tab-1">
Recents
<v-icon>mdi-phone</v-icon>
</v-tab>
<v-tab href="#tab-2">
Favorites
<v-icon>mdi-heart</v-icon>
</v-tab>
<v-tab href="#tab-3">
Nearby
<v-icon>mdi-account-box</v-icon>
</v-tab>
</v-tabs>
<v-tabs-items v-model="tab">
<v-tab-item
v-for="i in 3"
:key="i"
:value="'tab-' + i"
>
<v-card flat>
<v-card-text>{{ text }}</v-card-text>
</v-card>
</v-tab-item>
</v-tabs-items>
</v-card>
</template>
对话框组件是:
<template>
<v-row justify="center">
<v-dialog
v-model="dialog"
persistent
max-width="600px"
>
<template v-slot:activator="{ on, attrs }">
<v-btn
color="primary"
dark
v-bind="attrs"
v-on="on"
>
Open Dialog
</v-btn>
</template>
<v-card>
<v-card-title>
<span class="headline">User Profile</span>
</v-card-title>
<v-card-text>
<v-container>
<v-row>
<v-col
cols="12"
sm="6"
md="4"
>
<v-text-field
label="Legal first name*"
required
></v-text-field>
</v-col>
<v-col
cols="12"
sm="6"
md="4"
>
<v-text-field
label="Legal middle name"
hint="example of helper text only on focus"
></v-text-field>
</v-col>
<v-col
cols="12"
sm="6"
md="4"
>
<v-text-field
label="Legal last name*"
hint="example of persistent helper text"
persistent-hint
required
></v-text-field>
</v-col>
<v-col cols="12">
<v-text-field
label="Email*"
required
></v-text-field>
</v-col>
<v-col cols="12">
<v-text-field
label="Password*"
type="password"
required
></v-text-field>
</v-col>
<v-col
cols="12"
sm="6"
>
<v-select
:items="['0-17', '18-29', '30-54', '54+']"
label="Age*"
required
></v-select>
</v-col>
<v-col
cols="12"
sm="6"
>
<v-autocomplete
:items="['Skiing', 'Ice hockey', 'Soccer', 'Basketball', 'Hockey', 'Reading', 'Writing', 'Coding', 'Basejump']"
label="Interests"
multiple
></v-autocomplete>
</v-col>
</v-row>
</v-container>
<small>*indicates required field</small>
</v-card-text>
<v-card-actions>
<v-spacer></v-spacer>
<v-btn
color="blue darken-1"
text
@click="dialog = false"
>
Close
</v-btn>
<v-btn
color="blue darken-1"
text
@click="dialog = false"
>
Save
</v-btn>
</v-card-actions>
</v-card>
</v-dialog>
</v-row>
</template>
请注意,我直接从 vuetify 复制了每个组件。如您所见,为了触发对话框,vuetify 给出了使用 Dialog.vue 组件内的按钮的示例,我将再次粘贴下面的那部分代码:
<template v-slot:activator="{ on, attrs }">
<v-btn
color="primary"
dark
v-bind="attrs"
v-on="on"
>
Open Dialog
</v-btn>
</template>
它正在使用 v-slot:activator
触发对话框。但是,我不确定如何使用 Tabs.vue 中的选项卡之一来触发来自 Dialogs.vue 的对话框。谢谢
我为你做了一个CodeSandbox。如果这是你想要的,我会在之后解释我所做的。 Check here
好的...
首先让我们检查一下您的结构。
您将 Dialog.vue
包装在它自己的组件中,这意味着您现在需要从外部切换 Dialog On/Off 机制,即 parent(Tabs.vue
).
Tabs.vue
<template>
<v-card>
<v-tabs
background-color="deep-purple accent-4"
centered
dark
icons-and-text
>
<v-tabs-slider></v-tabs-slider>
<v-tab href="#tab-1" @change="toggleDialog('recents')">
Recents
<v-icon>mdi-phone</v-icon>
</v-tab>
<v-tab href="#tab-2" @change="toggleDialog('favorites')">
Favorites
<v-icon>mdi-heart</v-icon>
</v-tab>
<v-tab href="#tab-3" @change="toggleDialog('nearby')">
Nearby
<v-icon>mdi-account-box</v-icon>
</v-tab>
</v-tabs>
<v-tabs-items>
<v-tab-item v-for="i in 3" :key="i" :value="'tab-' + i">
<v-card flat>
<v-card-text>{{ text }}</v-card-text>
</v-card>
</v-tab-item>
</v-tabs-items>
<Dialog <--------------------------- ADDING component Dialog.vue
:show-dialog="dialog" <----------- PROP the On/Off logic
:tab-controll="tabControll" <----- PROP the "which tab is selected"
@close-dialog="dialog = false" <-- TOGGLE Off on "close" button
@save-dialog="dialog = false" <--- TOGGLE Off on "save" button
/>
</v-card>
</template>
<script>
import Dialog from "@/components/Dialog";
export default {
components: {
Dialog,
},
data() {
return {
tab: 0,
dialog: false, <--------- CONTROLLS the On/Off mechanism inside Dialog.vue
tabControll: "None Tab",<- CONTROLLS which tab is selected in Dialog.vue
text: "some text i guess",
};
},
methods: {
toggleDialog(tab) {
this.tabControll = tab;
this.dialog = true;
},
},
};
</script>
<style>
</style>
每个 v-tab
都有自己的 changed
事件,这就是为什么你需要在每个 v-tab
.
<v-tabs
background-color="deep-purple accent-4"
centered
dark
icons-and-text
>
<v-tabs-slider></v-tabs-slider>
<v-tab href="#tab-1" @change="toggleDialog('recents')"> <------- @change
Recents
<v-icon>mdi-phone</v-icon>
</v-tab>
<v-tab href="#tab-2" @change="toggleDialog('favorites')"> <------- @change
Favorites
<v-icon>mdi-heart</v-icon>
</v-tab>
<v-tab href="#tab-3" @change="toggleDialog('nearby')"> <------- @change
Nearby
<v-icon>mdi-account-box</v-icon>
</v-tab>
</v-tabs>
现在让我们看看 toggleDialog
函数
methods: {
toggleDialog(tab) {
this.tabControll = tab;
this.dialog = true;
},
},
它什么都不做,然后将 data
中的 dialog
切换为 true 并设置 tabControll
让 Dialog.vue
知道单击了哪个选项卡。
Dialog.vue
现在我们准备Dialog.vue
来处理外部控制的行为。
<template>
<v-row justify="center">
<v-dialog v-model="dialog" persistent max-width="600px"> <--------- HERE
<v-card>
<v-card-title>
<span class="headline">User Profile - {{ tabControll }}</span>
</v-card-title>
<v-card-text>
<v-container>
<v-row>
<v-col cols="12" sm="6" md="4">
<v-text-field label="Legal first name*" required></v-text-field>
</v-col>
<v-col cols="12" sm="6" md="4">
<v-text-field
label="Legal middle name"
hint="example of helper text only on focus"
></v-text-field>
</v-col>
<v-col cols="12" sm="6" md="4">
<v-text-field
label="Legal last name*"
hint="example of persistent helper text"
persistent-hint
required
></v-text-field>
</v-col>
<v-col cols="12">
<v-text-field label="Email*" required></v-text-field>
</v-col>
<v-col cols="12">
<v-text-field
label="Password*"
type="password"
required
></v-text-field>
</v-col>
<v-col cols="12" sm="6">
<v-select
:items="['0-17', '18-29', '30-54', '54+']"
label="Age*"
required
></v-select>
</v-col>
<v-col cols="12" sm="6">
<v-autocomplete
:items="[
'Skiing',
'Ice hockey',
'Soccer',
'Basketball',
'Hockey',
'Reading',
'Writing',
'Coding',
'Basejump',
]"
label="Interests"
multiple
></v-autocomplete>
</v-col>
</v-row>
</v-container>
<small>*indicates required field</small>
</v-card-text>
<v-card-actions>
<v-spacer></v-spacer>
<v-btn color="blue darken-1" text @click="$emit('close-dialog')">
Close
</v-btn>
<v-btn color="blue darken-1" text @click="$emit('save-dialog')">
Save
</v-btn>
</v-card-actions>
</v-card>
</v-dialog>
</v-row>
</template>
<script>
export default {
data() {
return {
dialog: this.showDialog,
};
},
watch: {
showDialog: function () {
this.dialog = this.showDialog;
},
},
props: {
showDialog: {
type: Boolean,
default: false,
},
tabControll: {
type: String,
default: "none",
},
},
};
</script>
<style>
</style>
我们保持一致并且我们不在我们的 v-model="dialog"
中使用 showDialog
道具,否则我们会收到警告,我们在不知道 parent 的情况下改变道具(Tabs.vue
)
<v-dialog v-model="dialog" persistent max-width="600px">
相反,我们将传入的 prop 数据绑定到我们的 dialog
内部数据
data() {
return {
dialog: this.showDialog,
};
},
现在我们不从外部改变道具,我们只是复制从 Tabs.vue
如果您现在单击选项卡,事件会将此 showDialog
切换为 true,这会将数据中的 dialog
也更改为 true 并显示对话框。
到目前为止一切顺利...现在我们需要再次关闭对话框的功能。
正如我多次说过的,改变道具是一件坏事,我们触发 $emit 并告诉 Tabs.vue
再次关闭对话框。
<v-btn color="blue darken-1" text @click="$emit('close-dialog')">
Close
</v-btn>
<v-btn color="blue darken-1" text @click="$emit('save-dialog')">
Save
</v-btn>
回到
Tabs.vue
我们监听那些自定义事件并切换 dialog = false
就在这里
<Dialog
:show-dialog="dialog"
:tab-controll="tabControll"
@close-dialog="dialog = false" <-- TOGGLE Off on "close" button
@save-dialog="dialog = false" <--- TOGGLE Off on "save" button
/>