Vue反应阵列数据输出不同的值

时间:2019-05-01 16:01:47

标签: javascript vue.js ecmascript-6

我对vue反应性数据工作流程还很陌生,我正在尝试制作一个图像上传器,它的主要工作原理是。我试图在更新特定值之前从阵列中的图像中删除所有true主值。但是我需要检查图像数组中的“主要”值,以便我可以进行条件更改。

我将图像创建功能留在了底部,因此您可以看到它是如何制作的。如果用于编辑图片,则父组件通过ajax从服务器获取所有数据,这就是_images道具。

由于某种原因,当我将数组引用为images[key].primary时,得到的值与在控制台中输出整个数组的值不同。有什么想法在这里发生什么事吗?

目标

当前,在子组件上,我单击一个make主按钮并向该组件发出更新。然后在update方法中尝试检查请求是否是新的主图像请求,并在所有其他图像上将主图像设置为false。然后将请求的图像设置为主图像。因此,在切换时使用一个主图像,因此只有一个主图像。

目前,我正在测试两张图片,依次将每张图片设置为主要,然后观看另一张图片自动变为假,但是通过第三次单击,它们都是真实的,没有任何反应。有什么想法在这里发生什么事吗?

父组件(v-image-upload):

export default {

  components: {
    'v-image': image
  },
  props: ['_errors', '_images', '_isMultiple'],
  data() {
    return {
      images: _.cloneDeep(this._images),
    }
  },

  methods: {
    updateImage(request) {

      //ISSUE: current images = true,true | images = false,true
      console.log('current images', this.images[0].primary, this.images[1].primary, );
      console.log('images', this.images);

      if (request.form.primary && !this.images[request.key].primary) {

        //reset all primary images
        $.each(this.images, (index, value) => {
              let image = value;
              image.primary = false;

              this.$set(this.images, index, image);
            }
              //update images with new image
              this.$set(this.images, request.key, request.form);
          },
          onFileChange(e) {
            let files = e.target.files || e.dataTransfer.files;

            if (files.length) {
              $.each(files, (index, file) => {
                this.createImage(file);
              });
            }
            e.target.value = '';
          },
          createImage(file) {
            let reader = new FileReader();
            let fileNameSegments = file.name.split('.');
            let fileName = fileNameSegments[0];
            let fileExtension = fileNameSegments[1];
            let validExtnesions = ['jpg', 'png', 'gif'];
            let placeholderImage = window.location.protocol + '//' + window.location.host + '/' + 'img/site/default/placeholder-image.png';
            let primary = (this.images.length == 0) ? true : false;


            reader.onload = (e) => {
              let image = ($.inArray(fileExtension, validExtnesions) == -1) ? placeholderImage : e.target.result;
              let data = {
                name: fileName,
                extension: fileExtension,
                source: image,
                description: null,
                primary: primary,
                image_directory: null,
              };

              this.$set(this.images, this.images.length, data);
            }
            reader.readAsDataURL(file);

          },
      }
    }

子组件(v图像):

    export default {
    props: ['_imgKey', '_image', '_errors'],
    data() {
        return {
            form: {
                id: _.clone(this._image.id),
                name: _.clone(this._image.name),
                description: _.clone(this._image.description),
                primary: _.clone(this._image.primary),
                extension: _.clone(this._image.extension),
                image_directory: _.clone(this._image.image_directory),
                source: _.clone(this._image.source),
            },
        }
    },
    watch: {
        _image: {
            handler(value) {
                console.log('_image watch', this._imgKey, value.primary);
                this.form.id = _.clone(value.id);
                this.form.name = _.clone(value.name);
                this.form.primary = _.clone(value.primary);
                this.form.source = _.clone(value.source);
                this.form.image_directory = _.clone(value.image_directory);

            }, deep: true
        }
    },
    methods: {
        updatePrimary() {
            this.form.primary = true;
            this.updateImage();
        },
        updateImage() {
            this.$emit('updateImage', {key: this._imgKey, form: this.form});
        },
        removeImage() {
            this.$emit('removeImage', this._imgKey);

        }
    }
}

更新

我一直在看vue开发人员工具对图像阵列的任何更改。我将虚假图片上的主按钮按下,该虚假图片会发送给父对象并调用updateImage方法。第一次和第二次重置和更新起作用,并更改值。该问题已被跟踪至:第二个“更新后”(true,false)与第三个“重置前”(true,true)不匹配。

  • 我进行了注释中提到的以前的更改,并在两个组件数据中添加了一个克隆,以防止出现奇异的反应性行为。
  • 我检查了事件日志:3x UpdateImage $emit by <VImage>,这是预期的。

注意:我将先前的重置逻辑移到了resetPrimary()方法中。

     updateImage(request) {
           console.log('update', request.key, request.form.primary);
           console.log('b4 reset', this.images[0].primary, this.images[1].primary);
           this.resetPrimary(request);
           console.log('after reset', this.images[0].primary, this.images[1].primary);
           this.$set(this.images, request.key, request.form);
           console.log('after update', this.images[0].primary, this.images[1].primary);
    },

输出:

//First click - Image 1 (Expected)
update 1 true
b4 reset true false
after reset false false
after update false true

//Second click - Image 0 (Expected)
update 0 true
b4 reset false true
after reset false false
after update true false

//Third click - Image 1 (What?)
update 1 true
b4 reset true true //should be true false
after reset true true
after update true true

似乎第二次尝试更新同一图像时,它以某种方式忽略了先前已将其重置为false的事实。

0 个答案:

没有答案