There is a task in the component to untie the object from the store. But so that it is reactive in the component itself.

If I create a copy using Object.assign or JSON.parse(JSON.stringify()) when creating or mounting a component, a copy is created, but the data is no longer reactive. Who implements this task?

ps. As an option, I can declare in date the object itself and all its properties are empty, then assign values ​​then everything works well. But it is not convenient when the object is large, to rewrite all its properties in the component, a little wrong as I understand it.

  • There seems to be a problem not in the decoupling, but in the reactivity of nesting: item is reactive, item.id is not. - Artem Gorlachev
  • Yes, I understand the fact of the matter. So far, I implement only by setting each variable separately, which is extremely inconvenient when there are 40 variables in the object - Ruslan Semenov
  • one
    Then you can enter data for example through Object.assign / spread - {...this.item, ...{title:'new title'}} , it’s not very messy - Artem Gorlachev

3 answers 3

https://ru.vuejs.org/v2/guide/reactivity.html

We read about this.$set

For example your case:

 this.$set(this.$data, 'someObject', { key: 'value' }) 
  • one
    This is not to write to data as null, but you can write to data right away as I answered. Also $ set sets for a specific property, and the author has many such properties. - Ilya Zelenko
  • That's right, but set can change the whole object. I'll check it out - Ruslan Semenov
  • Vue.set(this.$data, 'item', this.inputItem) worked, but this way the objects remain connected, I need to untie it. Thanks for the answer. - Ruslan Semenov
  • I have ceased to understand the essence of the question. It is necessary to untie the object from the component, but so that it remains reactive. Like this? - yarkov_aleksei
  • one
    Vue.set(this.$data, 'item', this.inputItem) do not do this unless you know exactly what you are doing. What about using computed and watch? - user273805 pm

For cloning, I advise this , JSON does not copy everything, but Object.assign not deep.

Don't quite understand what it means

unlink the store object from the component.

If you need to take data from the store and they are reactive:

As an option, I can declare in date the object itself and all its properties are empty, then assign values ​​then everything works well.

You can even like this:

  data () { // что нужно взять из store const fromStore = { info: this.$store.state.obj1, info2: this.$store.state.obj2 } return { ...clone(fromStore), // обычное реактивное свойстов normalProperty: 'value' } }, 

clone - your cloning function

But it is not convenient when the object is large, to rewrite all its properties in the component, a little wrong as I understand it.

It seems everything is correct. Until then, you also somehow inserted data from the store, I do not think that much more when it turns out.

  • clone doesn’t seem to be available in date 'clone' is not defined , as I understand it is part of lodash - Ruslan Semenov
  • @RuslanSemenov I meant that you should have a clone function that clones) - Ilya Zelenko
  • @RuslanSemenov see an example codepen.io/iliyazelenko/pen/aRvazm , there I brought an even more convenient way to not cause clone many times - Ilya Zelenko
  • So in your example, you also use JSON.parse (JSON.stringify (data)) This is also what I do - Ruslan Semenov
  • @RuslanSemenov You need to use lodash deppClone , in the example I didn’t bother with this and did it via JSON. Cloning via JSON works fine there, change it to lodash cloneDeep because it’s a better practice and that’s it. - Ilya Zelenko

In general, I have already checked on several projects and came to the conclusion that we should do this: component.vue

  props: { item: { type: Object, default: () => { return {}; } } }, data() { return { editedItem: {} }; }, methods: { refresh() { this.editedItem = Object.assign({}, this.item); this.dialog = true; } }, beforeMount() { this.refresh(); } 

In this case, when I call the component, I transfer old data or an empty object.

 <component-form :item="old.item"></component-form> 

old.item is a purely example; you can pass an empty object or do not transfer anything. old.item default, an empty object will be set as default.

With this approach, everything is decoupled and works quite correctly, and in case of changes I perform an update in the store via the object id.