【问题标题】:Array change does not rerender template数组更改不会重新渲染模板
【发布时间】:2020-09-15 21:12:14
【问题描述】:

我有一个组件,其中模板仅在我更改唯一值时才会更新:

setup(prop) {
  const uniqueValue = ref(1);
  const fullStar = ref(['fillerValue', false, false, false, false, false]);

  const displayRating = (rating: number) => {
    uniqueValue.value += 1;
    for (let index = 1; index <= rating; index++) {
      fullStar.value[index] = true;
    }
  };

  return {
    uniqueValue,
    fullStar,
  }

<template>
  <div class='ratingContainer'
    v-on:mouseleave='displayRating(storedRating)'>
    <div v-for='n in 5' :key='n'>
      <StarIcon v-if='fullStar[n]' />
      <div style="display: none">{{ uniqueValue }}</div>
    </div>
  </div>
</template>

我有一个名为fullStar 的数组,我想根据传递给displayRating 函数的评分在模板中显示一些星星。

但只有当我在模板中使用uniqueValue 值时,模板才会重新呈现,即使fullStar 数组值也发生了变化。

【问题讨论】:

  • 我是否理解正确,您有一个使用多个值的模板,但只想在 uniqueValue 更改时重新渲染?
  • 不,恰恰相反 :)。我已经更新了这个问题。所以想法是,当我将ratingContainer 元素留在组件中时,我调用displayRating 函数并传递storedRating 值。该值在组件中可用,只是省略它以免使问题混乱。问题是模板仅在我使用 {{ uniqueValue }} 时重新呈现
  • 不就是displayRating函数的问题吗?当前逻辑完全忽略输入参数并始终将所有数组项设置为false ....因此看起来组件实际上不会重新渲染,只是始终具有相同的数组内容...
  • 从头输入代码时出错。这个想法是,当调用该函数时,它将循环 x 数量(其中 x 是评级)并将数组中的 1 个布尔值设置为 true,这在本地工作正常(当我记录它时它确实显示了预期的输出)但是模板不会重新渲染。但似乎在组合 api 中存在一些关于反应性和数组的问题。 github.com/vuejs/composition-api/issues?q=array
  • 你知道你可以在没有任何数组的情况下做到这一点,对吧?或者这只是为了专门试验阵列反应性?

标签: vuejs2 vue-composition-api


【解决方案1】:

Looks like Vue is having some trouble with reactivity and array values。正如有人在该问题中所说:

只需在响应式中创建一个包含数组的对象。这很好用。类似于之前vue 2中的数据对象:

setup() {  
const fullStar = reactive({
  list: [
    { value: false },
    { value: false },
    { value: false },
    { value: false },
    { value: false },
    { value: false },
  ],
});

displayRating = (rating: number) => {
  for (let index = 1; index <= rating; index++) {
     // when this function is called it will set a number of objects in the list array to true and it will update the template.
     fullStar.list[index].value = true
  }
}

return { fullStar };
}

<template>
  <div class='ratingContainer'
    v-on:mouseleave='displayRating(storedRating)'>
    <div v-for='n in 5' :key='n'>
      <StarIcon
        v-if='fullStar.list[n].value' />
    </div>
  </div>
</template>

【讨论】:

  • 使用reactive() 时(当前)存在提到的反应性问题。使用ref([]) 时,Everythink 就好了。见我的demo。顺便说一句,你的 displayRating 函数仍然是错误的 - 如果你用参数 5 然后 3 调用它,数组无论如何都会是真的......
  • 我认为关键是您需要将属性(在本例中为布尔值)包装在对象中。 const fullStar = ref([{ value: false },{ value: false },{ value: false },{ value: false },{ value: false },{ value: false }]); 有效,但 const fullStar = ref([false, false, false, false, false, false]); 无效。 displayRating 函数有效,如果你用 3 调用它,它会将第一个对象设置为 true,其余对象将为 false。
  • omg 看看我的演示,不要再到处传播错误信息了...
  • 看起来您使用的是 Vue3 而不是我标记的组合 API。因为即使我直接在我的应用程序中复制您的代码,它也不会更新。但是当我将布尔属性包装在对象中时,您的代码示例在我的项目中有效,因为它们在组合 api 中指示读给我。因此,深呼吸并冷静下来,下次构建演示时请使用正确的规格。
  • [vue-composition-api] 不是为 Vue 2 的 composition-api 插件创建的标签,您可以在此处看到 stackoverflow.com/tags/vue-composition-api/info 。在没有明确指定使用哪个版本的 Vue 的情况下使用该标签会造成混乱,这不仅会导致人们试图帮助您,还会让人们在未来寻找答案...
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-03-14
  • 1970-01-01
  • 2020-07-07
  • 1970-01-01
  • 1970-01-01
  • 2019-06-29
  • 2018-10-23
相关资源
最近更新 更多