Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Modal Dialogs: router-vue get a default component and keeps old component unless new one is set #3041

Closed
osasson opened this issue Nov 27, 2019 · 3 comments

Comments

@osasson
Copy link

@osasson osasson commented Nov 27, 2019

What problem does this feature solve?

I think many developers come to a stage where they want to show modal dialogs, regardless of the previous route they were in, and without using some data model.

As far as I have seen, we have no ability doing so while using the history.

One problem might arise when no default view is given, in which case another property could be added as the default component instead of an empty node.

It is not a breaking change and the complexity of its implementation is hopefully very minor.

What does the proposed API look like?

router-vue becomes 2 more props:

preserve: {
  type: Boolean,
  default: false
},
default: {
  type: Function,
  default: null
}

and instead of setting the cache directly to the component or rendering an empty node:

// render previous view if the tree is inactive and kept-alive
if (inactive) {
  return h(cache[name], data, children)
}

const matched = route.matched[depth]
// render empty node if no matched route
if (!matched) {
  cache[name] = null
  return h()
}

const component = cache[name] = matched.components[name]

use something like

const renderCachedComponent = () => h(cache[name], data, children)

// render previous view if the tree is inactive and kept-alive
if (inactive) {
  return renderCachedComponent()
}

const matched = route.matched[depth]
// render default or empty node if no matched route
if (!matched) {
  cache[name] = props.default
  return cache[name] ? renderCachedComponent() : h()
}

let component = matched.components[name]
if (!component) {
  if (props.preserve && cache[name])
    return renderCachedComponent()
  component = props.default;
}
cache[name] = component;

Its usage would then be:

<template>
  <modal v-if="$route.meta.dialog">
    <router-view name="dialog"/>
  </modal>
  <router-view :default="Home" :preserve="true"/>
</template>
@posva

This comment has been minimized.

Copy link
Member

@posva posva commented Nov 27, 2019

Thank you looking into it but if you want to display a different component or an extra one based on a condition without changing the route, that's something you will have to handle in your code by setting flags on meta and a similar v-if to what you showed. From the router perspective the displayed view must be connected to the current location

@posva posva closed this Nov 27, 2019
@osasson

This comment has been minimized.

Copy link
Author

@osasson osasson commented Nov 27, 2019

@posva Thanks, I guess my example was not thorough enough, so I think you misunderstood me, I actually want to change the route but not change the content of the other views. I hope this example will make it clearer. As you can see, I do not need to define all views for each route, which makes the flow easier in this case, which IMO is not that seldom.

router.ts

const router = new Router({
  mode: 'history',
  base: process.env.BASE_URL,
  routes: [
    { path: '/', component: Home, },
    { path: '/news', component: News, },
    ...
    { path: '/contact', components: { dialog: Contact }, meta: { dialog: true }},
  ],
});

App.Vue

<template>
  <modal v-if="$route.meta.dialog">
    <router-view name="dialog"/>
  </modal>
  ...
  <router-view :default="Home" :preserve="true"/>
  ...
  <footer>
    <router-link to="/contact">Contact</router-link>
  <footer>
</template>
@posva

This comment has been minimized.

Copy link
Member

@posva posva commented Nov 28, 2019

See #703

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
2 participants
You can’t perform that action at this time.