在 Vue 中重新渲染组件的最简洁方法

dra*_*035 4 components vue.js vue-reactivity

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

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

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

事实并非如此。为什么不?

应用程序.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
    }
  }
Run Code Online (Sandbox Code Playgroud)

键盘.vue

<template>
  <section>
    <key class="letter" v-for="(letter) in letters" :key="letter" :letter="letter" />
  </section>
</template>
Run Code Online (Sandbox Code Playgroud)

Key.vue

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

<script>
export default {
  ...
  data () {
    return {
      disabled: false
    }
  }
Run Code Online (Sandbox Code Playgroud)

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

this.$store.commit('SET_KEYBOARD_VISIBILITY', false)
this.$store.commit('SET_KEYBOARD_VISIBILITY', true)
Run Code Online (Sandbox Code Playgroud)

小智 5

首先回答你的问题,重新渲染 Vue 组件或任何元素的最干净的方法是将其key属性绑定到将控制重新渲染的反应性内容,每当键值更改时,它都会触发重新渲染。

为了在每次渲染时使用这样一个唯一的键,我可能会使用一个递增的数字,并且每当我想重新渲染时我都会递增它。

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

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

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

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