【问题标题】:Vue3 prop updates title attribute but not computed propVue3 道具更新标题属性但不计算道具
【发布时间】:2022-02-07 23:22:48
【问题描述】:

我正在使用一个使用 Vue3 渲染的外部库。它具有来自第三方库的以下组件 [Edit:我意识到该库的 GitHub 存储库已过时,因此使用我的 node_modules 中的实际代码进行更新。]

<template>
  <div class="socket" :class="className" :title="socket.name"></div>
</template>

<script>
import { defineComponent, computed } from "vue";
import { kebab } from "./utils";
export default defineComponent({
  props: ["type", "socket"],
  setup(props) {
    const className = computed(() => {
      return kebab([props.type, props.socket.name]);
    });
    return {
      className
    };
  }
});
</script>

它基于作为道具传递的Socket 对象进行渲染。当我更新 Socket 的 name 属性时,我看到标题相应更新。但是,CSS/类不会更新。我已经在其父级上尝试了$forceRefresh(),但这没有任何改变。

更新:我能够将渲染代码移动到我自己的存储库中,因此我现在可以根据需要编辑此组件。

根据这个更新的代码,问题似乎是计算类。有什么办法可以强制刷新吗?

唯一一次是我在vue-cli-service serve 期间重新加载代码(不刷新页面)。

作为参考,| kebab 过滤器在这里定义:

Vue.filter('kebab', (str) => {
    const replace = s =>  s.toLowerCase().replace(/ /g, '-');

    return Array.isArray(str) ?  str.map(replace) : replace(str);
});

过滤后的属性更新不同吗?我不这么认为。

我还想知道这是否可能是反应性问题,以及是否需要使用 Vue.set 设置值,但据我了解,这在 Vue3 中没有必要,而且它也与正确更新的标题不一致。

【问题讨论】:

  • 我无法重现此demo 中的问题。
  • 问题说你使用 3 但你使用的东西是 2 - 过滤器,设置。考虑澄清这一点。 2 和 3 的反应性不同。请为您的问题提供stackoverflow.com/help/mcve。不知道什么是 Socket 以及 socket.name 是如何改变的。如果它不是响应式的,则不能期望更新计算。
  • @tony19 感谢演示。我认为我的设置的不同之处在于我使用外部 JS(不是 Vue)来更新对象。我猜是 Vue 何时进行更新,它管理响应性。我通过不使用对象作为道具来管理解决方法。

标签: css vue.js vuejs3 vue-reactivity


【解决方案1】:

计算属性是响应式的,但是 Vue 不希望你改变一个 prop 对象。

来自文档:

警告

请注意,JavaScript 中的对象和数组是通过引用传递的,所以 如果 prop 是数组或对象,则改变对象或数组本身 子组件内部会影响父状态,而 Vue 是 无法警告您注意这一点。作为一般规则,您应该避免 改变任何道具,包括对象和数组,因为这样做会忽略 单向数据绑定,可能会导致不良结果。

https://v3.vuejs.org/guide/component-props.html#one-way-data-flow

我知道这就是说,你不应该在子节点中改变它,但一般规则是,你根本不应该改变属性,而是用修改后的数据创建新对象.

在您的情况下,computed 函数将查找属性本身的更改,而不是属性成员的更改,这就是它不更新的原因。

【讨论】:

  • 好的,这有助于理解(所以旧的 Vue.set 函数和它的 Vue3 弃用仅适用于数据,而不适用于道具?)。但是,由于底层库的工作方式,我无法创建新对象(或者至少这会很麻烦)。有没有办法解决这个问题?
  • 好的,我找到了一个非常简单的解决方法:不是传递一个对象,而是传递我需要的那个对象的各个属性。这在我有限的情况下效果很好,但我可以想象如果你需要很多属性会很麻烦。
  • 这条规则完全适用于子类中的 mutating props,建议的替代方案是 2-way binding。父母没有这样的规则,不改变对象不会使数据流更简单。 “你根本不应该改变属性,而是用修改后的数据创建新对象” - 不是真的,Vue 中没有强制不变性。
猜你喜欢
  • 2021-07-09
  • 2019-06-03
  • 2018-05-06
  • 2021-05-09
  • 2018-02-07
  • 2017-11-23
  • 2022-11-24
  • 1970-01-01
  • 2021-07-27
相关资源
最近更新 更多