当“间接”更改表达式的值时,Vue不会更新DOM

Ult*_*nct 5 javascript vue.js

TL; DR

我正在尝试从JSON动态构建UI。JSON代表vue.js应用,其中应用状态(变量)和UI构建逻辑取决于这些变量。

的JSON对象"type": "switch"(请参阅下面的小提琴链接),指示vue.js应用"cases": {"case1": {..}, "case2": {..}}根据状态变量的值显示众多应用之一"variable": "key" /*translates to vueApp.key */

更改其中一个变量(update_status)会导致DOM最初进行更新。可悲的是,在安装应用程序后再次更改它不会影响DOM。我很确定我做的是愚蠢的事情或缺少一些细微的事情。


版本略长

(如果您仍在阅读本文,请此时看小提琴。没有它,下面的内容将毫无意义。谢谢!)

Vue.js模板(带有app.variables.update_status = "available"

<script type="text/x-template" id="template-switch">
  <div>
      <!-- Debug statements -->
      Switch cases: {{data.cases}}<br>
      Variables: {{$root.variables}}


      <div v-for="(value, key) in data.cases">
          <div v-bind:class="$root.variables[data.variable]"
               v-if="key == $root.variables[data.variable]">
              <all-components v-bind:data="value"></all-components>
          </div>
      </div>
  </div>
</script>
Run Code Online (Sandbox Code Playgroud)

输入JSON(绑定data在上面的模板中):

{
    // Switch on value of app.variables.update_status
    "type": "switch",
    "variable": "update_status",   // Refers to app.variables.update_status
                                   // Used in <script id="template-switch">
    "cases": {
        // if app.variables.update_status == "checking" (Initial value)
        "checking": {
          "type": "paragraph",
          "text": "Checking for updates"
        },
        // if app.variables.update_status == "available" (Changed below)
        "available": {
            "type": "paragraph",
            "text": "Updates available."
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

我的问题:

假设app是Vue.js应用程序,我希望设置app.variables.update_status = "available"会导致DOM更改。但这与TL; DR部分中所描述的不一样。我希望了解原因。

我曾尝试

  • 使应用监视对象下的整个层次结构。
  • 我最初以为这是因为Vue无法监视object[key]可以更改键的表达。但是它绝对能够做到。
  • 显示安装应用程序之前设置的最后一个值。挂载应用后,对变量的任何更改都会保留,但不会触发DOM更新。(在小提琴中用“不起作用!”注释。)

试试看!

这是JS Fiddle(已大幅缩小尺寸,并添加了注释以便于理解:)

尝试方法:

提琴一旦运行,请打开浏览器控制台并尝试执行以下语句:

  • DEBUG.variables.update_status = "available";
  • DEBUG.variables.update_status = "checking";

Vue.js版本:2.5.16


更新资料

另外,我刚刚发现,如果我将数据对象传递为:

new Vue({.., data: { .. , variables: {update_status: "temp"}}})
Run Code Online (Sandbox Code Playgroud)

- 有用!

我不明白这一点,主要是因为将变量字段设置为具有深度监视程序。我假设当它的字段更新时(例如variables.update_status = "new-value";),观察者最终会触发DOM更新。但是由于某种原因,这种情况不会发生。

我真的希望自己做的事很愚蠢,这不是一个错误。

链接到显示此行为的新提琴:https : //jsfiddle.net/g0z3xcyk/

Lui*_*duz 5

它不会在您的第一个小提琴中更新的原因是因为Vue不会检测到属性的添加或删除,并且您在update_status实例化vue时不会传递属性,因此文档会对其进行进一步说明

在第二个小提琴中,您要设置update_status实例vue的时间,这就是在这种情况下检测到变化的原因。

如文档中所述,另一种选择Vue.set是通过再次分配对象来完全使用或重新创建对象Object.assign