草庐IT

javascript - Vue 不会在 'indirectly' 更改表达式的值时更新 DOM

coder 2025-03-21 原文

长话短说

我正在尝试从 JSON 动态构建 UI。 JSON 表示具有应用程序状态(变量)和以这些变量为条件的 UI 构建逻辑的 vue.js 应用程序。

"type": "switch" 的 JSON 对象(参见下面链接的 fiddle ),指示 vue.js 应用程序显示多个 "case": {"case1 ": {..}, "case2": {..}} 取决于状态变量的值 "variable": "key"/*转换为 vueApp.key */.

更改其中一个变量 (update_status) 最初会导致 DOM 更新。遗憾的是,在安装应用程序后再次更改它不会影响 DOM。我很确定我正在做一些愚蠢的事情或遗漏了一些微妙的事情。


稍长的版本:

(如果你还在读这篇文章,please look at the fiddle 在这一点上。没有它,下面的任何内容都没有意义。谢谢!)

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>

输入 JSON(绑定(bind)为上述模板中的 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."
        }
    }
}

我的问题:

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

我尝试过的:

  • 让应用监视对象下的整个层次结构。
  • 我最初认为这是因为 Vue 无法监控 key 可以更改的 object[key] 表达式。 But its definitely able to do it.
  • 显示安装应用程序之前设置的最后一个值。安装应用程序后,对变量的任何更改都会保留但不会触发 DOM 更新。 (在 fiddle 中用“不起作用!”进行注释。)

试试吧!

这是 JS Fiddle (大幅缩小,并评论以便于理解 :))

尝试什么:

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

  • DEBUG.variables.update_status = "available";
  • DEBUG.variables.update_status = "检查中";

Vue.js 版本:2.5.16


更新

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

new Vue({.., data: { .. , variables: {update_status: "temp"}}})

——它有效!

这个我不太懂,主要是variables字段设置了deep watcher。我假设当它的字段更新时(例如 variables.update_status = "new-value";),观察者最终会触发 DOM 更新。但出于某种原因,这并没有发生。

我真的希望我在做一些愚蠢的事情,这不是一个错误。

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

最佳答案

它不会在您的第一个 fiddle 中更新的原因是因为 Vue 不检测属性添加或删除,并且您在实例化 vue 时没有传递 update_status 属性,the docs explain it further .

在你的第二个 fiddle 中,你在实例化 vue 时设置 update_status,这就是为什么在这种情况下会检测到更改。

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

关于javascript - Vue 不会在 'indirectly' 更改表达式的值时更新 DOM,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50999171/

有关javascript - Vue 不会在 'indirectly' 更改表达式的值时更新 DOM的更多相关文章

  1. ruby-on-rails - Ruby on Rails 迁移,将表更改为 MyISAM - 2

    如何正确创建Rails迁移,以便将表更改为MySQL中的MyISAM?目前是InnoDB。运行原始执行语句会更改表,但它不会更新db/schema.rb,因此当在测试环境中重新创建表时,它会返回到InnoDB并且我的全文搜索失败。我如何着手更改/添加迁移,以便将现有表修改为MyISAM并更新schema.rb,以便我的数据库和相应的测试数据库得到相应更新? 最佳答案 我没有找到执行此操作的好方法。您可以像有人建议的那样更改您的schema.rb,然后运行:rakedb:schema:load,但是,这将覆盖您的数据。我的做法是(假设

  2. ruby-on-rails - rails : "missing partial" when calling 'render' in RSpec test - 2

    我正在尝试测试是否存在表单。我是Rails新手。我的new.html.erb_spec.rb文件的内容是:require'spec_helper'describe"messages/new.html.erb"doit"shouldrendertheform"dorender'/messages/new.html.erb'reponse.shouldhave_form_putting_to(@message)with_submit_buttonendendView本身,new.html.erb,有代码:当我运行rspec时,它失败了:1)messages/new.html.erbshou

  3. ruby-on-rails - 'compass watch' 是如何工作的/它是如何与 rails 一起使用的 - 2

    我在我的项目目录中完成了compasscreate.和compassinitrails。几个问题:我已将我的.sass文件放在public/stylesheets中。这是放置它们的正确位置吗?当我运行compasswatch时,它不会自动编译这些.sass文件。我必须手动指定文件:compasswatchpublic/stylesheets/myfile.sass等。如何让它自动运行?文件ie.css、print.css和screen.css已放在stylesheets/compiled。如何在编译后不让它们重新出现的情况下删除它们?我自己编译的.sass文件编译成compiled/t

  4. ruby-on-rails - Rails 3.2.1 中 ActionMailer 中的未定义方法 'default_content_type=' - 2

    我在我的项目中添加了一个系统来重置用户密码并通过电子邮件将密码发送给他,以防他忘记密码。昨天它运行良好(当我实现它时)。当我今天尝试启动服务器时,出现以下错误。=>BootingWEBrick=>Rails3.2.1applicationstartingindevelopmentonhttp://0.0.0.0:3000=>Callwith-dtodetach=>Ctrl-CtoshutdownserverExiting/Users/vinayshenoy/.rvm/gems/ruby-1.9.3-p0/gems/actionmailer-3.2.1/lib/action_mailer

  5. ruby - Highline 询问方法不会使用同一行 - 2

    设置:狂欢ruby1.9.2高线(1.6.13)描述:我已经相当习惯在其他一些项目中使用highline,但已经有几个月没有使用它了。现在,在Ruby1.9.2上全新安装时,它似乎不允许在同一行回答提示。所以以前我会看到类似的东西:require"highline/import"ask"Whatisyourfavoritecolor?"并得到:Whatisyourfavoritecolor?|现在我看到类似的东西:Whatisyourfavoritecolor?|竖线(|)符号是我的终端光标。知道为什么会发生这种变化吗? 最佳答案

  6. ruby - 在 jRuby 中使用 'fork' 生成进程的替代方案? - 2

    在MRIRuby中我可以这样做:deftransferinternal_server=self.init_serverpid=forkdointernal_server.runend#Maketheserverprocessrunindependently.Process.detach(pid)internal_client=self.init_client#Dootherstuffwithconnectingtointernal_server...internal_client.post('somedata')ensure#KillserverProcess.kill('KILL',

  7. ruby 正则表达式 - 如何替换字符串中匹配项的第 n 个实例 - 2

    在我的应用程序中,我需要能够找到所有数字子字符串,然后扫描每个子字符串,找到第一个匹配范围(例如5到15之间)的子字符串,并将该实例替换为另一个字符串“X”。我的测试字符串s="1foo100bar10gee1"我的初始模式是1个或多个数字的任何字符串,例如,re=Regexp.new(/\d+/)matches=s.scan(re)给出["1","100","10","1"]如果我想用“X”替换第N个匹配项,并且只替换第N个匹配项,我该怎么做?例如,如果我想替换第三个匹配项“10”(匹配项[2]),我不能只说s[matches[2]]="X"因为它做了两次替换“1fooX0barXg

  8. ruby - 主要 :Object when running build from sublime 的未定义方法 `require_relative' - 2

    我已经从我的命令行中获得了一切,所以我可以运行rubymyfile并且它可以正常工作。但是当我尝试从sublime中运行它时,我得到了undefinedmethod`require_relative'formain:Object有人知道我的sublime设置中缺少什么吗?我正在使用OSX并安装了rvm。 最佳答案 或者,您可以只使用“require”,它应该可以正常工作。我认为“require_relative”仅适用于ruby​​1.9+ 关于ruby-主要:Objectwhenrun

  9. ruby - 无法让 RSpec 工作—— 'require' : cannot load such file - 2

    我花了三天的时间用头撞墙,试图弄清楚为什么简单的“rake”不能通过我的规范文件。如果您遇到这种情况:任何文件夹路径中都不要有空格!。严重地。事实上,从现在开始,您命名的任何内容都没有空格。这是我的控制台输出:(在/Users/*****/Desktop/LearningRuby/learn_ruby)$rake/Users/*******/Desktop/LearningRuby/learn_ruby/00_hello/hello_spec.rb:116:in`require':cannotloadsuchfile--hello(LoadError) 最佳

  10. ruby-on-rails - 项目升级后 Pow 不会更改 ruby​​ 版本 - 2

    我在我的Rails项目中使用Pow和powifygem。现在我尝试升级我的ruby​​版本(从1.9.3到2.0.0,我使用RVM)当我切换ruby​​版本、安装所有gem依赖项时,我通过运行railss并访问localhost:3000确保该应用程序正常运行以前,我通过使用pow访问http://my_app.dev来浏览我的应用程序。升级后,由于错误Bundler::RubyVersionMismatch:YourRubyversionis1.9.3,butyourGemfilespecified2.0.0,此url不起作用我尝试过的:重新创建pow应用程序重启pow服务器更新战俘

随机推荐