Vue3 道具更新标题属性但不计算道具

分享于2022年07月17日 css vue-reactivity vue.js vuejs3 问答
【问题标题】:Vue3 道具更新标题属性但不计算道具(Vue3 prop updates title attribute but not computed prop)
【发布时间】:2022-02-07 23:22:48
【问题描述】:

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




它基于作为道具传递的 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 何时进行更新,它管理响应性。我通过不使用对象作为道具来管理解决方法。

【解决方案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 中没有强制不变性。