2

I have a Vue.js component which shows a list of customers. When the use clicks on one, it switches to an edit view for the individual customer. This is done using v-if, testing a data field, 'editMode' (set to true or false). So the template has a listing table and an edit form and which is shown is dependent on the state of 'editMode'. When the user clicks on a customer, a method is called which switches the editMode to true (thus hiding the list and displaying the form), and when they save or cancel, a method is called which switches editMode back, thus hiding the form and displaying the list.

It works OK as a system, but I need to handle the back button better. At the moment, when the user is editing a customer, they would naturally expect that clicking the back button would take them back to the list they came from, but it doesn't, at the moment it takes them back to whatever route they came from before. But the edit environment for the customer isn't a different route, it's just a different part of the template, displayed using v-if/v-else. How can I get the back button to work as desired? Do I need to use history.pushState somehow? I know that I can probably control where the user goes by the use of a navigation guard, but this seems like the wrong approach to me.

LATER: In response to Richard Matsen's suggestion below, I've thought of another way to do this which doesn't require as much refactoring. I've been going about this the wrong way. I should always be thinking in terms of routes, if I want the back (and forward) buttons to work as I want them, so if I want the user to be able to go back to the list, I have to push the edit state on to the history so they can back out of it. But different routes can use the same component. Instead of directly changing 'editMode' in the component methods for when the user selects a customer row, or completes a customer edit, I should instead use router.push with a parameter, and have a watch (or beforeRouteUpdate navigation guard) which sets 'editMode' in response to the route change, with the parameter passed. That way a move to edit mode is a route change (which the user can go back from), even though it's using the same component. I think this should work - I'll have a play.

1 Answer 1

2

I recently changed a sub-component display from v-if to child routes (for purposes of webpack lazy loading, but that's another story).

It used to be

<div>
   <sub-component v-if="showIt"></sub-component>
</div>

Now the template is

<div>
  <router-view></router-view>
</div>

and the child routes are configured like so

const routes = [
  { 
    path: '/maincomponent', name: 'MainComponent', component: MainComponent,
    children: [{ path: '/subcomponent', name: 'SubComponent', component: SubComponent }] 
  },

The sub component route is activated from a method using

this.$router.push('subcomponent')

and deactivated with

this.$router.push('maincomponent')

I can confirm the browser back button works to take the page back, and sub component is 'inserted' into the page a it was with v-if.

3
  • Ah, now that is interesting! I've never really looked at router-view, except in my top-level App.vue - I have never considered nesting it. That looks like a good way to do this.
    – John Moore
    Commented Sep 24, 2017 at 9:29
  • Me neither, I was trying to break up the webpack chunks and to do it you need to de-reference subcomponents and child routes was the way to do that. Commented Sep 24, 2017 at 10:38
  • I've edited my question to add an approach inspired by Richard Matsen's suggestion above.
    – John Moore
    Commented Sep 24, 2017 at 14:41

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.