如何在删除列表项时刷新Vue组件? [英] How to refresh Vue components upon list item removal?

查看:140
本文介绍了如何在删除列表项时刷新Vue组件?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我知道如何从Vue实例中删除列表项。但是,当列表项传递给Vue组件时,如何在保持组件与列表数据同步的同时删除列表项?

I know how to remove a list item from a Vue instance. However, when list items are passed to Vue components, how to remove a list item while keeping the components in sync with the list data?

以下是用例。考虑使用Markdown编辑器的在线论坛。我们有一个Vue实例,其数据是从服务器获取的已保存注释的列表。这些评论应该用降价来写。

Here is the use case. Consider an online forum with a Markdown editor. We have a Vue instance whose data are a list of saved comments fetched from a server. These comments are supposed to be written in Markdowns.

为方便编辑和预览,我们还有一个组件列表。每个组件都包含一个可编辑的输入缓冲区和一个预览部分。 Vue实例中保存的注释的内容用于初始化输入缓冲区并在用户取消编辑时重置它。预览是输入缓冲区内容的转换。

To facilitate edits and previews, we also have a list of components. Each component contains an editable input buffer as well as a preview section. The content of the saved comment in the Vue instance is used to initialise the input buffer and to reset it when a user cancels an edit. The preview is a transformation of the content of the input buffer.

以下是测试实现:

<template id="comment">
    <div>
        Component:
        <textarea v-model="input_buffer" v-if="editing"></textarea>
        {{ preview }}
        <button type="button" v-on:click="edit" v-if="!editing">edit</button>
        <button type="button" v-on:click="remove" v-if="!editing">remove</button>
        <button type="button" v-on:click="cancel" v-if="editing">cancel</button>
    </div>
</template>

<div id="app">
    <ol>
        <li v-for="(comment, index) in comments">
            <div>Instance: {{comment}}</div>
            <comment
                v-bind:comment="comment"
                v-bind:index="index"
                v-on:remove="remove">
            </comment>
        </li>
    </ol>
</div>

<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.1.8/vue.js"></script>

<script>
let comments = ['111', '222', '333']

Vue.component('comment', {
  template: '#comment',
  props: ['comment', 'index'],
  data: function() {
    return {
      input_buffer: '',
      editing: false,
    }
  },
  mounted: function() { this.cancel() },
  computed: {
    preview: function() {
      // This is supposed to be a transformation of the input buffer,
      // but for now, let's simply output the input buffer
      return this.input_buffer
    },
  },
  methods: {
    edit:   function() { this.editing = true },
    remove: function() { this.$emit('remove', this.index) },
    cancel: function() { this.input_buffer = this.comment; this.editing = false },
    //save: function() {},  // submit to server; not implemented yet
  },
})

let app = new Vue({
  el: '#app',
  data: { comments: comments },
  methods: {
    remove: function(index) { this.comments.splice(index, 1); app.$forceUpdate() },
  },
})
</script>

问题在于,如果我们删除注释,则组件不会相应刷新。例如,我们在上面的实现中有3条评论。如果您删除评论2,项目3的预览仍将显示项目2的内容。仅当我们按编辑后跟取消时才会更新

The problem is that, if we remove a comment, the components are not refreshed accordingly. For example, we have 3 comments in the above implementation. if you remove comment 2, the preview of item 3 will still show the content of item 2. It is updated only if we press edit followed by cancel.

我试过 app。$ forceUpdate(),但那并没有没帮忙。

I've tried app.$forceUpdate(), but that didn't help.

推荐答案

你只需要添加 key 属性v-for循环如下:

You just need to add key attribute in the v-for loop like following:

<li v-for="(comment, index) in comments" :key="comment">

查看工作小提琴: https://fiddle.jshell.net/mimani/zLrLvqke/

Vue试图优化渲染,提供关键属性,它将它们视为完全不同的元素并重新呈现这些元素。

Vue tries to optimises rendering, by providing key attribute, it treats those as completely different elements and re-renders those properly.

参见 密钥文档以获取更多信息。

See the key documentation for more information.

这篇关于如何在删除列表项时刷新Vue组件?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆