Stack Exchange
vuejs reactivity of complex objects
I am using Vue.js 2.5.17 I have two components, App (parent) and TreeNode (child), which display a tree structure of items from a deeply nested object. Each node in the tree is presented with the TreeNode component which is a recursive component.
TreeNode component
const TreeNode = Vue.component('TreeNode', {
    name: 'TreeNode',
    template: '#treenode',
    props: {
      model: Object,
    },
    data() {
      return {
        open: false,
      };
    },
    computed: {
      isExpandable() {
        return this.model.children &&
          this.model.children.length;
      },
    },
    methods: {
      toggle() {
        if (this.isExpandable) {
          this.open = !this.open;
        }
      },
    },
  });

TreeNode template
<script type="text/x-template" id="treenode">
  <li>
    <input type="checkbox" :id="model.name" style="display:none;"/>
    <label :for="model.name" style="color:gray;" @click="toggle">
      {{ model.name }}
      {{ model.data.example }}
    </label>
    <ul v-show="open" v-if="isExpandable">
      <TreeNode
        class="item"
        v-for="(model, index) in model.children"
        :key="index"
        :model="model">
      </TreeNode>
    </ul>
  </li>
</script>

App component template
<script type="text/x-template" id="oulist">
  <div>
    <div id="unitsTable" class="row filterlist treelist b_widget2" style="width:85%;">
      <div class="css-treeview">
          <TreeNode
            class="item"
            :model="items">
          </TreeNode>
      </div>
    </div>
</script>

App component
const App = Vue.component('App', {
    template: '#oulist',
    components: {
      TreeNode,
    },
    data() {
      return {
        items: { 
          name: 'item1',
          data: { example: '1' },
          children: [
            { 
              name: 'item11',
              children: [],
              data: { example: '1' },
            },
            {
              name: 'item12',
              children: [
                { name: 'item121', children: [], data: { example: '1' } },
                { name: 'item122', children: [], data: { example: '1' } },
              ],
              data: { example: '1' },
            },
          ],
        },
      };
    },
    methods: {
      updateItem(currNode, name, data) {
        if (currNode.name === name) {
          Object.assign(currNode.data, data);
          this.items = Object.assign({}, this.items); // tried to create a new object here and overwrite it, but it didn't help
          return;
        }
        if (currNode.children) {
          currNode.children.forEach(c => this.updateItem(c, name, data));
        }
      },
    },
});

The object posted above is just an example, my actual object has a lot more nested levels and items per level.
The problem am I facing is that whenever a property deep within my items object is changed (more specifically, the example property of the data object inside a node), the DOM is not updated. I read through the reactivity caveats and saw that adding new properties is not reactive by default, but I am not adding new properties here, just changing the existing ones.
When data from a tree node is updated, I traverse the object to find the correct node and update its properties as follows:
updateItem(currNode, name, data) {
  if (currNode.name === name) {
    Object.assign(currNode.data, data);
    this.items = Object.assign({}, this.items); // tried to create a new object here and overwrite it, but it didn't help
    return;
  }
  if (currNode.children) {
    currNode.children.forEach(c => this.updateItem(c, name, data));
  }
},

this.updateItem(this.items, 'item121', { example: 'newVal' });

Any tips ? Thanks!
EDIT: The data is always changed only in the parent (App) component.

Dontt know if i understand it correctly.. Where will the data be changed? Data can only be changed on top level, you cant modify the property inside the co.ponent because it will be overriden from its parent

The data will be changed in the parent (App) component. The method, the method call and all the data is in the parent component.
