title: Vue doesn't update DOM upon 'indirectly' changing the value of an expression
body: <p><strong>TL;DR</strong></p>
  
  <p>I am trying to dynamically build a UI from JSON. The JSON represents a vue.js app with application state (variables) &amp; UI building logic conditional on those variables.</p>
  
  <p>The JSON object of <code>"type": "switch"</code> (see the fiddle linked below), directs the vue.js app to display one of many <code>"cases": {"case1": {..}, "case2": {..}}</code> depending on the value of a state variable <code>"variable": "key" /*translates to vueApp.key */</code>.</p>
  
  <p>Changing one of the variables (<code>update_status</code>) leads to DOM update initially. Changing it again after mounting the app does not affect the DOM, sadly. I'm pretty sure I am doing something stupid or missing something subtle.</p>
  
  <hr>
  
  <p><strong>Slightly longer version</strong>:</p>
  
  <p>(If you're still reading this, <a href="https://jsfiddle.net/eywraw8t/104139/" rel="noreferrer">please look at the fiddle</a> at this point. None of the below will make sense without it. Thanks!)</p>
  
  <p><em>Vue.js Template</em> (with <code>app.variables.update_status = "available"</code>)</p>
  
  <pre class="lang-html prettyprint-override"><code>&lt;script type="text/x-template" id="template-switch"&gt;
    &lt;div&gt;
        &lt;!-- Debug statements --&gt;
        Switch cases: {{data.cases}}&lt;br&gt;
        Variables: {{$root.variables}}
  
  
        &lt;div v-for="(value, key) in data.cases"&gt;
            &lt;div v-bind:class="$root.variables[data.variable]"
                 v-if="key == $root.variables[data.variable]"&gt;
                &lt;all-components v-bind:data="value"&gt;&lt;/all-components&gt;
            &lt;/div&gt;
        &lt;/div&gt;
    &lt;/div&gt;
  &lt;/script&gt;
  </code></pre>
  
  <p><em>Input JSON</em> (bound as <code>data</code> in the above template):</p>
  
  <pre class="lang-js prettyprint-override"><code>{
      // Switch on value of app.variables.update_status
      "type": "switch",
      "variable": "update_status",   // Refers to app.variables.update_status
                                     // Used in &lt;script id="template-switch"&gt;
      "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."
          }
      }
  }
  </code></pre>
  
  <p><strong>My question:</strong></p>
  
  <p>Assuming <code>app</code> is the Vue.js app, I'd expect setting <code>app.variables.update_status = "available"</code> should lead to DOM change. But it doesn't as described in TL;DR section. I'm hoping to understand why.</p>
  
  <p><strong>What I have tried</strong>:</p>
  
  <ul>
  <li>Made the app watch the entire hierarchy under the object.</li>
  <li>I initially thought this is because Vue is unable to monitor <code>object[key]</code> expression where key can change. <a href="https://jsfiddle.net/eywraw8t/104119/" rel="noreferrer">But its definitely able to do it.</a></li>
  <li>Last value set before mounting the app shows up. After the app is mounted, any change to the the variable sticks but doesn't trigger DOM update. (Annotated with "Doesn't work!" in the fiddle.)</li>
  </ul>
  
  <p><strong>Try it out!</strong></p>
  
  <p>Here's the <strong><a href="https://jsfiddle.net/eywraw8t/104139/" rel="noreferrer">JS Fiddle</a></strong> (heavily downsized, and commented for easier understanding :))</p>
  
  <p><strong>What to try:</strong></p>
  
  <p>Once the fiddle runs, open the browser console and try executing the following statements:</p>
  
  <ul>
  <li><code>DEBUG.variables.update_status = "available";</code></li>
  <li><code>DEBUG.variables.update_status = "checking";</code></li>
  </ul>
  
  <p>Vue.js version: 2.5.16</p>
  
  <hr>
  
  <h2>Update</h2>
  
  <p>Also, I just found out that if I pass data object as:</p>
  
  <pre><code>new Vue({.., data: { .. , variables: {update_status: "temp"}}})
  </code></pre>
  
  <p>– it works!</p>
  
  <p>I don’t understand this, primarily because variables field is set up to have a deep watcher. I’d assume that when it would have a its fields updated (such as <code>variables.update_status = "new-value";)</code>, the observer would eventually trigger the DOM update. But for some reason this doesn’t happen.</p>
  
  <p>I’m really hoping I’m doing something stupid, and that this isn’t this a bug.</p>
  
  <p>Link to the new Fiddle that shows this behaviour: <a href="https://jsfiddle.net/g0z3xcyk/" rel="noreferrer">https://jsfiddle.net/g0z3xcyk/</a></p>