After receiving feedback on my previous comment, I decided to take a different approach instead of attempting to map a modal to a specific route. I created a demo using Vue 2 and the CLI to showcase this implementation.
When navigating to either the /
or /visitors
routes, the Visitors component/page will be displayed. By clicking the 'Login' button, you can trigger the modal to open.
If you specifically type in the route /visitors/login
in the browser's address bar, the modal will be displayed on top of the Visitors page.
router/index.js
import Vue from 'vue'
import VueRouter from 'vue-router'
Vue.use(VueRouter)
import Visitors from '../Visitors.vue'
const routes = [
{
path: '/',
redirect: 'visitors'
},
{
name: 'visitors',
path: '/visitors/:modal?',
component: Visitors,
props: true
}
]
export default new VueRouter({
mode: 'history',
base: process.env.BASE_URL,
routes
})
App.vue
<template>
<div id="app" class="container">
<router-view></router-view>
</div>
</template>
<script>
export default {
name: 'App',
components: {
},
data() {
return {
}
}
}
</script>
Visitors.vue
<template>
<div class="visitors">
<h4>Visitors</h4>
<div class="row">
<div class="col-md-4">
<button class="btn btn-secondary" @click="showModal">Login</button>
</div>
</div>
<login-modal v-if="displayLogin" @login-event="login" @close-modal-event="hideModal" />
</div>
</template>
<script>
import LoginModal from './LoginModal.vue';
export default {
components: {
LoginModal
},
props: {
modal: {
type: String,
required: false
}
},
data() {
return {
displayLogin: false
}
},
methods: {
showModal() {
this.displayLogin = true;
},
hideModal() {
this.displayLogin = false;
},
login(user) {
this.hideModal();
// Process login
console.log(user);
}
},
created() {
if (this.$route.params.modal) {
if (this.$route.params.modal === 'login') {
this.displayLogin = true;
}
}
}
}
</script>
LoginModal.vue
<template>
<div class="login-modal">
<div class="modal" tabindex="-1" role="dialog">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">Login</h5>
<button type="button" @click="closeModal">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
<form @submit.prevent="login">
<div class="form-group">
<label for="username">User Name</label>
<input type="email" class="form-control" id="username" v-model="user.name">
</div>
<div class="form-group">
<label for="password">Password</label>
<input type="password" class="form-control" id="password" v-model="user.password">
</div>
</form>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-primary" @click="login">Login</button>
<button type="button" class="btn btn-secondary" @click="closeModal">Close</button>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
export default {
data() {
return {
user: {
name: '',
password: ''
}
}
},
methods: {
closeModal() {
this.$emit('close-modal-event');
},
login() {
this.$emit('login-event', this.user)
}
}
}
</script>
<style scoped>
/* Override default value of 'none' */
.modal {
display: block;
}
</style>