如何在 vue.js 中使用 v-if 指令在两个组件之间切换?

问题描述

我有两个组件 Register.vue 和 Login.vue ,Register.vue 负责注册它会包含两个标题,例如 Login 和 Signup ,如果用户点击 Register 页面内的 Login 标题,它会自动隐藏 Signup(Register .vue) 组件并显示 Login.vue ,到目前为止它工作正常[Register.vue page when user clicks on Login thing it should opens Login page ]1.[​​After clicking Login heading it opens like this ]2登录页面还有两个标题登录注册如果用户点击注册标题,它将隐藏 login.vue 组件,它应该显示 Register.vue ,它不起作用如何解决这个问题

Register.vue

<template>
<div class="main">
    <div  v-if="flag==true"  class="container">
        <img id="side-img" src="../assets/sideImg.png" alt="notFound" />
        <p id="side-content">Online Book Shopping</p>
        <div class="Box">
            <div class="headings">
               
                <h5 class="signin" v-on:click="flip()" id="login" :class="{ active: isLogin }" @click="isLogin = true">Login</h5>
                <h5 class="signup" id="signup" :class="{ active: !isLogin }" @click="isLogin = false">signup</h5>
            </div>
            <form ref="myForm" @submit.prevent="handlesubmit">
                <div class="fullname">
                    <p>FullName</p>
                    <input type="name" id="name-input" class="nameBox"  required v-model="fullName" autocomplete="off" pattern="[A-Za-z]{3,12}">
                </div>
                <div class="username">
                    <p>EmailID</p>
                    <input type="email" id="Email-input" class="emailBox" autocomplete="off" required v-model="email" pattern="^[a-z0-9._%+-]+@[a-z0-9.-]+\.[a-z]{2,4}$">
                </div>
                <div class="password-section">
                    <p>Password</p>
                    <input :type="password_type" class="password" :class="{'password-visible': isPasswordVisible }" id="passField" v-model="password" pattern="^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[@$!%*?&])[A-Za-z\d@$!%*?&]{6,}$" required>
                    <i class="bi bi-eye-slash" id="togglePassword" @click="togglePassword();"></i>
                </div>
                <div class="mobile">
                    <p>MobileNumber</p>
                    <input type="tel" class="telephone" autocomplete="off" v-model="mobile" id="tel" pattern="^\d{10}$" required>
                </div>
                <button class="btn-section" id="btn" type="submit">Signup</button>
            </form>
        </div>
    </div>
    <Login v-if="flag==false" />
</div>
</template>

<script>
import Login from './Login.vue'
import service from '../service/User'
export default {
    name: 'Register',components: {
        Login
    },data() {
        return {
            fullName: '',email: '',password: '',mobile: '',password_type: "password",isLogin: false,isPasswordVisible: false,flag: true,title: 'Online Book Shopping'
        }
    },methods: {
        flip() {
            this.flag = !this.flag;
        },togglePassword() {
            this.password_type = this.password_type === 'password' ? 'text' : 'password'
            this.isPasswordVisible = !this.isPasswordVisible
        },handlesubmit() {
            let userData = {
                fullName: this.fullName,email: this.email,password: this.password,mobile: this.mobile
            }
            service.userRegister(userData).then(response => {
                if (response.status == 201) {
                    alert("user registered successfully");
                    this.$refs.myForm.reset();
                    this.$router.push('/login');
                }
                return response;
            }).catch(error => {
                alert("invalid credentials");
                return error;
            })
        }
    }
}
</script>

Login.vue


<template>
<div class="main">
    <div  v-if="flag" class="container">
        <img id="side-img" src="../assets/sideImg.png" alt="notFound" />
        <p id="side-content">Online Book Shopping</p>
        <div class="Box">
            <div class="headings">
                <h5 class="signin"  :class="{ active: !isSignup }" @click="isSignup = false">Login</h5>
                <!-- <router-link to="/register">
                    <h5 class="signup"  id="signup" :class="{ active: !isLogin }" @click="isLogin = false">signup</h5>
                </router-link> -->
                <h5 class="signup"   id="signup" v-on:click="flip();" :class="{ active: isSignup }" @click="isSignup = true">signup</h5>
            </div>
            <form @submit.prevent="">
                <div class="username">
                    <p>EmailID</p>
                    <input type="email" id="Email-input" class="emailBox" autocomplete="off" required v-model="email" pattern="^[a-z0-9._%+-]+@[a-z0-9.-]+\.[a-z]{2,4}$">
                </div>
                <div class="password-section">
                    <p>Password</p>
                    <input :type="password_type" class="password" :class="{'password-visible': isPasswordVisible}" id="passField" v-model="password" pattern="^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[@$!%*?&])[A-Za-z\d@$!%*?&]{6,}$" required>
                    <i class="bi bi-eye-slash" id="togglePassword" @click="togglePassword();"></i>
                </div>
                <div class="forget-section">
                    <a href="">Forgot-password</a>
                </div>
                <div class="btn-section">
                    <button type="submit" @click="handlesubmit();" class="login-btn">Login</button>
                </div>
                <div class="seperator">
                    <h5><span>OR</span></h5>
                </div>
                <div class="btn-groups">
                    <button type="button" class="btn btn-primary">Facebook</button>
                    <button type="button" class="btn btn-light">Google</button>
                </div>
            </form>
        </div>
    </div>
    <Register  v-else />
</div>
</template>

<script>
import Register from './Register.vue'
import service from '../service/User'
export default {
    name: 'Login',components:{Register},data() {
        return {
            email: '',isSignup: false,flag:true,}
    },methods: {
          flip() {
            this.flag = !this.flag;
        },handlesubmit() {
            let userData = {
                email: this.email,}
            service.userLogin(userData).then(response => {
                    if(response.status==200){
                    alert("user logged in... ");
                    return response;
                    }
            }).catch(error => {
                alert("invalid credentials");
                return error;
            })
        }
    }
}
</script>

<style lang="scss" scoped>
@import "@/styles/Login.scss";
</style>


console errors


vue.runtime.esm.js?2b0e:619 [Vue warn]: UnkNown custom element: <Register> - did you register the component correctly? For recursive components,make sure to provide the "name" option.

found in

---> <Login> at src/Pages/Login.vue
       <Register> at src/Pages/Register.vue
         <App> at src/App.vue
           <Root>

解决方法

尝试使用异步导入,它会起作用

name:() => import('./path')
,

错误是因为递归组件造成的 Login.vue

<template>
//like this you have to modify
    <div  v-if="flag" class="container"> 
 <h5 class="signup"   id="signup" v-on:click="flip();">
<Register  v-else />
</template>
<script>
 name: 'Login',components:{Register},</script>