【问题标题】:Prevent main router-view from changing防止主路由器视图改变
【发布时间】:2021-05-04 19:53:18
【问题描述】:

在我的 Vue 应用程序中,我有一个主要组件,其中有以下路由器视图:

<router-view></router-view>
<div class="modal">
  <router-view name="modal"></router-view>
</div>

我想在多个地方打开特定的路由器链接以打开模式。为了达到这个目的,我通过以下方式制作了一条路线:

{
    path: '/visitors/login',
    props: true,
    components: {
        modal: ModalLogin
    },
    meta: {
        modal: true,
    }
},

通过这种方式,特定的模态被加载到模态路由器视图中。唯一的事情是,当我这样做时,默认的路由器视图会被清除。有没有办法防止默认路由器视图发生变化,所以它会保持活动页面,并且只填充模态路由器视图?

【问题讨论】:

  • 不必将模式映射到路线。你想完成什么?
  • 我正在尝试显示基于路线的模式。因此,如果我单击指向 /visitors/login 的链接,它将在现有页面上打开登录模式,如果您直接转到 url,我更愿意在默认主页上使用模式。
  • 你需要查看nested routes,这就是你要找的概念。

标签: javascript vue.js vue-router


【解决方案1】:

作为对我评论的跟进,我没有尝试将模式映射到路由,而是使用 Vue 2 和 CLI 构建了这个示例实现。

对于/或/visitors的路由,会渲染访问者组件/页面,您可以点击“登录”按钮打开模态。

如果您在浏览器地址栏中输入路由/visitors/login,模式将在访客页面上打开。

路由器/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>

【讨论】:

  • 但是使用这个解决方案只能在访客页面上显示模式,对吧?我想在每一页上展示它。因此,如果您在 /test 上打开它,它会显示 /test 页面,上面有模式。当我在 /bla 上打开它时,同样的故事。
  • 我在那种情况下为/test等添加一个具有相同模式参数实现的路由条目,然后将LoginModal作为子项导入Test.vue等。您可以将登录处理移至一个 mixin 方法,可以添加到任何需要它的组件中。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-01-21
  • 1970-01-01
相关资源
最近更新 更多