[Vuejs]-Prevent main router-view from changing

0👍

As a follow up to my comment, instead of trying to map a modal to a route, I built this sample implementation with Vue 2 and the CLI.

For the routes / or /visitors, the Visitors component/page will be rendered, and you can click the ‘Login’ button to open the modal.

If you enter the route /visitors/login in the browser address bar, the modal will open over 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">&times;</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>

Leave a comment