如何通过父级按钮在 v-for 中渲染组件
Posted
技术标签:
【中文标题】如何通过父级按钮在 v-for 中渲染组件【英文标题】:How render component in v-for by button from parent 【发布时间】:2019-06-13 09:55:18 【问题描述】:如何通过按钮(父级按钮)在 v-for 循环内单击来呈现 v-if 组件?并且应该只在点击的那个项目中呈现
<div v-for="item in items">
<button @click >Show child<button>
<div>item.name</div>
<child v-if="this button clicked" :item="item"><child>
<div>
【问题讨论】:
同时显示您的items
内容
不管。它类似于输入方法来提交存储 item.newtext 和来自输入的信息(它工作正常)
@RemiFokz 我以前解决过类似的问题,请查看 this post 并告诉我它是否适合您。
【参考方案1】:
您必须在数据中存储有关每个项目(如果被点击)的状态信息。然后,当您单击按钮时,您应该更新特定项目的 clicked 属性。最后,如果 item.clicked 设置为 true,您将显示您的子组件(或任何其他 html)。
<template>
<div>
<div v-for="item in items" :key="item.id">
<button @click="item.clicked = true" >Show child</button>
item.name
<div v-if="item.clicked">Item child</div>
</div>
</div>
</template>
<script>
export default
name: 'HelloWorld',
data: function()
return
items: [
id: 1,
name: 'test1',
clicked: false
,
id: 2,
name: 'test2',
clicked: false
,
id: 3,
name: 'test3',
clicked: false
]
</script>
【讨论】:
我正在从商店获取项目(大对象数组),但不确定是否需要向它们添加更多属性【参考方案2】:简单明了,您只需为后者设置一些标志v-if
:
<div id="app">
<div v-for="item in items">
<button @click="$set(item, 'shown', true)">Show child</button>
<div> item.name </div>
<div v-if="item.shown">Child component</div>
</div>
</div>
这里使用$set()
,因为初始item
可能缺少shown
字段,因此直接使用item.shown=true
设置它不会产生反应。
您也可以在点击后隐藏按钮:
<button @click="$set(item, 'shown', true)" v-if="!item.shown">Show child</button>
要切换可见性,您只需这样做:
<button @click="$set(item, 'shown', !item.shown)">
item.shown ? 'Hide' : 'Show' child
</button>
JSFiddle
【讨论】:
@RemiFokz 用切换变体更新了我的答案【参考方案3】:您可以利用 v-for 指令(例如 v-for="(item, i) in items"
)中提供的项目...索引,将其(项目的索引)绑定到通过更改项目属性来显示项目的函数:
更新:在需求细化后,初始答案已被删除。
由于您希望避免项目的变化,您可以将它们包装在 Map
对象(作为键)中,并将可见性设置单独保存为 Map
值。不幸的是,据我所知,Vue.js 暂时不支持Map
对象的反应性,这就是为什么我必须使用forceUpdate
手动触发重新渲染:
Vue.config.devtools = false;
Vue.config.productionTip = false;
Vue.component('child',
template: '<p>Visible child</p>'
)
new Vue(
el: "#demo",
template: `
<div>
<div v-for="item in items">
<button @click="toggleChild(item)">Toggle child</button>
<div>item.name</div>
<child v-if="isVisible(item)" :item="item"></child>
</div>
</div>
`,
data ()
return
itemsMap: new Map(
[
name: 'test1' ,
name: 'test2'
].map(item => [item, visible: false ])
)
;
,
methods:
toggleChild(item)
this.itemsMap.set(item, visible: !this.itemsMap.get(item).visible );
this.$forceUpdate();
,
isVisible(item)
return this.itemsMap.get(item).visible;
,
computed:
items: function()
return Array.from(this.itemsMap.keys());
)
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="demo"></div>
【讨论】:
我正在从商店获取项目(大对象数组),但不确定是否需要向它们添加更多属性 @RemiFokz 嗨,我已经用一个不会改变原始项目的变体更新了答案,希望它可能会有所帮助。以上是关于如何通过父级按钮在 v-for 中渲染组件的主要内容,如果未能解决你的问题,请参考以下文章
Bootstrap-Vue 模态:如何在 V-For 渲染列表中打开不同的模态?