In my quest to develop a single-page vue.js application using vue-router, I have set the default route (/) as a list of links to other pages resembling a landing page. Currently, all other pages function as dialogs for various scenarios. To simplify creating new dialogs, I devised a base-dialog page that establishes the generic dialog appearance while allowing specific routes to define the details. The three main sections include basic settings, logging settings, and advanced settings. Basic settings are mandatory for each scenario, logging settings remain constant across scenarios, and advanced settings are optional. I leverage named router-views to load the basic and advanced settings.
Prior Investigation
My approach was inspired by this discussion thread.
Code Excerpts
DialogPage.vue
<template>
<div>
<div id="basic-options" class="options">
<router-view name="basicView" basic="true"/>
</div>
<div id="logging-options" class="alt-options">
<!-- Custom components needed for logging options. This renders properly. -->
</div>
<div id="advanced-options" class="alt-options">
<router-view name="advancedView" basic="false"/>
</div>
</div>
</template>
{Scenario}.vue
<template>
<div>
<!-- custom components to set up basic dialogs for {Scenario} -->
</div>
</template>
The file {Scenario}Advanced.vue mirrors {Scenario}.vue but employs different child elements within the div container.
ScenarioSelector.js
/* Import Scenario Here */
import ScenarioA from '@/components/Scenarios/A'
import ScenarioAAdvanced from '@/components/Scenarios/AAdvanced'
import ScenarioB from '@/components/Scenarios/B'
import ScenarioBAdvanced from '@/components/Scenarios/BAdvanced'
/* Add them to the list */
const components =
{
ScenarioA,
ScenarioAAdvanced,
ScenarioB,
ScenarioBAdvanced
}
/* Do not modify anything here */
export default
{
functional: true,
props: [
{
name: 'scenario',
type: String
},
{
name: 'basic',
type: Boolean,
default: true
}
],
render (createElement, context) {
var scenario = context.props.scenario
console.log('Log anything, please')
if (context.props.basic) {
scenario += 'Advanced'
}
return createElement(components[scenario], context.data, context.children)
}
}
Relevant snippet from router/index.js
export default new Router({
routes: [
/* Other routes */,
{
path: "/dialog/:scenario",
component: DialogPage,
props: true,
children:[
{
path: "*",
components: { basicView: ScenarioSelector, advancedView: ScenarioSelector },
props: { basicView: true, advancedView: true }
}
]
}
]
}
The Issue
The render
function in ScenarioSelector
does not seem to be triggered. No logging occurs. There have been instances where it entered the function, but I cannot pinpoint the exact conditions leading to this behavior. Even when executed, no properties are being set.
Alternative Approaches Different route attempts:
export default new Router({
routes: [
/* Other routes */,
{
path: "/dialog/",
component: DialogPage,
props: true,
children:[
{
path: "/:scenario",
components: { basicView: ScenarioSelector, advancedView: ScenarioSelector },
props: { basicView: true, advancedView: true }
}
]
}
]
}
With this setup, the links from the landing page (/dialog/{Scenario}) do not initiate any actions.
export default new Router({
routes: [
/* Other routes */,
{
path: "/dialog/",
component: DialogPage,
props: true,
children:[
{
path: "ScenarioA",
components: { basicView: ScenarioA, advancedView: ScenarioAAdvanced }
},
{
path: "ScenarioB",
components: { basicView: ScenarioB, advancedView: ScenarioBAdvanced }
}
]
}
]
}
Similarly, in this case, the links do not trigger any actions.
Edit
Previously, I mentioned uncertainty about what caused the code execution variations. A simple change from *
to /
in the child path resolved the issue. Example below:
export default new Router({
routes: [
/* Other routes */,
{
path: "/dialog/:scenario",
component: DialogPage,
props: true,
children:[
{
path: "/",
components: { basicView: ScenarioSelector, advancedView: ScenarioSelector },
props: { basicView: true, advancedView: true }
}
]
}
]
}