为什么我的对话框堆叠在一起?(Vutify)

2022-03-01 00:00:00 javascript vue.js vuetify.js

所以,我正在学习Vutify,并且正在实现卡片和对话框。我只是按照 证明文档。我试图通过我的实现实现的目标:

  • 用户可以单击卡以打开显示更多信息的对话框 有关项目的信息。

  • 用户可以点击"添加到购物车",卡片将加载约3年 秒

问题1:列表中所有项目的对话框似乎同时打开,这会导致它们堆叠在一起。

问题2:为正在单击的项目打开的对话框错误。我假设如果问题#1得到解决,这个问题就会得到解决。

问题#3:当我单击"添加到购物车"按钮时,它会进行装载并打开该项目的对话框。

问题1:如何使其只打开一个对话框并且是正确的对话框?

问题#2:如何使对话框在我单击"添加到购物车"时不会打开?

我在没有激活器的情况下打开对话框;类似于Vutify文档中的第一个示例。我也尝试过使用Actiator进行对话,但仍然存在相同的问题。

CODEPEN:https://codepen.io/chataolauj/pen/RwwYxBg?editors=1010

以下是HTML:

<v-app id="app">
  <v-container>
    <v-row>
      <v-col cols="4" height="100%" v-for="(food, index) in foods" :item="food" :key="index">
        <v-card class="mx-auto" :loading="loading && current_index === index" @click.stop="dialog = true">
          <v-img height="200px" :src="food.imgURL"></v-img>
          <v-card-title class="mb-2 pb-0">{{food.name}}</v-card-title>
          <v-card-subtitle>{{food.type}}</v-card-subtitle>
          <v-card-actions>
            <v-btn color="green" text @click="addToCart(index)">Add to Cart</v-btn>
          </v-card-actions>
        </v-card>
        <v-dialog v-model="dialog" max-width="50%">
          <v-card>
            <v-row no-gutters class="pa-4">
              <v-col cols="6" max-width="25%">
                <v-img :src="food.imgURL" class="pa-0" height=175></v-img>
              </v-col>
              <v-col cols="6" max-width="25%" class="pl-2 d-flex flex-column">
                <v-card-title class="pa-0">{{food.name}}</v-card-title>
                <v-subtitle>{{food.type}}</v-subtitle>
                <v-text>{{food.description}}</v-text>
              </v-col>
            </v-row>
          </v-card>
        </v-dialog>
      </v-col>
    </v-row>
  <v-container>
</v-app>

这里是JavaScript:

new Vue({
  el: "#app",
  vuetify: new Vuetify(),
  data() {
    return {
      loading: false,
      current_index: null,
      dialog: false,
      foods: [
        {
          type: 'Fruit', 
          name: 'Apple',
          imgURL: 'https://placebeard.it/400x400',
          description: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.'
        },
        {
          type: 'Fast Food', 
          name: 'Pizza',
          imgURL: 'https://placebeard.it/400x400',
          description: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Sit amet luctus venenatis lectus magna fringilla. Sem viverra aliquet eget sit amet tellus. Porta lorem mollis aliquam ut porttitor leo. Augue eget arcu dictum varius duis at consectetur.'
        },
        {
          type: 'Meat',
          name: 'Steak',
          imgURL: 'https://placebeard.it/400x400',
          description: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Sed egestas egestas fringilla phasellus faucibus scelerisque. Diam maecenas sed enim ut sem viverra aliquet eget. Sagittis nisl rhoncus mattis rhoncus urna neque viverra. Quam id leo in vitae turpis massa.'
        }
      ]
    }
  },
  methods: {
    addToCart(index) {
      this.loading = true;
      this.current_index = index;

      setTimeout(() => (this.loading = false), 2000);
    }
  }
});

解决方案

因此,我解决问题#1的方法是创建一个对象,然后根据数组中的项数用属性填充该对象。

data() {
    return {
      loading: false,
      current_index: null,
      previousItem: null,
      dialog: {}, //object to be populated with properties
      foods: [ /* some objects*/ ]
    }
}

我在Created()生命周期挂接中向对象添加了属性。

created() {
  for(let i = 0; i < this.foods.length; i++) {
    this.dialog['dialog_' + i] = false;
  }
}

这些添加到对话框对象的不同属性将根据卡片的索引作为卡片的v模型。例如,第一张卡的v-model将是Dialog_0。这样,只会打开所单击的卡的对话框,而不会打开每张卡的对话框。

<v-col v-for="(food, index) in foods" :item="food" :key="index">
   <v-dialog v-model="dialog['dialog_' + index]"> //v-model
      <template v-slot:activator="{ on: {click} }"> //clicking the card is the activator for the dialog
         <v-card> /*stuff goes here */ </v-card>
      </template>
   </v-dialog>
</v-col>

至于我是如何解决问题#3的,我只是按照DjSh的答案将.stop添加到@click,所以就是@click.stop="addToCart(index)"

相关文章