首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何用vuetify的选项卡而不是按钮触发vuetify对话框

如何用vuetify的选项卡而不是按钮触发vuetify对话框
EN

Stack Overflow用户
提问于 2021-04-11 04:06:11
回答 1查看 742关注 0票数 0

我正试图用vuetify的选项卡触发一个vuetify对话框。我不知道如何做到这一点。我有两个组件,Tabs.vue和Dialog.vue。

从vuetify,Tabs.vue组件是:

代码语言:javascript
运行
复制
<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>

Dialog组件是:

代码语言:javascript
运行
复制
<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组件中的一个按钮的示例,我将再次粘贴下面代码的这一部分:

代码语言:javascript
运行
复制
<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的对话框。谢谢

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-04-11 05:09:18

我为你做了一个CodeSandbox。如果这是你想要的,我会在事后解释我做了什么。检查这里

好的..。

首先,让我们检查一下您的结构。您将Dialog.vue封装在它自己的组件中,这意味着您需要从外部切换Dialog /Off机制,即父(Tabs.vue)。

Tabs.vue

代码语言:javascript
运行
复制
<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上收听它。

代码语言:javascript
运行
复制
<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函数

代码语言:javascript
运行
复制
methods: {
    toggleDialog(tab) {
      this.tabControll = tab;
      this.dialog = true;
    },
  },

它什么也不做,然后将data中的data切换为true,并设置tabControll以让Dialog.vue知道单击了哪个选项卡。

Dialog.vue

现在我们准备好Dialog.vue来处理外部控制的行为。

代码语言:javascript
运行
复制
<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>

我们保持一致,我们不使用showDialog道具在我们的v-model="dialog",否则我们得到一个警告,我们突变道具,而不知道父母(Tabs.vue)

代码语言:javascript
运行
复制
<v-dialog v-model="dialog" persistent max-width="600px">

相反,我们将传入的支柱数据绑定到数据中的dialog中。

代码语言:javascript
运行
复制
data() {
    return {
      dialog: this.showDialog,
    };
  },

现在我们不从外部修改道具,只复制从Tabs.vue处理的对话框的状态。

如果现在单击Tab,则事件将将此showDialog切换为true,这将将数据中的dialog更改为true并显示对话框。

到目前为止还不错..。现在我们需要功能来再次关闭对话框。

正如我多次说过的,变异道具是一件坏事,我们触发一个$emit,然后告诉Tabs.vue再次关闭对话框。

代码语言:javascript
运行
复制
<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

代码语言:javascript
运行
复制
<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
    />
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/67041365

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档