如何在点击时显示项目的属性(由循环生成)?
How to show an attribute of an item (generated by a loop) on-click?
在我的 vue3 应用程序中,我有三个板:
- 一个用于可拖动元素(已在 JSON 文件中定义)
- 一个用于可放置元素(存储在vue中的一个空列表中)
- 一个用于显示放置元素的属性,当您单击它时
我正在使用 Vuedraggable 进行拖放,这是它的外观:IMG
我的问题是在第三个面板上:我想点击“下拉面板”中的一个项目,并在知道一个项目有多个属性的情况下将其属性显示到“属性面板”中。
我已经试了好几天了,还是找不到解决办法,有人能帮帮我吗?
我是 Vue 和 Whosebug 的新手,我尽量说得清楚,如果我有错误,请原谅。
Home.vue - 首先,我在这里声明我的板子:
<template>
<div>
<Board v-for="(board, index) in boards" :key="index" :id="index" :board="board"/>
</div>
</div>
</template>
<script>
import Board from "@/components/Board.vue";
export default {
components: {
Board,
},
data: () => ({
boards: [
{
title: "Toolbox Board",
},
{
title: "Mockup Board",
},
{ title: "Properties" },
],
}),
};
Board.vue - “拖板”代码:
<div class="dd-container" v-if="board.title == 'Toolbox Board'">
<draggable v-model="dragItems" item-key="id":group="{ name: 'items', pull: 'clone', put: false }" :clone="cloneItems" @change="log">
<template #item="{ element }">
<div class="item">
{{ element.title }}
</div>
</template>
</draggable>
</div>
Board.vue - “拖板”代码:
<div class="dd-container" v-if="board.title == 'Mockup Board'">
<draggable
v-model="dropItems" item-key="id" group="items" @change="log">
<template #item="{ element }">
<div class="item">
{{ element.title }}
</div>
</template>
</draggable>
</div>
Board.vue - “属性板”:
<div class="dd-container" v-if="board.title == 'Properties'">
{{ property }} ??
</div>
Board.vue - 一些脚本:
import dragItemsList from "/dragItems.json";
import draggable from "vuedraggable";
export default {
components: {
draggable,
},
data() {
return {
dragItems: dragItemsList,
dropItems: [],
DragItems.json - 最重要的是 JSON 文件:
[
{"title": "Simple list","id": 1,"properties": ["this is a property"],"fixed": true},
{"title": "Search list","id": 2,"properties": ["this is a property"],"fixed": true},
{"title": "Simple options","id": 3,"properties": ["this is a property"],"fixed": true},
{"title": "Multiple options","id": 4,"properties": ["this is a property"],"fixed": true },
{"title": "Location","id": 5,"properties": ["this is a property"],"fixed": true},
{"title": "Picture","id": 6,"properties": ["this is a property"],"fixed": true},
{"title": "Signature","id": 7,"properties": ["this is a property"],"fixed": true},
{"title": "Audio","id": 8,"properties": ["this is a property"],"fixed": true},
{"title": "Todo list","id": 9,"properties": ["this is a property"],"fixed": true},
{"title": "Grouped items","id": 10, "properties": ["this is a property"],"fixed": true},
{"title": "Divider","id": 11, "properties": ["this is a property"],"fixed": true},
{"title": "Grouping container","id": 12, "properties": ["this is a property"],"fixed": true},
{"title": "NFC reader","id": 13, "properties": ["this is a property"],"fixed": true},
{"title": "QR code scanner","id": 14, "properties": ["this is a property"],"fixed": true},
{"title": "Barcode scanner","id": 15, "properties": ["this is a property"],"fixed": true},
{"title": "Fingerprint read (Idemia)","id": 16, "properties": [],"fixed": false}
]
我认为你把自己逼到了一个角落,因为你试图在不需要的地方使用 v-for,列表看起来一样,但你可以将它们作为单独的组件使用相同 类.
第二个问题是您用 3 种不同的实现重载了 Board.vue 组件。
如果三个板的行为各不相同,则将这些部分拆分为各自的组件。
所以你最终会得到 3 个板组件,每个组件显示不同类型的板。
If you insist on avoiding writing things twice you can create a component to display a board and have the contents thereof be a slot.
按照你的路线,强制模板在两种不同类型的列上使用 v-for 效果不佳,因为你不应该将可拖动列表和属性窗格放在同一个 v-for循环。
因为拖放板都使用 draggable,所以您可以制作一个 Board 组件,它会显示一个可拖动的项目列表,然后在项目被拖放到上面时发出一个事件(例如 drop
)董事会。
因为您为这些看板分享的片段的不同之处在于可拖动的配置,您可以为这些看板的 enabling/disabling 和 drag-and-drop 功能创建道具(例如 allow-drag
, allow-drop
).
<!-- Home.vue -->
<template>
<div>
<Board :items="dragItems" @select="select" allow-drag/>
<Board :items="dropItems" @drop="transfer" @select="item => select(item)" allow-drop />
<PropertiesBoard :selected="selectedItem" />
</div>
</template>
<script>
export default {
data: () => ({
dragItems: [],
dropItems: [],
selectedItem: null,
}),
methods: {
select(item) {
console.log('Dropped', item);
this.selectedItem = item;
},
},
};
</script>
<!-- Board.vue -->
<template>
<button @click="testme">Trigger</button>
</template>
<script>
export default {
methods: {
testme() {
const item = {
id: 1,
name: 'This is my item',
};
this.$emit('drop', item);
},
},
};
</script>
In this snippet the @select
event is emitted by the boards when an item is selected, so the Home component can then set it as the focussed item and bind it to the PropertiesBoard to display its properties.
Edit: I've updated this snippet to show how to emit events from Board.vue
在我的 vue3 应用程序中,我有三个板:
- 一个用于可拖动元素(已在 JSON 文件中定义)
- 一个用于可放置元素(存储在vue中的一个空列表中)
- 一个用于显示放置元素的属性,当您单击它时
我正在使用 Vuedraggable 进行拖放,这是它的外观:IMG
我的问题是在第三个面板上:我想点击“下拉面板”中的一个项目,并在知道一个项目有多个属性的情况下将其属性显示到“属性面板”中。 我已经试了好几天了,还是找不到解决办法,有人能帮帮我吗?
我是 Vue 和 Whosebug 的新手,我尽量说得清楚,如果我有错误,请原谅。
Home.vue - 首先,我在这里声明我的板子:
<template>
<div>
<Board v-for="(board, index) in boards" :key="index" :id="index" :board="board"/>
</div>
</div>
</template>
<script>
import Board from "@/components/Board.vue";
export default {
components: {
Board,
},
data: () => ({
boards: [
{
title: "Toolbox Board",
},
{
title: "Mockup Board",
},
{ title: "Properties" },
],
}),
};
Board.vue - “拖板”代码:
<div class="dd-container" v-if="board.title == 'Toolbox Board'">
<draggable v-model="dragItems" item-key="id":group="{ name: 'items', pull: 'clone', put: false }" :clone="cloneItems" @change="log">
<template #item="{ element }">
<div class="item">
{{ element.title }}
</div>
</template>
</draggable>
</div>
Board.vue - “拖板”代码:
<div class="dd-container" v-if="board.title == 'Mockup Board'">
<draggable
v-model="dropItems" item-key="id" group="items" @change="log">
<template #item="{ element }">
<div class="item">
{{ element.title }}
</div>
</template>
</draggable>
</div>
Board.vue - “属性板”:
<div class="dd-container" v-if="board.title == 'Properties'">
{{ property }} ??
</div>
Board.vue - 一些脚本:
import dragItemsList from "/dragItems.json";
import draggable from "vuedraggable";
export default {
components: {
draggable,
},
data() {
return {
dragItems: dragItemsList,
dropItems: [],
DragItems.json - 最重要的是 JSON 文件:
[
{"title": "Simple list","id": 1,"properties": ["this is a property"],"fixed": true},
{"title": "Search list","id": 2,"properties": ["this is a property"],"fixed": true},
{"title": "Simple options","id": 3,"properties": ["this is a property"],"fixed": true},
{"title": "Multiple options","id": 4,"properties": ["this is a property"],"fixed": true },
{"title": "Location","id": 5,"properties": ["this is a property"],"fixed": true},
{"title": "Picture","id": 6,"properties": ["this is a property"],"fixed": true},
{"title": "Signature","id": 7,"properties": ["this is a property"],"fixed": true},
{"title": "Audio","id": 8,"properties": ["this is a property"],"fixed": true},
{"title": "Todo list","id": 9,"properties": ["this is a property"],"fixed": true},
{"title": "Grouped items","id": 10, "properties": ["this is a property"],"fixed": true},
{"title": "Divider","id": 11, "properties": ["this is a property"],"fixed": true},
{"title": "Grouping container","id": 12, "properties": ["this is a property"],"fixed": true},
{"title": "NFC reader","id": 13, "properties": ["this is a property"],"fixed": true},
{"title": "QR code scanner","id": 14, "properties": ["this is a property"],"fixed": true},
{"title": "Barcode scanner","id": 15, "properties": ["this is a property"],"fixed": true},
{"title": "Fingerprint read (Idemia)","id": 16, "properties": [],"fixed": false}
]
我认为你把自己逼到了一个角落,因为你试图在不需要的地方使用 v-for,列表看起来一样,但你可以将它们作为单独的组件使用相同 类.
第二个问题是您用 3 种不同的实现重载了 Board.vue 组件。 如果三个板的行为各不相同,则将这些部分拆分为各自的组件。
所以你最终会得到 3 个板组件,每个组件显示不同类型的板。
If you insist on avoiding writing things twice you can create a component to display a board and have the contents thereof be a slot.
按照你的路线,强制模板在两种不同类型的列上使用 v-for 效果不佳,因为你不应该将可拖动列表和属性窗格放在同一个 v-for循环。
因为拖放板都使用 draggable,所以您可以制作一个 Board 组件,它会显示一个可拖动的项目列表,然后在项目被拖放到上面时发出一个事件(例如 drop
)董事会。
因为您为这些看板分享的片段的不同之处在于可拖动的配置,您可以为这些看板的 enabling/disabling 和 drag-and-drop 功能创建道具(例如 allow-drag
, allow-drop
).
<!-- Home.vue -->
<template>
<div>
<Board :items="dragItems" @select="select" allow-drag/>
<Board :items="dropItems" @drop="transfer" @select="item => select(item)" allow-drop />
<PropertiesBoard :selected="selectedItem" />
</div>
</template>
<script>
export default {
data: () => ({
dragItems: [],
dropItems: [],
selectedItem: null,
}),
methods: {
select(item) {
console.log('Dropped', item);
this.selectedItem = item;
},
},
};
</script>
<!-- Board.vue -->
<template>
<button @click="testme">Trigger</button>
</template>
<script>
export default {
methods: {
testme() {
const item = {
id: 1,
name: 'This is my item',
};
this.$emit('drop', item);
},
},
};
</script>
In this snippet the @select
event is emitted by the boards when an item is selected, so the Home component can then set it as the focussed item and bind it to the PropertiesBoard to display its properties.
Edit: I've updated this snippet to show how to emit events from Board.vue