I have a component.

<template> <HotTable :settings="hotSettings" ></HotTable> </template> <script> import HotTable from "@handsontable/vue"; import Handsontable from "handsontable"; export default { data() { return { hotSettings: { data: [ ["", "Ford", "Volvo", "Toyota", "Honda"], ["2016", "10", 11, 12, 13], ["2017", 20, 11, 14, 13], ["2018", 30, 15, 12, 13] ], rowHeaders: true, colHeaders: true } }; }, components: { HotTable } }; </script> 

This component is displayed in three different paths: /path/path1 , /path/path2 , /path/path3 . How can I make it so that, following these paths, this component is displayed on each page, but the data for it (the data field) is different?

Recently prompted to use props in routes. It turned out the following.

Component

 <template> <HotTable :data="myData"></HotTable> </template> <script> import HotTable from "@handsontable/vue"; import Handsontable from "handsontable"; export default { data: function() { return {} }; }, props: ["myData"], components: { HotTable } }; </script> <style src="handsontable/dist/handsontable.full.css"></style> <style> #hot-preview { width: 600px; height: 400px; overflow: hidden; } </style> 

File with routes

 export default new Router({ routes: [{ path: '/tables/groups', component: Table, props: { myData: [ ["", "Ford", "Volvo", "Toyota", "Honda"], ["2016", 10, 11, 12, 13], ["2017", 20, 11, 14, 14], ["2018", 30, 15, 12, 15] ] }, }, { path: '/tables/subjects', component: Table, props: { myData: [ ["", "Ford", "Volvo", "Toyota", "Honda"], ["2016", 10, 11, 12, 15], ["2017", 20, 11, 14, 14], ["2018", 30, 15, 12, 13] ] }, }, ], }) 

This solution is working, but I need to dynamically retrieve data for the table, so I use the storage. How can I associate a repository with this design?

File store.js

 export const store = new Vuex.Store({ state: { groupsTableData: [], }, actions: { loadGroupsTableData({commit}) { axios .get("/api/tables/groups") .then((response) => { commit("SET_GROUPS_TABLE_DATA", response.data); console.log(response); }) .catch((error) => { console.log(error); }); }, }, mutations: { SET_GROUPS_TABLE_DATA(state, data) { state.groupsTableData = data; }, }, getters: { groupsTableData: state => { return state.groupsTableData } } }) 

    1 answer 1

    Option 1: $watch on $route

    • Initialize data to null
    • Use $watch to follow $route
    • In the change handler, we obtain the necessary data from the store , depending on the current path.
    • Probably the easiest option (without using additional libraries)
     const tables = { '/path/path1': store => store.state.table1, '/path/path2': store => store.state.table2, } export default { data() { return { data: null } }, watch: { $route(to, from) { const path = to.path; this.data = tables[path](this.$store); } } } 

    Option 2: wrapper components

    • For each path we create a component wrapper that will transfer the necessary data from the store to the source component.
    • I do not like this option, since I need to write a lot of almost identical components.
     <template> <original-component :table="table1" /> </template> <script> export default { computed: { ...mapGetters(['table1']) } } </script> 

    Option 3: reactive $route using vuex-router-sync

    • The vuex-router-sync library is vuex-router-sync
    • Turn data into a computed method that will return data from the store depending on the current path.
    • The easiest and cleanest option
     export default { computed: { table() { const path = store.state.route.path; return store.state...; // Π²Ρ‹Π±ΠΈΡ€Π°Π΅ΠΌ ΠΊΠ°ΠΊΠΈΠ΅ Π΄Π°Π½Π½Ρ‹Π΅ ΠΈΠ· store Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Ρ‚ΡŒ Π² зависимости ΠΎΡ‚ path } } } 
    • Could you explain this entry from the first version of this.data = tables[path](this.$store); , namely the part that after the = sign. And again: as I understand it, the code (after const tables ... ) from the first option is necessary to write in my component? - Dmitry Bystrov
    • @ Dmitry Bystrov Yes, we have tables is an object in which the key is a string, and the value is a function. This function takes the store and returns some data from it. Thus, tables[path] is the value of the tables object by the path key, that is, a function. And we immediately call this function by passing the store to it. You can split this entry into two lines for clarity ( const getter = tables[path]; this.data = getter(this.$store); ), or you can use the usual if / else instead of this line sep
    • @ Dmitry Bystrov The const tables = ... code can be written both in the component itself and (if desired) in any other place, without having forgotten to export it in that place ( export const tables = ... ), and in the component import diraria