从数组中删除项目:删除了错误的项目

Removing an item from array: Wrong item being removed

我有一个包含媒体附件列表的 post 页面。我希望用户在单击 "delete" link 时能够手动删除附件。此事件有效,但是,问题是被删除的实际项目不是被点击的项目!我做错了什么?

这是我的代码和现场演示:[codesandbox](单击帖子-->选择一个 post ID 以查看 post 详细信息 -- > 点击编辑 post)

EditPost.vue <template> section:

...snip..
    <ul>
      <li>Media Attachments
        <template>
          <ul v-if="attachmentsFileNames && attachmentsFileNames.length">
            <li v-for="(mediaAttachment, index) in attachmentsFileNames" :key="index">
              <a href="#">{{ mediaAttachment }}</a>&nbsp;
              <button @click.prevent="deleteMediaAttachment(mediaAttachment, index)">Delete me!</button>
            </li>
          </ul>
          <p v-else>No Media Attachments</p>
        </template>
      </li>
    </ul>

EditPost.vue <script>:

...snip..
data() {
    return {
      post: {},
      editPostFormIsVis: false,
      attachmentsArray: attachments
    };
  },
  created() {
    this.getPost();
  },
  methods: {
    getPost() {
      axios
        .get(
          "https://jsonplaceholder.typicode.com/posts/" + this.$route.params.id
        )
        .then(resp => {
          this.post = resp.data;
        })
        .catch(err => {
          console.log(err);
        });
    },
    editPost() {
      this.editPostFormIsVis = true;
    },
deleteMediaAttachment: function(item, index) {
      if (this.attachmentsArray.attachments[index] === item) {
        // The template passes index as the second parameter to avoid indexOf,
        // it will be better for the performance especially for one large array
        // (because indexOf actually loop the array to do the match)
        this.attachmentsArray.attachments.splice(index, 1);
      } else {
        let found = this.attachmentsArray.attachments.indexOf(item);
        this.attachmentsArray.attachments.splice(found, 1);
      }
    }
  },
  computed: {
    emailAttachmentsFileNames() {
      if (this.attachmentsArray.emailAttachments) {
        const emailAttachmentsFileNameArray = this.attachmentsArray.emailAttachments.map(
          item => {
            const tokens = item.split("/");
            return tokens[tokens.length - 1];
          }
        );
        return emailAttachmentsFileNameArray;
      } else {
        return null;
      }
    },
    attachmentsFileNames() {
      if (this.attachmentsArray.attachments) {
        const attachmentsFileNameArray = this.attachmentsArray.attachments.map(
          item => {
            const tokens = item.split("/");
            return tokens[tokens.length - 1];
          }
        );
        return attachmentsFileNameArray;
      } else {
        return null;
      }
    }
  }
...snip...

将您的 deleteMediaAttachment 函数更改为

deleteMediaAttachment: function(item, index) {
  this.attachmentsArray.attachments.splice(index, 1);
},

您的问题是您从 attachmentsFileNames 发送项目并尝试将其与原始 attachments 数组中的项目匹配。第一个包含文件名,而第二个包含完整路径,因此它们不会匹配。例如:

console.log(item);                                     // star_wars_luke.jpeg
console.log(this.attachmentsArray.attachments[index]); // attachments/2019/201900002020/star_wars_luke.jpeg

这就是为什么 this.attachmentsArray.attachments[index] === itemfalse,然后是 this.attachmentsArray.attachments.indexOf(item) returns -1,因此,this.attachmentsArray.attachments.splice(-1, 1) 总是删除列表中的最后一项数组。

由于您自己从 this.attachmentsArray.attachments 解析了 attachmentsFileNames 数组,您可以依赖正确对应的 index,因此甚至不需要这些检查。只需删除它们和 运行 this.attachmentsArray.attachments.splice(index, 1) 就可以了。