在Vue中重新渲染组件的最干净的方法

时间:2019-11-08 17:21:37

标签: vue.js components vue-reactivity

我有一个Keyboard.vue组件,其中包含许多Key.vue子组件实例(每个键一个)。

Key.vue中,键实际上是可以被禁用的html <button>元素。

通过单击应用程序中的某个按钮,我想重置键盘并再次启用所有键。我认为将v-if设置为false,然后再次设置为true<keyboard v-if="BooleanValue" />)将重新呈现Keyboard.vue及其所有Key.vue子组件实例。

不是。为什么不呢?

App.vue

<template>
  <div class="app">
    ...
    <keyboard v-if="!gameIsOver && showKeyboard" />
    ...
  </div>
</template>

<script>
export default {
  components: {
    Keyboard
  },
  computed: {
    gameIsOver () {
      return this.$store.state.gameIsOver
    },
    showKeyboard () {
      return this.$store.state.showKeyboard
    }
  }

Keyboard.vue

<template>
  <section>
    <key class="letter" v-for="(letter) in letters" :key="letter" :letter="letter" />
  </section>
</template>

Key.vue

<template>
  <button :disabled="disabled" @click="checkLetter(letter)">
    {{ letter }}
  </button>
</template>

<script>
export default {
  ...
  data () {
    return {
      disabled: false
    }
  }

我的按钮重置键盘触发器:

this.$store.commit('SET_KEYBOARD_VISIBILITY', false)
this.$store.commit('SET_KEYBOARD_VISIBILITY', true)

3 个答案:

答案 0 :(得分:0)

请您尝试为如下所示的键盘设置:key

<keyboard v-if="!gameIsOver && showKeyboard" :key="increment" /> 

“增量”:本地组件属性

,当您需要重新渲染视图时,将“增量”属性值增加一。使用vuex store属性与本地“增量”属性进行同步。

如何将vuex值更改与本地属性同步:添加一个“观察程序”以监视vuex存储库属性更改,并将该更改分配给我们设置为键盘“键”的本地“增量”属性

答案 1 :(得分:0)

最干净的方法是将禁用状态设置为可以重置的位置,因为重新渲染组件以重置它是利用了销毁和重新创建组件的副作用。由于没有代码将disabled变量更改为false,因此您很难弄清为什么为什么再次启用按钮

也就是说,您看到了您当前的行为,因为Vue会汇总当前“滴答”的所有更改,并且仅在该滴答结束时重新渲染。这意味着,如果将变量设置为false,然后设置为true,则只会使用最后一个值。

// Nothing happens
this.showSomething = false
this.showSomething = true

要强制重新渲染,可以使用Amitha显示的技巧,并使用键。由于Vue将针对每个键值使用一个实例,因此更改键将破坏旧的键并创建一个新的键。另外,您可以使用this.$nextTick(() => { ... })来强制您的某些代码在下一个刻度上运行。

// Destroy all the things
this.showSomething = false
this.$nextTick(() => {
  // Okay, now that everything is destroyed, lets build it up again
  this.showSomething = true
});

答案 2 :(得分:0)

首先要回答您的问题,重新渲染Vue组件或任何元素的最干净的方法是将其key属性绑定到可控制重新渲染的反应性对象,只要键值发生更改,触发重新渲染。

要在每个渲染中创建这样的唯一键,我可能会使用递增的数字,每当我想要重新渲染时,我都会对其进行递增。

<template>
<div>
  <div :key="renderKey">
  </div>
</div>
</template.

<script>
export default {
  data: () => ({
    renderKey: 0
  }),
  methods: {
    reRender() {
       this.renderKey++;
    }
  }
};
</script>

现在,为什么切换v-if不起作用:在true和false之间切换反应性属性并不一定会触发2次重新渲染,因为Vue具有异步更新队列,该队列在某些补丁中应用DOM更改时间范围,而不是每次更新。这就是Vue如此快速和高效的原因。

因此,您触发disabledfalse,然后触发true。渲染器将​​决定不更新DOM,因为最终值与上次相比没有变化,如果我没记错的话,时间约为16毫秒。因此,您可以通过在truefalse之间切换道具之间等待超过16毫秒来完成这项工作,我说的是“可以”,但不是“应该”。