将v-model添加到v-dialog中会破坏数组中的元素



我有一个array apps,每个app都有一个link。我还有一个组分,Dialog。添加v-model="dialog"后,可以从ChildComponent中关闭对话框Dialog我的应用程序不工作了。正如你所看到的,我将当前应用程序添加为对话框的道具,但在v-dialog上添加v-model后,它总是发送apps array中的最后一个应用程序。我不知道我哪里做错了。

Parent component

<v-col  v-for="app in apps" :key="app._id" :cols="setBreakpointCols">
<v-card class="pa-2 " outlined height="230px">
<v-dialog v-model="dialog">
<template v-slot:activator="{ on: dialog, attrs }">
<v-tooltip right color="#363636" max-width="250px">
<template v-slot:activator="{ on: tooltip }">
<v-img :src="getImgUrl(app.src)" class="white--text align-end"
gradient="to bottom, rgba(0,0,0,.5), rgba(0,0,0,.5)" height="85%" v-bind="attrs"
v-on="{ ...tooltip, ...dialog }">
<v-card-title v-text="app.title"></v-card-title>
</v-img>
</template>
<span v-if="app.vpnRequired">VPN needed to run!</span>
<v-divider class="my-1" v-if="app.vpnRequired" dark ></v-divider>
<span>{{ app.description }}</span>
</v-tooltip>
<!-- shows the link of the clicked app (for example the second of 5) in the array-->
<h1>{{app.link}}</h1>
</template>
<!-- shows the link of the last ( 5 of 5) app in the array. Why is this link different then the app.link from 2 lines up?-->
<h1>{{app.link}}</h1>
<Dialog @closeDialog="closeDialog" :app="app" />
</v-dialog>
<v-card-actions mb-2>
<v-spacer></v-spacer>
<v-tooltip top color="#363636">
<template v-slot:activator="{ on, attrs }" v-if="app.quickActions">
<v-btn @click="DeleteAppFromQuickActions(app)" icon>
<v-icon v-bind="attrs" v-on="on" >
mdi-minus-box-outline
</v-icon>
</v-btn>
</template>
<template v-slot:activator="{ on, attrs }" v-else>
<v-btn @click="AddAppToQuickActions(app)" icon>
<v-icon v-bind="attrs" v-on="on">
mdi-plus-box-outline
</v-icon>
</v-btn>
</template>
<span v-if="app.quickActions">Delete from QuickActions</span>
<span v-else>Add to QuickActions</span>
</v-tooltip>
<v-spacer></v-spacer>
</v-card-actions>
</v-card>
</v-col>

child component

<template>
<v-container fluid>
<v-row>
<v-col fixed style="background:#363636;" class="d-flex justify-end" cols="12">
<v-btn plain color="grey" :href="app.link" target="_blank">
<v-icon>mdi-open-in-new</v-icon>
</v-btn>
<v-btn @click="closeDialog" plain color="grey">
<v-icon>mdi-close-box-outline</v-icon>
</v-btn>
</v-col>
<v-col cols="12">
<iframe :src="app.link" width="100%" height="800px"
frameborder="0">
</iframe>
</v-col>
</v-row>
</v-container>
</template>
<script>
export default {
name: "Dialog",
props: ['app'],
data() {
return {
}
},
methods: {
closeDialog: function (){
this.$emit('closeDialog')
}
}

}
</script>

我们不需要为for循环中的每个项创建一个模态组件。

因为当我们在for循环中创建模态时,所有模态的组件都是单独创建的,但是它们都绑定到同一个v-model,所以最后一个v-model将始终是活动的,并且只传递最后一个项目的数据。

这个问题也可以通过传递数组索引或使用对象创建单独的v-model来解决,但是好的做法是将模态组件保持在for循环之外,并通过将每个选定项的数据作为prop传递来使用它。

这意味着你可以这样做-(我使用虚拟数据来创建UI)

父组件——

<template>
<div>
<!-- To open dialog on click on any item -->
<Dialog
v-if="dialog && selectedApp"
v-model="dialog"
:app="selectedApp"
@closeDialog="closeDialog"
/>
<!-- Loop on items -->
<v-col v-for="app in apps" :key="app._id" cols="12">
<v-card class="pa-2 " outlined height="230px">
<v-dialog v-model="dialog">
<template v-slot:activator="{ on: dialog, attrs }">
<v-tooltip right color="#363636" max-width="250px">
<template v-slot:activator="{ on: tooltip }">
<v-img
:src="app.src"
class="white--text align-end"
gradient="to bottom, rgba(0,0,0,.5), rgba(0,0,0,.5)"
height="85%"
v-bind="attrs"
v-on="{ ...tooltip, ...dialog }"
@click="selectedApp = app"
>
<v-card-title v-text="app.title"></v-card-title>
</v-img>
</template>
<span v-if="app.vpnRequired">VPN needed to run!</span>
<v-divider class="my-1" v-if="app.vpnRequired" dark></v-divider>
<span>{{ app.description }}</span>
</v-tooltip>
<!-- shows the link of the clicked app (for example the second of 5) in the array-->
<h1>{{ app.link }}</h1>
</template>
<!-- shows the link of the last ( 5 of 5) app in the array. Why is this link different then the app.link from 2 lines up?-->
<h1>{{ app.link }}</h1>
</v-dialog>
<v-card-actions mb-2>
<v-spacer></v-spacer>
<v-tooltip top color="#363636">
<template v-slot:activator="{ on, attrs }" v-if="app.quickActions">
<v-btn @click="DeleteAppFromQuickActions(app)" icon>
<v-icon v-bind="attrs" v-on="on">
mdi-minus-box-outline
</v-icon>
</v-btn>
</template>
<template v-slot:activator="{ on, attrs }" v-else>
<v-btn @click="AddAppToQuickActions(app)" icon>
<v-icon v-bind="attrs" v-on="on">
mdi-plus-box-outline
</v-icon>
</v-btn>
</template>
<span v-if="app.quickActions">Delete from QuickActions</span>
<span v-else>Add to QuickActions</span>
</v-tooltip>
<v-spacer></v-spacer>
</v-card-actions>
</v-card>
</v-col>
</div>
</template>
<script>
import Dialog from "/var/www/html/weresearchfrontend/src/Dialog.vue";
export default {
name: "ParentComponent",
data() {
return {
dialog: false,
selectedApp: null,
apps: [
{
title: "A",
vpnRequired: true,
src: "https://source.unsplash.com/user/c_v_r/1900x800",
description: "Hello Google",
link: "https://google.com",
quickActions: true,
},
{
title: "B",
vpnRequired: true,
src: "https://source.unsplash.com/user/c_v_r/100x100",
description: "Hello Github",
link: "https://github.com",
quickActions: true,
},
],
};
},
components: {
Dialog,
},
methods: {
closeDialog: function() {
this.dialog = false;
// reset selected app also
this.selectedApp = app;
},
},
};
</script>

子组件(DIALOG COMPONENT)-

<template>
<v-dialog :value="value">
<v-card>
<v-container fluid>
<v-row>
<v-col fixed style="background:#363636;" class="d-flex" cols="12">
<span class="white--text font-weight-bold"
>{{ app.title }} > {{ app.description }} > {{ app.link }}</span
>
<v-spacer></v-spacer>
<v-btn plain color="grey" :href="app.link" target="_blank">
<v-icon>mdi-open-in-new</v-icon>
</v-btn>
<v-btn @click="$emit('closeDialog')" plain color="grey">
<v-icon>mdi-close-box-outline</v-icon>
</v-btn>
</v-col>
<v-col cols="12">
<iframe :src="app.link" width="100%" height="800px" frameborder="0">
</iframe>
</v-col>
</v-row>
</v-container>
</v-card>
</v-dialog>
</template>
<script>
export default {
name: "Dialog",
props: ["value", "app"],
};
</script>

最新更新