[Vuejs]-How can I share a vue componenent state by sharing an url?

3👍

Instead of registering route like /path/:parameter_1/:parameter_2 you should actually register /path and then use this.$router.push('/path?parameter_1=xxx&parameter_2=yyy')

This is an excerpt from my code – the data-table component will emit pagination event when the page/sorting/rowsPerPage is changed and also on the initial rendering. Since we are changing only the URL query values (the text after ? in the URL) – Vue will reuse the component so we listen to beforeRouteUpdate to react on the new parameters in the URL and fetch the appropriate data:

  data () 
  {
    return {
      filters:
      {
        parameter_1: this.$route.query.parameter_1 || '',
        parameter_2: this.$route.query.parameter_2 || '',
      }
    }
  },
  watch:
  {
    filters:
    {
      deep: true,
      handler: 'filtrationHasChanged'
    }
  },
  beforeRouteUpdate (to, from, next) 
  {
    this.fetchData(to);
    next();
  },
  methods:
  {
      buildQuery (route) 
      {
        const query = route ? route.query : this.$route.query;
        let params = '?';
        if (query.parameter_1) params += '&parameter_1=' + query.parameter_1;
        if (query.parameter_2) params += '&parameter_2=' + query.parameter_2;
        return params;
      },
      fetchData (route) 
      {
        this.$ajax.get('/api_endpoint' + this.buildQuery(route)).then(response =>
        {
          // use the API response
        });
      },

      filtrationHasChanged (filters) 
      {
        const obj = Object.assign({}, this.$route.query);

        if (filters.parameter_1) 
        { 
          obj.parameter_1 = filters.parameter_1; 
        }
        else 
        { 
          delete obj.parameter_1; 
        }

        if (filters.parameter_2) 
        { 
          obj.parameter_2 = filters.parameter_2; 
        }
        else 
        { 
          delete obj.parameter_2; 
        }

        // check if old and new query are the same - VueRouter will not change the route if they are, so probably this is the first page loading
        if (this.isSameObject(query, obj)) 
        { 
          this.fetchData(); // page has been manually reloaded in the browser
        } 
        else 
        {
          this.$router.replace({
            ...this.$router.currentRoute,
            query: obj
          });
        }
      },

      isSameObject (a, b) 
      {
        let same = true;
        for (const key in a) 
        {
          if (a[key] != b[key]) 
          {
            same = false;
            break;
          }
        }
        // to handle the case when a KEY exists in B but not in A
        for (const key in b) 
        {
          if (a[key] != b[key]) 
          {
            same = false;
            break;
          }
        }
        return same;
      }
  }

Leave a comment