【问题标题】:Using duplicate VueJS component on same page, doesn't reference it's own instance properly在同一页面上使用重复的 VueJS 组件,没有正确引用它自己的实例
【发布时间】:2017-05-04 14:58:58
【问题描述】:

我已经构建了一个 VueJS 组件并在同一页面上多次使用它。组件完美地相互独立工作,但是组件中有一个方法可以获取它的 offsetWidth 并将其(带有前缀)作为一个类(例如 width-800)应用于组件。

当页面上只有一个组件时,它可以正常工作。

当有多个时,只有最后一次出现应用该类。它确实以正确的宽度正确计算了类,但只是没有将其应用于页面上的其他类。

<template>
    <div id="app-medialib" v-bind:class="[this.breakpoint]">
        <p>{{ this.breakpoint }}</p>

this.breakpoint 是一个保存类名的数据属性。

mounted: function(){
  var self = this;

  this.calculateBreakpoint();

  window.onresize = function(event) {
      self.calculateBreakpoint();
  };
}

以及断点方法:

calculateBreakpoint: function(){
    var mediaLibraryWidth = null;

    var elems = document.getElementsByClassName('header medialib');
    for( var i=0; i<elems.length; i++ ){
        if( elems[i].offsetParent !== null ){
            console.log('elems[i]', elems[i]);
            mediaLibraryWidth = elems[i].offsetWidth;
            break;
        }
    }

    console.log('calculateBreakpoint', mediaLibraryWidth);

    if( mediaLibraryWidth > 956 ) {
        this.breakpoint = 'md';
    } else if( mediaLibraryWidth < 957 && mediaLibraryWidth > 700 ){
        this.breakpoint = 'sm';
    } else {
        this.breakpoint = 'xs';
    }

    console.log('calculateBreakpoint', this.breakpoint);
},

非常感谢任何帮助。一直在挠头。

谢谢。

【问题讨论】:

  • 我们需要调用该组件的代码以及如何计算 this.breakpoint 以提供帮助:)
  • 编辑更多代码示例,请原谅凌乱的计算,一旦正确应用类,这将被重新设计:)

标签: javascript vue.js


【解决方案1】:

当您执行 window.onresize 并将函数绑定到它时,之前的绑定会被覆盖,因此当您的应用中有多个组件时,它们的挂载函数会被调用,该函数会覆盖 window.onresize。这就是为什么只更改最后一个组件类的原因。

在您的控制台中尝试以下操作。

window.onresize = function (e) {
  console.log('a')
}

window.onresize = function (e) {
  console.log('b')
}

调整大小时仅记录“b”。

结帐:What is the best practice to not to override other bound functions to window.onresize?

在您的情况下,使用 jquery 在 window.onresize 上绑定函数将是一种更好的方法。

试试:

$(window).resize(function() {
 console.log('a')
})

$(window).resize(function() {
 console.log('b')
})

当您调整大小时,它会同时记录“a”和“b”。

所以将你的 window.onresize 更改为:

$(window).resize(function() {
  self.calculateBreakpoint();
})

或者按照 Daniel Beck 的建议,如果您想避免使用 jquery,请使用:

 window.addEventListener('resize', self.calculateBreakpoint )

【讨论】:

  • 为了避免覆盖事件绑定而将整个 jQuery 库扔进去是可怕的过度杀伤力。 window.addEventListener("resize", foo()) 会做同样的事情。
  • @DanielBeck 是的,我同意。更新我的答案,以便它也可以在没有 jquery 的情况下解决问题。谢谢。
  • 干杯。我正在删除我的答案,因为它现在实际上是你的副本。
【解决方案2】:

像这样在模板之外应用v-bind:class

Vue.component("foo", {
  template: "<div>{{item}}</div>",
  props: ["item"]
});

var app = new Vue({
  el: "#app",
  data: {
    background: "blue",
    items: ["a", "b", "c", "d"]
  },
  mounted: function() {
    var self = this;
    this.calculateBreakpoint();
    window.onresize = function(event) {
      self.calculateBreakpoint();
    };
  },
  methods: {
    calculateBreakpoint: function() {
      var mediaLibraryWidth = null;
      var elems = document.getElementsByClassName("app");
      for (var i = 0; i < elems.length; i++) {
        if (elems[i].offsetParent !== null) {
          console.log("elems[i]", elems[i]);
          mediaLibraryWidth = elems[i].offsetWidth;
          break;
        }
      }

      console.log("calculateBreakpoint", mediaLibraryWidth);

      if (mediaLibraryWidth > 956) {
        this.background = "red";
      } else if (mediaLibraryWidth < 957 && mediaLibraryWidth > 700) {
        this.background = "blue";
      } else {
        this.background = "green";
      }

      console.log("calculateBreakpoint", this.breakpoint);
    }
  }
});
.red {
  background: red;

}

.blue {
  background: blue;

}

.green {
  background: green;

}

.widget {
  margin: 10px;
  padding: 20px;
  width: 200px;
  font-weight: bold;
  font-size: 16px;
  color: white;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.1.10/vue.min.js"></script>
<div id="app" class="app"> 
  <foo v-for="item in items" :class="[background]" class="widget" :item="item"> 
</div> 

https://codepen.io/anon/pen/RVLrmG

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-08-11
    • 1970-01-01
    • 2017-08-01
    • 2022-06-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多