Vue js 3 - 当多个值相似时,我的 Json 或对象树查看器有一个重复的键错误

Vue js 3 - My Json or Object tree viewer have a duplicate key bug when multiple values are similar

提问人:Gino 提问时间:11/1/2023 更新时间:11/1/2023 访问量:34

问:

我对此代码有疑问:我正在尝试从一个对象制作一个树查看器,它工作得很好,直到一个值与另一个值完全相同时,它克隆了 de 键,并替换了值相同的键。

在 CodePen 上:https://codepen.io/onigetoc/pen/rNPeQag?editors=1010

这个对象:

[
    {
        "userId": 1,
        "id": 1,
        "title": "delectus aut autem",
        "description": "delectus aut autem"
    },
    {
        "userId": 1,
        "id": 2,
        "title": "quis ut nam facilis et officia qui",
        "description": "et porro tempora"
    },
]

在我的树视图中给我:

[-]
userId:1
userId:1
title:delectus aut autem
title:delectus aut autem
[-]
userId:1
id:2
title:quis ut nam facilis et officia qui
description:et porro tempora

我们可以看到键 userIdtitle 是重复的,因为它们具有相同的值。 第二部分没问题,因为没有相同的值。

HTML 部分:

<!-- item template -->
<script type="text/x-template" id="item-template">
  <li>
    <span :class="{bold: isFolder}" @click="toggle">
      <span class="key" v-if="!isFolder" @click="toggleKey">{{ key }}:</span>
      <span class="value" v-if="!isFolder">{{ value }}</span>
      <span v-if="isFolder">[{{ isOpen ? '-' : '+' }}]</span>
    </span>
    <ul v-show="isOpen" v-if="isFolder">
      <tree-item
        class="item"
        v-for="(child, index) in item"
        :key="index"
        :item="child"
      ></tree-item>
    </ul>
  </li>
</script>

<p>(You can double click on an item to turn it into a folder.)</p>

<!-- the demo root element -->
<ul class="view-list" id="connect-list">
  <tree-item class="item" :item="treeData" @make-folder="makeFolder" @add-item="addItem"></tree-item>
</ul>

Javascript 部分:

<!-- demo data -->
// https://jsonplaceholder.typicode.com/users
var treeData = [
    {
        "userId": 1,
        "id": 1,
        "title": "delectus aut autem",
        "description": "delectus aut autem"
    },
    {
        "userId": 1,
        "id": 2,
        "title": "quis ut nam facilis et officia qui",
        "description": "et porro tempora"
    },
];

const app = Vue.createApp({
  data: function() {
    return {
      treeData: treeData
    }
  },

methods: {
  makeFolder: function(item) {
    Vue.set(item, 'newFolder', {});
    this.addItem(item.newFolder);
  },
  addItem: function(item) {
    Vue.set(item, 'newItem', 'new stuff');
  }
}
})

app.component("tree-item", {
  template: '#item-template',
  props: {
    item: Object
  },
  data: function() {
    return {
      isOpen: true // default was false
    };
  },
  computed: {
    isFolder: function() {
      return typeof this.item === 'object' && this.item !== null;
    },
    key: function() {
      if (typeof this.item === 'object' && this.item !== null) {
        return '';
      } else {
        return Object.keys(this.$parent.item).find(key => this.$parent.item[key] === this.item);
      }
    },
    value: function() {
      if (typeof this.item === 'object' && this.item !== null) {
        return '';
      } else {
        return this.item;
      }
    }
  },
  methods: {
    toggle: function() {
      if (this.isFolder) {
        this.isOpen = !this.isOpen;
      }
    },
    toggleKey: function(event) {
      event.target.classList.toggle("bgcolor");
    }
  }
})

  app.mount('#connect-list')
javascript vue.js vuejs3 树视图

评论


答:

1赞 Jaromanda X 11/1/2023 #1

问题是会找到第一个具有匹配项的键Object.keys(this.$parent.item).find(key => this.$parent.item[key] === this.item);value

实际上,您需要将“索引”作为道具传递(因为对象中的索引是一个字符串,并且是itemtree-item)

我用它作为道具,但我不太喜欢:p想不出这个道具更好的名字——但是,这真的不是什么值得担心的事情name

  <tree-item
    class="item"
    v-for="(child, index) in item"
    :key="index"
    :name="index"
    :item="child"
  ></tree-item>

注意:保留 因为这对:key="index"v-for

并在计算的this.namekey:

key: function() {
      if (typeof this.item === 'object' && this.item !== null) {
        return '';
      } else {
        return this.name;
      }
    },

评论

0赞 Gino 11/2/2023
你测试过吗?因为它不起作用。如果你使一个版本工作,如果你愿意,你可以暂时保存你的版本,如果你愿意,这里的代码可以帮助其他需要它的人?
0赞 Jaromanda X 11/2/2023
@Gino是的,我确实测试过它。我总是在发布代码之前对其进行测试......您是否将 prop 添加到您的树项组件中?- 即添加它nameprops: { item: Object, name: String },
0赞 Jaromanda X 11/2/2023
检查你的 CodePen ...你所做的只是添加 - 你读过整个答案吗?:name="index"
0赞 Jaromanda X 11/5/2023
@Gino - 该链接中的代码似乎可以按要求工作?
0赞 Gino 11/7/2023
我修好了它,我发现是因为我错过了一些关于道具的东西,现在没问题了