Test

HTML

<script type="text/x-template" id="template-all-components">
  <div v-if="data.type == 'paragraph'">
  	  <paragraph v-bind:data="data.text"></paragraph>
  </div>
  <div v-else-if="data.type == 'switch'">
      <weave-switch v-bind:data="data"></weave-switch>
  </div>
</script>
<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>
<script type="text/x-template" id="template-paragraph">
  <p>{{data}}</p>
</script>

<script type="text/x-template" id="template-card">
  <all-components v-bind:data="ui"></all-components>
</script>


<div id="app">
  
</div>

Vue

function registerComponents() {
    Vue.component('all-components', {
      template: '#template-all-components',
      props: ['data']
    });
    Vue.component('weave-switch', {
      template: '#template-switch',
      props: ['data']
    });
    Vue.component('paragraph', {
      template: '#template-paragraph',
      props: ['data']
    });
}

function GenericCard(selector, options) {
    var data = Object.assign({}, options.data, {variables: {}});
    var watch = {};
    Object.keys(data).forEach(function(key) {
        watch[key] = {handler: function(val) {}, deep: true};
    });
    var app = new Vue({
        template: options.template,
        data: data,
        watch: watch,
    });
    
    DEBUG = app;

    return {
        load: function(data) {
            Object.keys(data).forEach(function(key) {
                app[key] = data[key];
            });
            
            app.variables.update_status = "checking";
						
            app.$mount();
            var dom = app.$el;
            $(selector).append(dom);
            
            // Doesn't work!
            DEBUG.variables.update_status = "available";
        }
    };
}

registerComponents();

card = GenericCard('#app', {
  template: "#template-card",
  data: {
  	ui: {}
  }
});
card.load({
		ui: {
      // 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."
        }
      }
    }
  });
  
  
DEBUG.variables.update_status = "checking";