3
votes

I'm new to Vue.js. I followed the tutorial here - https://coligo.io/dynamic-components-in-vuejs/ - on dynamic components, to give me a dynamic layout I liked, for listing products and allowing the user to switch to an edit view when they click on one of the products in the table. So, I have a 'list-products' component and an 'edit-product' component, and which one is displayed is dependent on the state of 'currentView' in the main Vue instance.

<div id="content">
  <keep-alive>
    <component :is="currentView"></component>
  </keep-alive>
</div>

The switching is all working fine when currentView is changed. What I haven't got figured out is how best to pass the product information to the edit component such that it ends up as data. I suppose the list and edit components are two sibling components of the main Vue instance, instantiated at the same time. What I need to do is when I click on a row in listing table, have the product object used for building that row made available to the edit component. I'm not sure how I do that (at least, in a proper Vue way). When the displayed component is switched (via the change in 'currentView'), is some event called for the newly (re)displayed component? If so, I could presumably call some function?

LATER: I have determined that the 'activated' hook is called when I switch to the edit-product component, which I imagine I should be able to use somehow. Now to figure that out.

1

1 Answers

1
votes

You could use Vuex for that. Vuex is a Flux inspired state management library for Vue.

Your application basically has two different states: (1) no product selected (list-products component), and (2) any product selected (edit-product). When this is modeled with Vuex, the idea is to keep the currently selected product in a so-called store and let the components figure out their internal state depending on the store state. Here's an example:

Create a store to keep the application state:

const store = new Vuex.Store({
    state: {
        selectedProduct: null
    },
    getters: {
        selectedProduct: state => state.selectedProduct
    },
    mutations: {
        selectProduct: (state, data) => state.selectedProduct = data
    }
});

Handle product selection in your list-products component:

methods: {
    selectProduct(product) {
        this.$store.commit('selectProduct', product);
    }
}

Display the current product in edit-product:

Vue.component('edit-product', {
    store,
    template: '<div>{{selectedProduct.name}}</div>',
    computed: Vuex.mapGetters(['selectedProduct'])
});

And finally switch the components depending on the state:

new Vue({
    el: '#app',
    store,
    computed: Object.assign(Vuex.mapGetters(['selectedProduct']), {
        currentView() {
            return this.selectedProduct ? 'edit-product' : 'list-products'
        }
    })
});

Here's a basic working JSFiddle.