Vue: shared data between different pages

var app = new Vue({
    el: '#app',
    data: {
        sharedData : ""
    },

    methods: {
        goToPageB: function() {
             if (some condition is met) {
                window.location.href="pageB.html";
                sharedData = 1234;  <------- I want to access sharedData in page B as well
             } 

        } 
    }

I am new to Vue, i made a dummy login page and try to make my main page display sharedData according to the username. But the data is always lost after my app directs to Page B. How can I fix this?


Solution 1:

You can pass the sharedData as an URL param : 'window.location.href="pageB.html?sharedData=myData"' and access it in the other page. If you would had been using vue-router, you could just do

this.$route.params.sharedData

As you are not using it, You can just use plain javascript to get it, however you will have to write a helper function like following to get the params, as explained here

var QueryString = function () {
  // This function is anonymous, is executed immediately and 
  // the return value is assigned to QueryString!
  var query_string = {};
  var query = window.location.search.substring(1);
  var vars = query.split("&");
  for (var i=0;i<vars.length;i++) {
    var pair = vars[i].split("=");
        // If first entry with this name
    if (typeof query_string[pair[0]] === "undefined") {
      query_string[pair[0]] = decodeURIComponent(pair[1]);
        // If second entry with this name
    } else if (typeof query_string[pair[0]] === "string") {
      var arr = [ query_string[pair[0]],decodeURIComponent(pair[1]) ];
      query_string[pair[0]] = arr;
        // If third or later entry with this name
    } else {
      query_string[pair[0]].push(decodeURIComponent(pair[1]));
    }
  } 
  return query_string;
}();

Vue way

You can use a centralised state management to manage your shared data, which will be available across page unless you reload the page.

You can define you state, like following:

var store = {
  state: {
    message: 'Hello!'
  },
  setMessageAction (newValue) {    
    this.state.message = newValue
  },
  clearMessageAction () {
    this.state.message = 'action B triggered'
  }
}

and you can use it in your components like following:

var vmA = new Vue({
  data: {
    privateState: {},
    sharedState: store.state
  }
})
var vmB = new Vue({
  data: {
    privateState: {},
    sharedState: store.state
  }
})

A Better Vue way: Vuex way

However Vue ecosystem havs a dedicated a redux like state management system as well, called vuex which is quite popular among community. You store all your projects/users etc in vuex state, and each component can read/update from the central state. If its changed by one component, updated version is available to all components reactively. You can initiate the data in one place using actions in vuex itself.

Following is the architecture diagram:

enter image description here

You can have a look at my answer here on similar question and have a look at example on how to call api and save data in store.

Solution 2:

It doesn't really look like you need to employ state management for something that minor. If you're simply looking to pass data from one child component to another then I would suggest using an event bus.

Non Parent-Child Communication

Sometimes two components may need to communicate with one-another but they are not parent/child to each other. In simple scenarios, you can use an empty Vue instance as a central event bus:

var bus = new Vue()

// in component A's method
bus.$emit('id-selected', 1)

// in component B's created hook
bus.$on('id-selected', function (id) {
  // ...
})

In more complex cases, you should consider employing a dedicated state-management pattern.