javascript - VueJS: ReplaceUpdate Array - Stack Overflow

I currently have an array of object that I am rendering to a table. I am trying to follow the examples

I currently have an array of object that I am rendering to a table. I am trying to follow the examples provided by Vuejs to use a "single source of truth" shared between multiple vues on the same page.

Overall, I am trying to make it where when vue1.refresh() is triggered, all the vues update their data when the "single source of truth" is updated. However, self.surveys = surveys; only updates the data on vue1.

Note: I am following the guide from .html

// The single source of truth
var cache = {
    data: [{...}] // Array of objects
}

var vue1 = new Vue({
    el: "#table",
    data: {
        surveys: cache.data // Points to the single source of truth
    },        
    methods: {
        refresh: function(){
            var self = this;                 

            // After getting data back from an ajax call
            .done(function(surveys) {
                self.surveys = surveys;
            });
        },
    }
});

var vue2 = new Vue({
    el: "#table",
    data: {
        surveys: cache.data // Points to the single source of truth
    },        
    methods: {
        // Methods
    }
});

I currently have an array of object that I am rendering to a table. I am trying to follow the examples provided by Vuejs to use a "single source of truth" shared between multiple vues on the same page.

Overall, I am trying to make it where when vue1.refresh() is triggered, all the vues update their data when the "single source of truth" is updated. However, self.surveys = surveys; only updates the data on vue1.

Note: I am following the guide from https://v2.vuejs/v2/guide/state-management.html

// The single source of truth
var cache = {
    data: [{...}] // Array of objects
}

var vue1 = new Vue({
    el: "#table",
    data: {
        surveys: cache.data // Points to the single source of truth
    },        
    methods: {
        refresh: function(){
            var self = this;                 

            // After getting data back from an ajax call
            .done(function(surveys) {
                self.surveys = surveys;
            });
        },
    }
});

var vue2 = new Vue({
    el: "#table",
    data: {
        surveys: cache.data // Points to the single source of truth
    },        
    methods: {
        // Methods
    }
});
Share Improve this question edited Jul 14, 2022 at 1:00 tony19 139k23 gold badges277 silver badges347 bronze badges asked Sep 7, 2017 at 12:08 Neve12ende12Neve12ende12 1,1944 gold badges18 silver badges35 bronze badges 2
  • 1 Take a look at Vuex – Vanojx1 Commented Sep 7, 2017 at 12:13
  • You should not mutate another ponent's data, like a parent's data from a child. – For the Name Commented Sep 7, 2017 at 14:44
Add a ment  | 

4 Answers 4

Reset to default 2

There are two principles of Vue that will help you here:

  1. In Vue, every data item is a source of truth.
  2. Only the owner of a data item should modify it.

In your example, you have three sources of truth: the one you want to be the single source, and two others that are initialized from it. Also, the one you want to be the source of truth isn't a data item, it is outside Vue.

So to start, you should have a single Vue that represents your entire application and defines any data that represents application-level state:

new Vue({
  el: '#app',
  data: {
    cache: {
      data: [...]
    }
  }
});

The two Vue objects that you created should be children of the application Vue, which is to say, ponents.

The parent tells the children what the truth is via props. The child can suggest changes to the truth by emitting events to the parent, but the child does not directly modify the truth. That keeps all management of the truth in one place.

You would need to mutate the array, not replace it.

Array.prototype.splice can do this for you, if you don't want to use something like Vuex, as suggested by Vanojx1.

Splice expects specific elements, not a plete array for insertions. Because you have an array you want to use and you need to clear the old one, the syntax is a little odd... You pass this, the start, the count to remove (the entire length), and then the elements to add (concatenated on from your new array).

Array.prototype.splice.apply([self.surveys, 0, self.surveys.length].concat(surveys));

Problem is, you are replacing shared Cache object previously assigned to surveys variable, with new, not shared object. And solution? Do not try to mutate cache object. Just use Vuex. Vuex is simple, real "Vue way" solution.

// The single source of truth
var cache = {
    data: [{...}] // Array of objects
}

var vue1 = new Vue({
    el: "#table",
    data: {
        surveys: cache.data // Points to the single source of truth
    },        
    methods: {
        refresh: function(){
            var self = this;                 

            // After getting data back from an ajax call
            .done(function(surveys) {
                self.surveys = surveys; // Problem is right here

            });
        },
    }
});

var vue2 = new Vue({
    el: "#table",
    data: {
        surveys: cache.data // Points to the single source of truth
    },        
    methods: {
        // Methods
    }
});

Try this example, which works like you code - not correct way:

var cache = {
  key1: 'Value1'
}

var vue1 = new Vue({
  el: '#app1',
  data: {
    surveys: cache
  },
  methods: {
    replace () {
      this.surveys = {key1: 'Replaced'}
    }
  }
})

var vue2 = new Vue({
  el: '#app2',
  data: {
    surveys: cache
  },
  methods: {
    replace () {
      this.surveys = {key1: 'Replaced'}
    }
  }
})
<script src="https://unpkg./[email protected]/dist/vue.min.js"></script>

<div id="app1">
  Input for Vue1: <input type="text" v-model="surveys.key1">
  <button @click="replace">Replace</button>
  <p>{{ surveys.key1 }}</p>
</div>

<div id="app2">
  Input for Vue1: <input type="text" v-model="surveys.key1">
  <button @click="replace">Replace</button>
  <p>{{ surveys.key1 }}</p>
</div>

Then try this example, with Vuex, where you can freely replace "cache object" and replacint will affect other instance:

const store = new Vuex.Store({
  state: {
    cache: {
      key1: 'Value1'
    }
  },
  mutations: {
    replace (state) {
      state.cache = {key1: 'Replaced'}
    }
  }
})

var vue1 = new Vue({
  el: '#app1',
  store,
  puted: {
    surveys () {
      return this.$store.state.cache
    }
  },
  methods: Vuex.mapMutations([
    'replace'
  ])
})

var vue2 = new Vue({
  el: '#app2',
  store,
  puted: {
    surveys () {
      return this.$store.state.cache
    }
  },
  methods: Vuex.mapMutations([
    'replace'
  ])
})
<script src="https://unpkg./[email protected]/dist/vue.min.js"></script>
<script src="https://unpkg./[email protected]/dist/vuex.min.js"></script>

<div id="app1">
  Input for Vue1: <input type="text" v-model="surveys.key1">
  <button @click="replace">Replace</button>
  <p>{{ surveys.key1 }}</p>
</div>

<div id="app2">
  Input for Vue1: <input type="text" v-model="surveys.key1">
  <button @click="replace">Replace</button>
  <p>{{ surveys.key1 }}</p>
</div>

As said in the ment before, you can use vuex to acplish what you need, everytime you need to pass data between diferent ponents you can do that with a eventBus or passing props up and down between the ponents.

When you have a aplication that needs to pass a lot of data and receive it you can use vuex, first you need to install it and then you can do it this way:

you should cut the methods out and place the mounted(), it fires when the ponent loads, i think it was you need

var vue1 = new Vue({
    el: "#table",
    data: {
        surveys: cache.data // Points to the single source of truth
    },        
    methods: {

    }.
    mounted() {
      var self = this;                 

      // After getting data back from an ajax call
      .done(function(surveys) {
      self.surveys = surveys;
      });
    }
});

when you get the response pass it to vuex store, you can do it with a mutation like this:

this.$store.mutation('handlerFunction', self.surveys)

in the vuex you need to have the handlerfunction inside the mutation

  mutations: {
    // appends a section to the tree
    handlerFunction: (state, dataReceived) => {
      //then you can do
      state.surveys = dataReceived
    },

then in your other ponent you can receive it via a getter, the logic is the same watch vuex for more deaills, you have the main logic of connection here.

Hope it helps!

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1742419562a4440408.html

相关推荐

  • javascript - VueJS: ReplaceUpdate Array - Stack Overflow

    I currently have an array of object that I am rendering to a table. I am trying to follow the examples

    22小时前
    20

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信