简体   繁体   English

如何在点击时显示项目的属性(由循环生成)?

[英]How to show an attribute of an item (generated by a loop) on-click?

In my vue3 app I have three boards:在我的 vue3 应用程序中,我有三个板:

  • one for draggable elements (already defined in a JSON file)一个用于可拖动元素(已在 JSON 文件中定义)
  • one for droppable elements (stored in a empty list in the vue)一个用于可放置元素(存储在 vue 中的一个空列表中)
  • one to display the properties of a dropped element, when you click on it一个用于显示放置元素的属性,当您单击它时

I'm using Vuedraggable for the drag and drop and here's how it looks : IMG我正在使用 Vuedraggable 进行拖放,这是它的外观IMG

My problem is on the third board: I want to click on an item in the "drop board" and show its properties into the "properties board" knowing that an item have multiple properties.我的问题在第三个板上:我想单击“下拉板”中的一个项目并将其属性显示到“属性板”中,因为我知道一个项目有多个属性。 I've tried for days and still can't find the solution, can somebody help me please?我已经尝试了好几天了,仍然找不到解决方案,有人可以帮我吗?

I'm new to Vue and StackOverflow, I've tried to be as clear as possible, sorry if I made mistakes.我是 Vue 和 StackOverflow 的新手,我试图尽可能清楚,如果我犯了错误,我深表歉意。

Home.vue - first of all, where I declare my boards: 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 - The "drag board" code: 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 - The "drop board" code: 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 - The "properties board": Board.vue - “属性板”:

<div class="dd-container" v-if="board.title == 'Properties'">
    {{ property }} ??
</div>

Board.vue - Some of the script: Board.vue - 一些脚本:

import dragItemsList from "/dragItems.json";
import draggable from "vuedraggable";

export default {
  components: {
    draggable,
  },

  data() {
    return {
      dragItems: dragItemsList,
      dropItems: [],

DragItems.json - Most importantly the JSON file: 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}
]

I think you have put yourself into a corner because you are trying to use v-for where it is not needed, the lists look the same but you can just have them as separate components that happen to use the same classes.我认为你把自己逼到了一个角落,因为你试图在不需要它的地方使用 v-for ,列表看起来是一样的,但你可以将它们作为单独的组件,恰好使用相同的类。

Second problem is that you are overloading the Board.vue component with 3 different implementations.第二个问题是您正在使用 3 种不同的实现重载 Board.vue 组件。 If there are three boards that each behave differently from the others, then split those parts into their own components.如果三块板的行为各不相同,则将这些部分拆分为各自的组件。

So you would end up with 3 board components, each displaying a different kind of board.所以你最终会得到 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.如果你坚持避免写两次,你可以创建一个组件来显示一个板并将其内容作为一个插槽。

Going your route, of forcing the templating to use a v-for over two different types of columns is not working out well, because you shouldn't put draggable lists and a properties pane in the same v-for loop.走你的路,强制模板对两种不同类型的列使用 v-for 效果不佳,因为你不应该将可拖动列表和属性窗格放在同一个 v-for 循环中。

Because the drag and drop boards both are using draggable, you could make a single Board component that would present a draggable list of items and then emit an event (eg drop ) when an item is dropped onto the board.因为拖放板都使用 draggable,所以您可以创建一个 Board 组件,它会显示一个可拖动的项目列表,然后在将项目放到板上时发出一个事件(例如drop )。

Because the difference in the snippets you shared for those boards was in the configuration of draggable, you can create props for enabling/disabling the drag-and-drop features for those boards (eg allow-drag , allow-drop ).因为您为这些板分享的片段的不同之处在于可拖动的配置,您可以创建道具来启用/禁用这些板的拖放功能(例如allow-dragallow-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. 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编辑:我已经更新了这个片段来展示如何从 Board.vue 发出事件

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM