【问题标题】:How to control order of rendering in vue.js for sibling component如何控制 vue.js 中兄弟组件的渲染顺序
【发布时间】:2017-03-28 14:04:13
【问题描述】:

我有以下类型的代码:

<div>
  <compA />
  <compB />
</div>

如何确保第一个 compA 仅在呈现 compB 之后才呈现。

为什么我想要的是我对compA 的几个元素有一些依赖,而compB 的样式取决于这些元素的存在。

为什么要详细说明

我有一些复杂的 UI 设计,滚动时会固定一个框。所以当你滚动时它不会超出屏幕,一旦你开始滚动它就会固定它开始触摸标题。所以我使用jquery-visible 来查找具有特定iddiv 在屏幕上是否可见,如果不可见,我会更改样式并固定该框。以下代码应该说明我在做什么:

methods: {
  onScroll () {
    if ($('#divId').visible(false, false, 'vertical')) { // This is div from the compA, so I want to make sure it is rendered first and it is visible
      this.isFixed = false
    } else {
      this.isFixed = true
    }
  }
},
mounted () {
  window.addEventListener('scroll', this.onScroll() }
},
destroyed () {
  window.removeEventListener('scroll', this.onScroll)
}

我不想将它们放在同一个组件中,原因之一是这些组件的性质没有意义,其他我在很多地方使用compA,而compB 仅特定于一页。这些布局也不允许我按照 cmets 中的建议将 compB 设为 compA 的子级。

欢迎提出任何建议。

【问题讨论】:

  • 我最好的方法是使用事件。
  • 可能CompB 不是CompA 的孩子,因为CompB 依赖于CompA
  • @AmreshVenugopal 不,由于这些组件的性质,我不喜欢这样做。
  • @JonatasWalker 如何在这里使用事件?
  • 好吧,我的另一个问题是为什么CompB 依赖于CompA 的元素,为什么不依赖CompA 的数据?由于不同元素种类的差异也会是某种v-if='true': make input tag'v-else: make p-tag之类的实现?

标签: javascript vue.js vuejs2 vue-component


【解决方案1】:

带有事件的选项:

<!-- Parent -->
<div>
  <comp-a @rendered="rendered = true"></comp-a>
  <component :is="compB"></component>
</div>
<script>
  // import ...
  export default {
    components: { CompA, CompB },
    watch: {
      rendered: function (val) {
        if (val) this.compB = 'comp-b';
      }
    },
    data() {
      return {
        rendered: false,
        compB: null
      }
    }
  }
</script>

<!-- Component B -->
<script>
  export default {
    mounted() {
      this.$emit('rendered');
    }
  }
</script>

【讨论】:

  • 所以 @rendered 是从 comp-a 发出的,对吧?
  • 不。我想我颠倒了你需要的顺序。只需更改顺序即可。
  • 是的,这也有效,但使用setTimeout,而不是没有setTimeout,正如我对@AmreshVenugopal 的回答所评论的那样
【解决方案2】:

在完成编辑后,我意识到依赖不是数据驱动的,而是事件驱动的(onscroll)。我已经尝试过something 并且看起来它可以工作(代码中的 setTimeout 用于演示)。

我的实现与 Jonatas 的实现略有不同。

<div id="app">
  RenderSwitch: {{ renderSwitch }} // for demonstration 
  <template v-if='renderSwitch'>
    <comp-a></comp-a>  
  </template>
  <comp-b @rendered='renderSwitchSet'></comp-b>
</div>
  1. component-B 被渲染时,它会发出一个事件,该事件只是在component-Acomponent-B 的父级中设置一个数据属性。

  2. 周围的&lt;template&gt; 标签用于减少v-if 的额外标记。

  3. 时刻 renderSwitch 设置为 truecomponent-a 被创建。

【讨论】:

  • 谢谢,这行得通,有趣的是我必须给setTimeout,即使超时可以是 0 秒,但没有超时它不起作用。这可能是什么原因?
  • 也许在$emit 发生的组件中发生了很多事情?如果是,则 setTimeouts 将函数排队,使其有时间执行,read here。在我的小提琴中,即使没有超时,它也能正常工作。
猜你喜欢
  • 1970-01-01
  • 2018-04-05
  • 1970-01-01
  • 2017-05-16
  • 1970-01-01
  • 2016-11-08
  • 2016-12-03
  • 2017-10-22
  • 2013-03-09
相关资源
最近更新 更多