【问题标题】:Vue.js - Template with parent scope not updatingVue.js - 父范围未更新的模板
【发布时间】:2018-02-28 07:18:02
【问题描述】:

我创建了一个组件,用于以漂亮的方式显示一些信息。该组件只是内容的包装器,在父组件内呈现。父组件是这样实现子组件的:

    <my-component v-for="item in items" :key="item.id">
        <template slot="header">
            {{ item.title }}
        </template>
        <template slot="meta">
            <div>
                <template v-if="typeof item.additionalData != 'undefined'">
                    {{ item.additionalData.text }}
                </template>
            </div>
        </template>
    </my-component>

它工作正常,直到我想更改数据。 items 是父组件中的一个变量,在渲染时,数据以正确的方式解析。当我在渲染后更改 items 内部的某些内容时,子组件无法识别它。原因是 item.additionalData 是在组件渲染完成后通过 AJAX 调用添加的。

文档说

父模板中的所有内容都在父范围内编译;子模板中的所有内容都在子范围内编译。

但这似乎只在渲染时才成立。

我不能以这种方式使用我的组件还是有解决方案?

【问题讨论】:

  • 这里解释了如何等待 Ajax 调用完成,然后渲染:laracasts.com/discuss/channels/vue/…
  • 顺便说一句,欢迎来到 StackOverflow。如果以下任何答案解决了您的问题,请务必将最适合您的答案标记为已接受,以便社区可以从您的反馈中受益。如果您的问题仍未解决,请更新您的答案并提供更多信息,以便我们帮助您了解问题的根源。

标签: javascript ajax vue.js


【解决方案1】:

来自docs

由于现代 JavaScript 的局限性(以及放弃 Object.observe),Vue 无法检测到属性的添加或删除。 由于 Vue 在执行 getter/setter 转换过程 实例初始化,属性必须存在于数据对象中 以便 Vue 对其进行转换并使其具有反应性。

所以我怀疑你的 item.additionalData 字段最初是未定义的,这意味着 Vue 稍后在添加它时会错过它。最好的解决方案是定义item.additionalData,但设置为nullfalse。如果这不可能,请考虑使用Vue.set(object, key, value) 概述的here

【讨论】:

  • 我还尝试了一个名为 AdditionalLoaded 的变量,该变量最初设置为 false,后来(在 AJAX 调用之后)设置为 true,但它不会在插槽内更新。
  • 那是因为 Vue 在更新页面时做了尽可能少的工作。由于它无法监视 additionalData 的更改,因此它会跳过该插槽。
  • @M.Andrea 据我所知,没有办法做到这一点。
【解决方案2】:

我在向项目模板添加搜索图标时遇到了类似的问题。 我解决它的方法是(就你的例子而言)additionData 一个计算属性,然后它是完全反应的。这是基本形式:

computed: {
  additionalDataText() {
    return item.additionalData ? item.additionalData.text : null
  }
} 

我不清楚您的代码是显示父组件还是子组件。
实际上,您可以进行的最简单更改需要计算属性接收 item 作为参数,如下所示:

computed: {
  additionalDataText() {
    return function (item) {
      return item.additionalData ? item.additionalData.text : null
    }
  }
} 

你的模板是

<my-component v-for="item in items" :key="item.id">
    <template slot="header">
        {{ item.title }}
    </template>
    <template slot="meta">
        <div>
            <template v-if="additionalDataText(item)">
                {{ additionalDataText(item) }}
            </template>
        </div>
    </template>
</my-component>

这项技术来自 Unirgy 对这个问题的回答:Can I pass parameters in computed properties in Vue.Js。关于这种方法存在一些争议,但我在我的项目中尝试过,它似乎有效。
请注意,在引用的问题中,接受的答案建议使用一种方法,但这并没有给您所需的反应性。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-02-06
    • 1970-01-01
    • 1970-01-01
    • 2022-01-23
    • 2017-10-20
    • 2016-11-29
    • 1970-01-01
    相关资源
    最近更新 更多