Maintaining view state when navigating to another view - vue.js

I have one VuesJS view with two components in it that have a main-detail relationship. The user can click on an item in the main component (the item gets highlighted) and the details component will show the related detail items.
products.vue
<main></main>
<details>></details>
The user can edit a detail item and I want that to take place using a separate view containing the necessary components to edit the detail item.
I want the user to be able to navigate back to the products.vue view (say after finishing the editing process) with its state as it was when the initiated the editing operation.
I tried wrapping each of main and details in <keep-alive></keep-alive> but that did not seem to do the trick.
I have also read a few posts where <keep-alive></keep-alive> is used with the include property around the <router-view></router-view> but I'm not sure what to include in the include in my case.
Any thoughts on whether this is possible or what I'm doing wrong?
thanks

To persist state beyond route changes the state needs to either be stored:
in a component that is a parent to the <router-view> (such as <App>)
in a new vue instance with shared state that you import into the required components
in the official state management library Vuex (recommended)

Related

Events between unrelated components Vuejs

I have two Vue.js parent components.
In one component, it shows available names list which are its child components and in other it shows already selected names list.
What I want to do is that when I click on an available name, it should hide from that component and show it in the other component. And the same if I remove from a selected it should appear in available list.
But these two components are completely unrelated. How can I do this?
Option 1
Create a vuex store:
https://vuex.vuejs.org/guide/
This will allow you to share information between components.
Vuex is a state management pattern + library for Vue.js applications. It serves as a centralized store for all the components in an application
Options 2
Use something called an event bus:
https://blog.logrocket.com/using-event-bus-in-vue-js-to-pass-data-between-components/
With this method you can create events in one component and catch them in another component and they don't have to have a parent/child relationship.
Which option to go for depends on your preference and you will have to determine which is best suited for you.

Best way to use props passing to multiple children componets

I have parent component that contains form component and detail component for created_at and updated_at in editing Product page.
Form is to edit the existing data and detail component will be next to the form.
I didn't have the detail component before so I fetch data from form component and use it in the component however I need some of the data in detail component which is the child of the parent of the form component.
So I moved the fetch axios to parent component and pass the data to both children now.
Is it better to do this way or is it better to send axios request both in form component and detail component?
The form is also used in adding new product.
My opinion is that you should fire requests from most top level possible. This way your children components (building blocks) can work independently from your current context. It's called presentational component and it's role is to output some markup. The container component feeds the data to the presentational component making the data flow go from top to the bottom nicely.
So in short, you did it right! However you should be careful, when your data changes in the edit form, then you probably want to fire the request on parent again, so that the data is updated for the whole app. This kind of flow is highly facilitated by Vuex. It serves as single source of truth (data) that your whole application can rely on.

Tabbed Layout For Each Resource

I'd like to change the layout for my resources, so that the page /resource-name shows a card with the tabs "List", "Create", "Edit". I managed to make it "list" under the List tab using dataProvider(), but I can't figure out how to render the Create & Edit components under the relevant tabs. Any advice?
For what I understood you want to have a component with a <TabbedShowLayout> with tabs for list, create and edit on the route /resource? The route /resource is the one RA assumes when a component is provider in the list prop of <Resource>, so if you create a component with a <TabbedShowLayout> an in <Tab> list, put a <List> component, on create and Create component, and for edit an Edit component it might work for what you desire, I have not tested it. However see if is not ideal to use the props create, edit, and list of Resource, with them you can present data and have actions linking to one another.
Maybe your problem is in routing, since create in RA defaults to /resource/create, could you clarify your problem?

cache view in vue.js

I have started to build apps with vuejs recently and have one small issue that I can't get around:
I am using vue-router to jump between pages and lets say I have a huge list where additional items may be injected with ajax, user has to scroll, he click on item, see the details (is in new route) and when gets back list is reinitialized and has to scroll again to be at the point he was previously. Do I have some possibility to keep the state of given component (and view like scroll position) while using vue-router or do I have to keep some cache-instance in main app component and then map it on init?
Thank you.
Essentially, the issue is that your component stores state internally. Navigating away clears the state. There are two ways I see this could be handled.
1) (quickfix) instead of redirecting use another way of displaying the item details (modal, or expand come to mind). This way the state of the component is not lost
2) (the "proper way") store the state. Inevitably, you'll come up against this sooner or later and the best way to deal with storing a state is vuex. https://vuex.vuejs.org/en/intro.html Initially, this will require a bit of learning and add some complexity, but it is a worthwhile investment

Vuejs: shared states between components

I would like to know the best practice for implementing shared states between components in Vuejs.
Imagine situation A: you have a web app that shows a modal. The modal has the boolean state show. This state should change if the modal OK-button is clicked, but also if any part of the background is clicked, and perhaps even on some server pushed state change. Thus the modal should be able to change the state as should the parent app.
Situation B: you have a web app that shows input fields inside different components that share a common data value. If the user changes value through the field in one component, it should also update in the other. Again both should even update on a server push event.
Questions:
I am right that the correct way to go about this would be to use vuex and make the shared state a store field that is observed by and changed through emitted actions by all components / parents that need to modify that value?
Does that not introduce this kind of dangerous (since hard to handle) magic reactivity that we know from Meteor?
How to best document the flow, what depends on what?
A: For a modal component, I'd say that show should be a prop. So the parent component can control the modal whatever it wants. In this case there is no shared state at all.
The modal itself doesn't need to know anything about the server. If the prop show is true, just display the modal and vice versa.
I think the mask layer is a part of the modal, so when the mask is clicked, the modal emits an event. The parent component receives the event and can decide to hide the modal or not to.
Vue has an official modal example here (thanks #craig_h for mentioning): https://v2.vuejs.org/v2/examples/modal.html
B: Just bind the vuex state to the inputs. Nothing wrong.
Note that not all the components need to access the vuex store directly. For some pure UI components, just use props. So the parent components have the right to control them and increase flexibility.
I recommend you to read these docs:
https://facebook.github.io/react/docs/lifting-state-up.html
https://medium.com/#dan_abramov/smart-and-dumb-components-7ca2f9a7c7d0#.j7ry4a3as
http://redux.js.org/docs/basics/UsageWithReact.html
Yes these are React / Redux docs. Since Vue is relatively young, react community has more documentation / articles. But both Vue and React are component-based libraries. The idea of how you design a component is basically the same.
You can also take a look at this vuex example: https://github.com/vuejs/vuex/tree/dev/examples/chat
This is a very simple example but it does use all the things I mentioned above. Emitting an event, some pure UI components...