You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何为Laravel Breeze的Vue登录/注册脚手架编写弹窗模态框

Laravel Breeze Vue 登录/注册模态框实现方案

1. 添加模态框触发按钮

在需要展示登录/注册入口的页面(比如导航栏组件resources/js/Layouts/App.vue)中添加触发按钮,并引入模态框组件:

<template>
  <!-- 其他导航内容 -->
  <button @click="showAuthModal = true" class="text-gray-600 hover:text-gray-900">
    登录/注册
  </button>

  <!-- 引入模态框组件 -->
  <LoginRegisterModal v-model="showAuthModal" />
</template>

<script setup>
import { ref } from 'vue';
import LoginRegisterModal from '@/Pages/Modal/LoginRegister.vue';

// 控制模态框显示状态
const showAuthModal = ref(false);
</script>

2. 编写LoginRegister.vue模态框组件

在resources/js/Pages/Modal/LoginRegister.vue中实现带标签页的模态框,整合原有的Login和Register组件:

<template>
  <!-- 模态框遮罩层,点击空白处关闭 -->
  <div 
    v-if="modelValue" 
    class="fixed inset-0 bg-black/50 flex items-center justify-center z-50"
    @click.self="closeModal"
  >
    <!-- 模态框主体 -->
    <div class="bg-white rounded-lg w-full max-w-md shadow-xl relative">
      <!-- 标签页切换 -->
      <div class="border-b">
        <div class="flex">
          <button 
            @click="activeTab = 'login'"
            :class="[
              'px-4 py-3 font-medium',
              activeTab === 'login' ? 'text-blue-600 border-b-2 border-blue-600' : 'text-gray-500 hover:text-gray-700'
            ]"
          >
            Login
          </button>
          <button 
            @click="activeTab = 'register'"
            :class="[
              'px-4 py-3 font-medium',
              activeTab === 'register' ? 'text-blue-600 border-b-2 border-blue-600' : 'text-gray-500 hover:text-gray-700'
            ]"
          >
            Register
          </button>
        </div>
      </div>

      <!-- 关闭按钮 -->
      <button 
        @click="closeModal"
        class="absolute top-3 right-3 text-gray-500 hover:text-gray-700 text-xl"
      >
        ×
      </button>

      <!-- 条件渲染登录/注册组件 -->
      <div class="p-6">
        <LoginComponent v-if="activeTab === 'login'" @close="closeModal" />
        <RegisterComponent v-else @close="closeModal" />
      </div>
    </div>
  </div>
</template>

<script setup>
import { ref, defineProps, defineEmits } from 'vue';
// 引入Breeze自带的登录/注册组件
import LoginComponent from '@/Pages/Auth/Login.vue';
import RegisterComponent from '@/Pages/Auth/Register.vue';

// 接收父组件传递的显示状态
const props = defineProps({
  modelValue: {
    type: Boolean,
    required: true
  }
});

// 向父组件传递关闭事件
const emit = defineEmits(['update:modelValue']);

// 控制当前激活的标签页,默认选中Login
const activeTab = ref('login');

// 关闭模态框的方法
const closeModal = () => {
  emit('update:modelValue', false);
};
</script>

3. 修改原有Login/Register组件的逻辑

因为原组件是页面级的,需要添加关闭模态框的事件触发,同时保留原有表单提交逻辑:

调整Login.vue

在resources/js/Pages/Auth/Login.vue中添加emit事件,登录成功后关闭模态框:

<script setup>
import { useForm } from '@inertiajs/vue3';
import { router } from '@inertiajs/vue3';
import { defineEmits } from 'vue';

const emit = defineEmits(['close']);

const form = useForm({
  email: '',
  password: '',
  remember: false,
});

const submit = async () => {
  if (form.processing) return;

  await form.post(route('login'), {
    onSuccess: () => {
      // 登录成功后关闭模态框
      emit('close');
      // 保留原有的跳转逻辑,比如跳转到仪表盘
      router.visit(route('dashboard'), { replace: true });
    },
    onError: () => {
      // 错误处理保持不变
    },
  });
};
</script>

调整Register.vue

在resources/js/Pages/Auth/Register.vue中做同样的修改:

<script setup>
import { useForm } from '@inertiajs/vue3';
import { router } from '@inertiajs/vue3';
import { defineEmits } from 'vue';

const emit = defineEmits(['close']);

const form = useForm({
  name: '',
  email: '',
  password: '',
  password_confirmation: '',
});

const submit = async () => {
  if (form.processing) return;

  await form.post(route('register'), {
    onSuccess: () => {
      // 注册成功后关闭模态框
      emit('close');
      // 保留原有的跳转逻辑
      router.visit(route('dashboard'), { replace: true });
    },
    onError: () => {
      // 错误处理保持不变
    },
  });
};
</script>

4. 可选:禁用原登录/注册路由

如果你不想让用户通过URL直接访问登录/注册页面,可以在resources/js/routes.js中注释掉对应的路由:

// 注释掉这两行
// { path: '/login', component: () => import('./Pages/Auth/Login.vue') },
// { path: '/register', component: () => import('./Pages/Auth/Register.vue') },

内容的提问来源于stack exchange,提问作者Cam

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.13 17:20:37