【问题标题】:Remove listing from Vuejs1 vs Vuejs2从 Vuejs1 vs Vuejs2 中删除列表
【发布时间】:2018-03-31 18:29:45
【问题描述】:

目前我正在使用 Vuejs2 生成用于图像上传的列表,在选择图像文件后会显示预览图像,这是我用 Vuejs2 用 codepan 编写的代码: https://codepen.io/anon/pen/MELZKe

<div v-for="(image, index) in images" :key="index">
    <div class="image-upload">
        <label v-bind:for="'cover-upload-' + index">
            <img src="http://via.placeholder.com/100x100" width="100" class="preview-img"/>
        </label>
        <input v-bind:id="'cover-upload-' + index" v-bind:name="'slides[' + index + ']'" type="file" class="upload-preview" style="display:none">
    </div>
    <button type="button" 
            @click.prevent="removeImage(index)"
            v-show="image_quantity > 1">
      Remove
  </button>
</div>

我创建了 2 个文件上传图片,上传第一张图片(将预览您的图片),删除第一张预览图片,但它会删除最后一张预览图片而不是第一个。

但是,几乎相同的编码但使用 Vuejs1,它将删除第一个预览图像而不是最后一个。这是使用 Vuejs1 的 codepen: https://codepen.io/anon/pen/VMgqbG

我不知道如何为 Vuejs2 编写这种情况,或者我必须坚持使用 Vuejs1?

谢谢。

【问题讨论】:

  • 我看到的问题是图像源没有保存在任何变量中,它存储在您的 readURL 函数的 dom 对象中,您需要将该信息移动到您的数组中目前只是一堆与 dom 无关的 {name=""} 元素。
  • 另外,您可以在 >= 2.2 中使用Vue.delete(this.images, index),添加了一些漂亮的助手。
  • 问题是我无法将 v-model 绑定到 img 元素中,因为它不是输入的。
  • Vue.delete 与 splice(index, 1); 的结果完全相同;

标签: vue.js vuejs2


【解决方案1】:

使用数组的索引作为键是a bad idea。这是因为索引变异。使用正确的密钥即可解决您的问题。

想想原始代码中图像数组中有两个图像的情况。首先,第一张图片的索引为零,第二张图片的索引为一。当您删除第一个图像时,原来第二个图像的索引现在已更改为零,但 Vue 具有键零的现有 DOM 元素,这些元素显示索引为零的前一个对象的图像。由于 Vue 将这些 DOM 元素用作键 0,因此它会重复使用它们,并且看起来好像第一个图像没有被删除。

console.clear()
new Vue({
  el: '#content',
  data: {
    images: [{ name: '' , id: 1}],
  },
  computed: {
    image_quantity: function () {
      return this.images.length;
    },
  },
  methods: {
    removeImage: function (index) {
      this.images.splice(index, 1);
    },
    addImage: function (event) {
      event.preventDefault();
      this.images.push({
        name: '',
        id: Math.max(...this.images.map(i => i.id)) + 1
      });
    }
  }
});

function readURL(input, preview) {
  if (input.files && input.files[0] && input.files[0].type.match('image.*')) {
    var reader = new FileReader();
    reader.onload = function (e) {
      $(preview).attr('src', e.target.result);
    }
    reader.readAsDataURL(input.files[0]);
  }
}

$(document).on('change', '.upload-preview', function () {
  readURL(this, $(this).prev().find('.preview-img'));
});
<div id="content">
    <div v-for="(image, index) in images" :key="image.id">
        <div class="image-upload">
            <label v-bind:for="'cover-upload-' + index">
                <img src="https://via.placeholder.com/100x100" width="100" class="preview-img"/>
            </label>
            <input v-bind:id="'cover-upload-' + index" v-bind:name="'slides[' + index + ']'" type="file" class="upload-preview" style="display:none">
        </div>
        <button type="button" 
                @click.prevent="removeImage(index)"
                v-show="image_quantity > 1">
          Remove
      </button>
    </div>
    <button type="button" v-on:click="addImage">Create New</button>
</div>

<script src="https://cdn.jsdelivr.net/npm/vue"></script>
<script src="https://code.jquery.com/jquery-2.2.4.min.js"></script>

【讨论】:

  • 感谢我的救命稻草。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-03-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多