【发布时间】:2018-06-23 07:53:50
【问题描述】:
TL;DR
我正在尝试从 JSON 动态构建 UI。 JSON 表示具有应用程序状态(变量)和以这些变量为条件的 UI 构建逻辑的 vue.js 应用程序。
"type": "switch" 的 JSON 对象(参见下面链接的小提琴),根据状态变量 "variable": "key" /*translates to vueApp.key */ 的值,指示 vue.js 应用显示多个 "cases": {"case1": {..}, "case2": {..}} 之一。
更改其中一个变量 (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(在上述模板中绑定为 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 无法监控
object[key]表达式,其中 key 可以更改。 But its definitely able to do it. - 显示安装应用程序之前设置的最后一个值。安装应用程序后,对变量的任何更改都会保留,但不会触发 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"}}})
– 有效!
我不明白这一点,主要是因为变量字段设置为有深度观察者。我假设当它的字段更新时(例如variables.update_status = "new-value";),观察者最终会触发 DOM 更新。但由于某种原因,这不会发生。
我真的希望我在做一些愚蠢的事情,这不是一个错误。
显示此行为的新 Fiddle 的链接:https://jsfiddle.net/g0z3xcyk/
【问题讨论】:
-
在第二个小提琴中,当您实例化
Vue时,您正在设置update_status属性,而在第一个小提琴中您没有。还有vue can't detect property addition or deletion。 -
检查this fiddle,正如@LuisOrduz 所说,Vue 无法检测到属性添加或删除。这就是为什么第一个小提琴不起作用的原因。所以一个解决方案是像你的第二个小提琴那样首先贴上它,另一个解决方案是使用
Vue.set或vm.$set。然后你不需要使用 JQUERY 将 $el 附加到目标 dom 对象,只需使用app.$mount(selector)。 -
是的,stackoverflow.com/questions/49143631/… 的另一个变体(希望我能找到更规范的答案……)。一个更简单的改动(使用
Vue.set)和一个交互按钮:jsfiddle.net/xo7rhpec
标签: javascript vue.js