Bootstrap

学习路由和弹窗的关系

一、Vue Router

  • 定义路径组件的对应关系。
  • 基于 URL 的变化来渲染不同的组件。
  • 管理导航守卫,实现权限控制。

二、菜单与路由

菜单导航

<!-- 示例:导航菜单:导航到不同的页面,即通过绑定路由,可以实现点击菜单项时,路由发生变化,页面组件随之更新。 -->
<template>
  <nav>
    <router-link to="/">首页</router-link>
    <router-link to="/about">关于我们</router-link>
    <router-link to="/contact">联系我们</router-link>
  </nav>
</template>

路由配置

// router/index.js
import { createRouter, createWebHistory } from 'vue-router';
import Home from '../views/Home.vue';
import About from '../views/About.vue';
import Contact from '../views/Contact.vue';

const routes = [
  { path: '/', component: Home },
  { path: '/about', component: About },
  { path: '/contact', component: Contact },
];

const router = createRouter({
  history: createWebHistory(),
  routes,
});

export default router;

三、弹窗与路由的关系

基于路由的弹窗显示

有时,我们希望在特定的路由下显示弹窗,例如在用户点击某个链接时,弹出一个模态框而不是跳转页面。这可以通过以下方式实现:

  • 使用子路由:将弹窗作为父路由的子组件,当匹配子路由时,显示弹窗。
  • 使用查询参数:根据路由中的查询参数决定是否显示弹窗。

使用子路由显示弹窗:

import { createRouter, createWebHashHistory } from 'vue-router'
import MainContent from '../components/MainContent.vue'
import OtherPage from '../components/OtherPage.vue'
import PopupComponent from '../components/PopupComponent.vue'

const routes = [
  {
    path: '/',
    component: MainContent,
    children: [
      {
        path: 'popup',
        components: {
          popup: PopupComponent
        }
      }
    ]
  },
  {
    path: '/other',
    component: OtherPage
  }
]

const router = createRouter({
  history: createWebHashHistory(),
  routes
})

export default router
//MainContent.vue

<template>
  <div>
    <h1>主内容区域</h1>
    <p>这里是主内容。</p>
    <router-link to="/other">前往其他页面</router-link>
    <button @click="openPopup">打开弹窗</button>

    <!-- 命名视图,用于展示弹窗 -->
    <router-view name="popup"></router-view>
  </div>
</template>

<script>
import { useRouter } from 'vue-router';

export default {
  name: 'MainContent',
  setup () {
    const router = useRouter();

    const openPopup = () => {
      router.push('/popup');
    };

    return {
      openPopup,
    };
  },
};
</script>
//PopupComponent.vue
<template>
  <div class="popup-overlay" @click.self="closePopup">
    <div class="popup-content">
      <h2>弹窗内容</h2>
      <p>这是弹窗的内容。</p>
      <button @click="closePopup">关闭弹窗</button>
    </div>
  </div>
</template>

<script>
import { useRouter } from 'vue-router';

export default {
  name: 'PopupComponent',
  setup () {
    const router = useRouter();

    const closePopup = () => {
      router.back();
    };

    return {
      closePopup,
    };
  },
};
</script>

<style scoped>
.popup-overlay {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background-color: rgba(0, 0, 0, 0.5);
  z-index: 1000;
}

.popup-content {
  position: fixed;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  background: white;
  padding: 20px;
}
</style>
// OtherPage.vue
<template>
  <div>
    <h1>其他页面</h1>
    <p>这是另一个页面的内容。</p>
    <router-link to="/">返回主页面</router-link>
  </div>
</template>

<script>
export default {
  name: 'OtherPage',
};
</script>
说明
  • 当路径为 /modal 时,ModalComponent 将作为子路由显示。
  • Home.vue 中,通过 <router-view> 渲染子组件。
  • 点击关闭按钮时,路由返回到 /,弹窗消失。

使用查询参数控制弹窗:

import { createRouter, createWebHashHistory } from 'vue-router'
import MainContent from '../components/MainContent.vue'

const routes = [
  {
    redirect: "/",
    path: '/',
    component: MainContent
  }
]

const router = createRouter({
  history: createWebHashHistory(),
  routes
})

export default router
// MainContent.vue
<template>
  <div>
    <h1>主内容区域</h1>
    <p>这里是主内容。</p>
    <button @click="openModal">打开弹窗</button>

    <PopupComponent v-if="showModal" @close="closeModal"></PopupComponent>
  </div>
</template>

<script>
import { ref, computed } from 'vue';
import { useRoute, useRouter } from 'vue-router';
import PopupComponent from './PopupComponent.vue';

export default {
  components: { PopupComponent },
  setup () {
    const route = useRoute();
    const router = useRouter();

    const showModal = computed(() => route.query.modal === 'true');

    const openModal = () => {
      router.push({ path: '/', query: { modal: 'true' } });
    };

    const closeModal = () => {
      router.push({ path: '/', query: {} });
    };

    return { showModal, openModal, closeModal };
  },
};
</script>
//PopupComponent.vue
<template>
  <div class="popup-overlay" @click.self="closePopup">
    <div class="popup-content">
      <h2>弹窗内容</h2>
      <p>这是弹窗的内容。</p>
      <button @click="closePopup">关闭弹窗</button>
    </div>
  </div>
</template>

<script>
import { useRouter } from 'vue-router';

export default {
  name: 'PopupComponent',
  setup () {
    const router = useRouter();

    const closePopup = () => {
      router.back();
    };

    return {
      closePopup,
    };
  },
};
</script>

<style scoped>
.popup-overlay {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background-color: rgba(0, 0, 0, 0.5);
  z-index: 1000;
}

.popup-content {
  position: fixed;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  background: white;
  padding: 20px;
}
</style>
说明
  • 使用 useRouteuseRouter 来获取路由信息和进行导航。
  • showModal 计算属性根据查询参数 modal 的值来决定是否显示弹窗。
  • 点击打开和关闭按钮时,修改查询参数,触发视图更新。
;