【问题标题】:VueJS: background img gets uploaded in all sibling components instead of the component through which image was uploadedVue JS:背景图像被上传到所有兄弟组件中,而不是上传图像的组件
【发布时间】:2019-11-14 11:35:35
【问题描述】:

在这个codeSandBox demo中,子cmp包含图片文件输入,

文件被上传到并使用reader.readAsDataURL(file)作为输入的父包装div的背景图像读取。

问题是上传的文件在所有同级中重复。

我想上传的文件只影响上传孩子的组件。

Parent.vue

<template>
  <div id="app">
    <div v-for="n in 5">
      <div class="wrapper" :style="bgImg">
        <child @imageSelected="updateBgImg($event)"/>
      </div>
    </div>
  </div>
</template>

<script>
  import child from "./components/child";

  export default {
    name: "App",
    data() {
      return {
        bgImgURL: "Image URL",
        bgImg: {}
      };
    },
    methods: {
      updateBg(url) {
        this.bgImgURL = url;
        this.bgImg = {
          "background-image": "url(" + this.bgImgURL + ")"
        }
      }
    },
    components: {
      child
    }
  }
</script>

child.vue

<template>
  <div>
    <input type="file" @change="getImage">
  </div>
</template>

<script>
export default {
  name: "HelloWorld",
  props: {
    msg: String
  },
  methods: {
    getImage(e) {
      var file = e.target.files[0];
      this.createImage(file);
    },
    createImage(file) {
      var reader = new FileReader();
      reader.readAsDataURL(file);

      var vm = this;
      reader.onload = function() {
        vm.$emit("imageSelected", this.result);
      };
    }
  }
};
</script>

谢谢

【问题讨论】:

  • 因为所有五个 `
    ` 元素都在父元素中而不是在子元素中,所以bgImg 当然是相同的。尝试将您的包装器移动到您的孩子中并在那里应用bgImg,然后每个实例都将被隔离。

标签: vue.js vuejs2


【解决方案1】:

更新您孩子的形象。示例on codesandbox

你的父母长这样

<template>
  <div id="app">
    <div v-for="n in 5" :key='n'>
        <child/>

        <!-- <child @imageSelected="updateBg($event)"/> -->
    </div>
  </div>
</template>

<script>
import child from "./components/child";

export default {
  name: "App",
  data() {
    return {
      msg: "Parent Message",
      // testUrl: "Image URL",
      // bgImg: {}
    };
  },
  methods: {
    // updateBg(url,index) {
    //   // this.testUrl = url;
    //   this.bgImg[index] = {
    //     "background-image": "url(" + url + ")"
    //   };
    //   // console.log(this.bgImg);
    // },

  },
  components: {
    child
  }
};
</script>

<style>
#app {
  font-family: "Avenir", Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
  margin-top: 60px;
}
.wrapper {
  width: 300px;
  height: 100px;
  margin-bottom: 30px;
  border: 1px solid red;
  background-size: cover;
}
</style>

和你的孩子一样

<template>
  <div>
    <div class="wrapper" :style="img">
      <input type="file" @change="getImage">
    </div>
  </div>
</template>

<script>
export default {
  name: "HelloWorld",
  props: {
    msg: String
  },
  data(){
    return {
      img:''
    }
  },
  methods: {
    getImage(e) {
      var file = e.target.files[0];
      this.createImage(file);
    },
    createImage(file) {
      var reader = new FileReader();
      reader.readAsDataURL(file);

      var vm = this;
      reader.onload = function() {
        // console.log(this.result)
        vm.img = {
        "background-image": "url(" + this.result + ")"
      }
        // don't need
        // vm.$emit("imageSelected", this.result);
      };
    }
  }
};
</script>

更新

从子级更新父级中的图像。示例on codepen

你的父母

<template>
  <div id="app">
    <div v-for="n in imgCount" :key="n">
      <div class="wrapper" :style="imgs[n]">
        <sibling/>
        <child :image-id="n" @imageSelected="updateBg($event)"/>
      </div>
    </div>
  </div>
</template>

<script>
import child from "./components/child";
import sibling from "./components/simpleCmp";

export default {
  name: "App",
  data() {
    return {
      imgCount: 5,
      msg: "Parent Message",
      testUrl: "Image URL",
      bgImg: {},
      imgs: []
    };
  },
  methods: {
    updateBg(item) {
      // console.log(item.index);
      this.$set(this.imgs, item.index, item.bg)
    }
  },
  components: {
    child,
    sibling
  }
};
</script>

你的孩子

<template>
  <div>
    <input type="file" @change="getImage">
  </div>
</template>

<script>
export default {
  name: "HelloWorld",
  props: {
    msg: String,
    imageId: Number
  },
  methods: {
    getImage(e) {
      var file = e.target.files[0];
      if (!file) return;
      this.createImage(file);
    },
    createImage(file) {
      var reader = new FileReader();
      reader.readAsDataURL(file);

      var vm = this;
      reader.onload = function() {
        // console.log(this.result);
        vm.$emit("imageSelected", {
          index: vm.imageId,
          bg: {
            "background-image": "url(" + this.result + ")"
          }
        });
      };
    }
  }
};
</script>

【讨论】:

  • 我发布的演示是我的应用程序的简化版本。在实际应用程序中,包装器下的该子组件还有其他兄弟组件,因此无法移动该子组件中的包装器。您可以建议解决此问题的任何其他方式。谢谢
  • 我已经更新了我的codesandbox demo
  • 另一种方法是使用数组和 vuex 存储来存储图像
  • @Sabjee 你能做一个演示吗?谢谢
猜你喜欢
  • 1970-01-01
  • 2017-12-17
  • 2018-11-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-11-09
  • 2020-09-02
  • 2020-07-30
相关资源
最近更新 更多