VueJS 模板 - 在登录表单和注册表单之间切换

Posted

技术标签:

【中文标题】VueJS 模板 - 在登录表单和注册表单之间切换【英文标题】:VueJS template - Flip between Login Form & Register Form 【发布时间】:2020-05-09 23:39:45 【问题描述】:

我正在尝试在“登录表单”和“注册表单”之间切换。我尝试使用在 codepen Flat html5/CSS3 Login Form 上遇到的代码。代码工作得很好,但是当我将 HTML 代码集成到 Vue 模板中时,表单不会翻转到“创建帐户”表单。我观察到 javascript 中有一些需要纠正的地方,但我无法准确理解。

我的代码如下:

HTML

<template id="login-page"> // PROBLEM When this Tag is added and called using VueJS component
<div class="login-page">
  <div class="form">
    <form class="register-form">
      <input type="text" placeholder="name"/>
      <input type="password" placeholder="password"/>
      <input type="text" placeholder="email address"/>
      <button>create</button>
      <p class="message">Already registered? <a href="#">Sign In</a></p>
    </form>
    <form class="login-form">
      <input type="text" placeholder="username"/>
      <input type="password" placeholder="password"/>
      <button>login</button>
      <p class="message">Not registered? <a href="#">Create an account</a></p>
    </form>
  </div>
</div>
</template>  // PROBLEM When this Tag is added and called using VueJS component

VueJS

// Vue component: login-page
const LoginPage = 
    template: '#login-page',
    data() 
        return 
            login_message: 'Please enter your credentials to login.',
            loginStage: 'login-form',
            
        ,
    

JavaScript

<script>
$('.message a').click(function()
   $('form').animate(height: "toggle", opacity: "toggle", "slow");
);
</script>

CSS

<style>
@import url(https://fonts.googleapis.com/css?family=Roboto:300);

.login-page 
  width: 360px;
  padding: 8% 0 0;
  margin: auto;

.form 
  position: relative;
  z-index: 1;
  background: #FFFFFF;
  max-width: 360px;
  margin: 0 auto 100px;
  padding: 45px;
  text-align: center;
  box-shadow: 0 0 20px 0 rgba(0, 0, 0, 0.2), 0 5px 5px 0 rgba(0, 0, 0, 0.24);

.form input 
  font-family: "Roboto", sans-serif;
  outline: 0;
  background: #f2f2f2;
  width: 100%;
  border: 0;
  margin: 0 0 15px;
  padding: 15px;
  box-sizing: border-box;
  font-size: 14px;

.form button 
  font-family: "Roboto", sans-serif;
  text-transform: uppercase;
  outline: 0;
  background: #4CAF50;
  width: 100%;
  border: 0;
  padding: 15px;
  color: #FFFFFF;
  font-size: 14px;
  -webkit-transition: all 0.3 ease;
  transition: all 0.3 ease;
  cursor: pointer;

.form button:hover,.form button:active,.form button:focus 
  background: #43A047;

.form .message 
  margin: 15px 0 0;
  color: #b3b3b3;
  font-size: 12px;

.form .message a 
  color: #4CAF50;
  text-decoration: none;

.form .register-form 
  display: none;

.container 
  position: relative;
  z-index: 1;
  max-width: 300px;
  margin: 0 auto;

.container:before, .container:after 
  content: "";
  display: block;
  clear: both;

.container .info 
  margin: 50px auto;
  text-align: center;

.container .info h1 
  margin: 0 0 15px;
  padding: 0;
  font-size: 36px;
  font-weight: 300;
  color: #1a1a1a;

.container .info span 
  color: #4d4d4d;
  font-size: 12px;

.container .info span a 
  color: #000000;
  text-decoration: none;

.container .info span .fa 
  color: #EF3B3A;

body 
  background: #76b852; /* fallback for old browsers */
  background: -webkit-linear-gradient(right, #76b852, #8DC26F);
  background: -moz-linear-gradient(right, #76b852, #8DC26F);
  background: -o-linear-gradient(right, #76b852, #8DC26F);
  background: linear-gradient(to left, #76b852, #8DC26F);
  font-family: "Roboto", sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;      

</style>

【问题讨论】:

看起来你在 Vue 中使用 jQuery,你确定你已经导入了 jQuery 库并且已经设置了 $ 引用吗?最终,它只是通过添加动画来切换 css 属性,如果需要,这可以在没有 jQuery 的情况下轻松完成。 是的,我已经设置了jQuery库。 【参考方案1】:

您混淆了 Vue 作为库和 Vue 作为框架的使用。看起来,您实际上是在尝试使用 Vue 作为库,所以我相应地更改了代码,here is myfiddle。您只需添加一个转换,有关更多信息,请查看文档Enter/Leave & List Transitions。

HTML:

<div id="login-page" class="login-page">
  <div class="form">
    <form class="register-form" v-show="showRegisterForm">
      <input type="text" placeholder="name"/>
      <input type="password" placeholder="password"/>
      <input type="text" placeholder="email address"/>
      <button>create</button>
      <p class="message">Already registered? <a href="#" @click.prevent="toggleForm('login')">Sign In</a></p>
    </form>
    <form class="login-form" v-show="showLoginForm">
      <input type="text" placeholder="username"/>
      <input type="password" placeholder="password"/>
      <button>login</button>
      <p class="message">Not registered? <a href="#" @click.prevent="toggleForm('register')">Create an account</a></p>
    </form>
  </div>
</div>

JS:

new Vue(
  el: '#login-page',
  data() 
      return 
        login_message: 'Please enter your credentials to login.',
        loginStage: 'login-form',
        currentForm: 'login',
      
    ,
  computed: 
        showRegisterForm() 
        return this.currentForm === 'register';
    ,
    showLoginForm() 
        return this.currentForm === 'login';
    ,
  ,
    methods: 
        toggleForm(formName) 
        this.currentForm = formName;
    ,
  ,
);

CSS:

@import url(https://fonts.googleapis.com/css?family=Roboto:300);

.login-page 
  width: 360px;
  padding: 8% 0 0;
  margin: auto;

.form 
  position: relative;
  z-index: 1;
  background: #FFFFFF;
  max-width: 360px;
  margin: 0 auto 100px;
  padding: 45px;
  text-align: center;
  box-shadow: 0 0 20px 0 rgba(0, 0, 0, 0.2), 0 5px 5px 0 rgba(0, 0, 0, 0.24);

.form input 
  font-family: "Roboto", sans-serif;
  outline: 0;
  background: #f2f2f2;
  width: 100%;
  border: 0;
  margin: 0 0 15px;
  padding: 15px;
  box-sizing: border-box;
  font-size: 14px;

.form button 
  font-family: "Roboto", sans-serif;
  text-transform: uppercase;
  outline: 0;
  background: #4CAF50;
  width: 100%;
  border: 0;
  padding: 15px;
  color: #FFFFFF;
  font-size: 14px;
  -webkit-transition: all 0.3 ease;
  transition: all 0.3 ease;
  cursor: pointer;

.form button:hover,.form button:active,.form button:focus 
  background: #43A047;

.form .message 
  margin: 15px 0 0;
  color: #b3b3b3;
  font-size: 12px;

.form .message a 
  color: #4CAF50;
  text-decoration: none;


.container 
  position: relative;
  z-index: 1;
  max-width: 300px;
  margin: 0 auto;

.container:before, .container:after 
  content: "";
  display: block;
  clear: both;

.container .info 
  margin: 50px auto;
  text-align: center;

.container .info h1 
  margin: 0 0 15px;
  padding: 0;
  font-size: 36px;
  font-weight: 300;
  color: #1a1a1a;

.container .info span 
  color: #4d4d4d;
  font-size: 12px;

.container .info span a 
  color: #000000;
  text-decoration: none;

.container .info span .fa 
  color: #EF3B3A;

body 
  background: #76b852; /* fallback for old browsers */
  background: -webkit-linear-gradient(right, #76b852, #8DC26F);
  background: -moz-linear-gradient(right, #76b852, #8DC26F);
  background: -o-linear-gradient(right, #76b852, #8DC26F);
  background: linear-gradient(to left, #76b852, #8DC26F);
  font-family: "Roboto", sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;      

【讨论】:

这符合我的要求。只需要更改 JavaScript 代码的前两行,因为在我的情况下,我有一个现有的 Vue,它调用登录组件,然后激活登录模板。 哦,好吧,我以为你想在没有 jQuery 的情况下使用 Vue。我的错 :),至少我们解决了这个问题。【参考方案2】:

@chr 解决方案对我有用,除了 JavaScript 代码的前两行必须更改,因为在我的情况下,我有一个现有的 Vue,它调用登录组件,然后激活登录模板。

JavaScript

// Vue component: login-page
const LoginPage = 
    template: '#login-page',
    data() 
        return 
            login_message: 'Please enter your credentials to login.',
            currentForm: 'login',
            
        ,
    computed: 
        showRegisterForm() 
            return this.currentForm === 'register';
        ,
        showLoginForm() 
            return this.currentForm === 'login';
            ,
        ,
    methods: 
        toggleForm(formName) 
        this.currentForm = formName;
        ,
    ,

【讨论】:

【参考方案3】:

虽然@Fred 接受了@chr 的回答,但这(仍然)是对 Vue 的误用。 (请注意,这不是试图重现工作小提琴,而是回答如何使用更面向 Vue 的方法在“登录表单”和“注册表单”之间切换的一般问题)

在 Vue 的处理方式中,登录表单和注册表单之间的切换应该使用标记完成,使用 Vue conditional rendering 而不是调用函数 showRegisterForm()showLoginForm()toggleForm 不会不需要参数,因为模型已经知道currentForm 的值是什么。

ifelse 是最简单的方法,利用 Vue 模型中的属性,例如 chr 在他们的回答中引入的 currentForm: 'login'。 HTML 只需稍作改动

<div id="login-page" class="login-page">
  <div class="form">
    <form v-if="currentForm.toLowerCase() === 'register'" class="register-form">
      <input type="text" placeholder="name"/>
      <input type="password" placeholder="password"/>
      <input type="text" placeholder="email address"/>
      <button>create</button>
      <p class="message">Already registered?
          <a href="#" @click.prevent="toggleForm()">Sign In</a></p>
    </form>
    <form v-else class="login-form">
      <input type="text" placeholder="username"/>
      <input type="password" placeholder="password"/>
      <button>login</button>
      <p class="message">Not registered?
          <a href="#" @click.prevent="toggleForm()">Create an account</a></p>
    </form>
  </div>
</div>

这需要的模型的部分查看可能是

const model = new Vue(
    data : 
        'currentForm' : 'login',
        ...
    ,
    ...
    methods : 
        toggleForm() 
            this.currentForm = this.currentForm === 'login' ? 'register' : 'login';
        
    ,
    ...
);

currentForm 的值发生变化时,Vue 将负责更改要显示的表单。

另请参阅问题的答案VueJS - Swap component on click,了解更通用的方法。

【讨论】:

这也行得通并且是一个更简洁的代码,除了第一个表单应该有单引号中的寄存器,即'register'【参考方案4】:

HTML

<div id="login-page" class="login-page">
    <span><h1>currentForm.toUpperCase() FORM</h1></span>
    <span><h5>Please enter your credentials to currentForm.toLowerCase().</h5></span>
    <div class="form">
        <form v-if="currentForm.toLowerCase() === 'register'" class="register-form">
        <input type="text" placeholder="name"/>
        <input type="password" placeholder="password"/>
        <input type="text" placeholder="email address"/>
        <button>create</button>
        <p class="message">Already registered? <a href="#" @click.prevent="toggleForm()">Sign In</a></p>
        </form>
        <form v-else class="login-form">
        <input type="text" placeholder="username"/>
        <input type="password" placeholder="password"/>
        <button>login</button>
        <p class="message">Not registered? <a href="#" @click.prevent="toggleForm()">Create an account</a></p>
        </form>
    </div>
</div>

JavaScript

// Vue component: login-page
const LoginPage = 
    template: '#login-page',
    data() 
        return 
            currentForm: 'login',
            
        ,
    methods: 
        toggleForm()
        
            this.currentForm = this.currentForm === 'login' ? 'register' : 'login';
        
    ,

CSS

@import url(https://fonts.googleapis.com/css?family=Roboto:300);

.login-page 
  width: 360px;
  padding: 8% 0 0;
  margin: auto;

.form 
  position: relative;
  z-index: 1;
  background: #FFFFFF;
  max-width: 360px;
  margin: 0 auto 100px;
  padding: 45px;
  text-align: center;
  box-shadow: 0 0 20px 0 rgba(0, 0, 0, 0.2), 0 5px 5px 0 rgba(0, 0, 0, 0.24);

.form input 
  font-family: "Roboto", sans-serif;
  outline: 0;
  background: #f2f2f2;
  width: 100%;
  border: 0;
  margin: 0 0 15px;
  padding: 15px;
  box-sizing: border-box;
  font-size: 14px;

.form button 
  font-family: "Roboto", sans-serif;
  text-transform: uppercase;
  outline: 0;
  background: #4CAF50;
  width: 100%;
  border: 0;
  padding: 15px;
  color: #FFFFFF;
  font-size: 14px;
  -webkit-transition: all 0.3 ease;
  transition: all 0.3 ease;
  cursor: pointer;

.form button:hover,.form button:active,.form button:focus 
  background: #43A047;

.form .message 
  margin: 15px 0 0;
  color: #b3b3b3;
  font-size: 12px;

.form .message a 
  color: #4CAF50;
  text-decoration: none;


.container 
  position: relative;
  z-index: 1;
  max-width: 300px;
  margin: 0 auto;

.container:before, .container:after 
  content: "";
  display: block;
  clear: both;

.container .info 
  margin: 50px auto;
  text-align: center;

.container .info h1 
  margin: 0 0 15px;
  padding: 0;
  font-size: 36px;
  font-weight: 300;
  color: #1a1a1a;

.container .info span 
  color: #4d4d4d;
  font-size: 12px;

.container .info span a 
  color: #000000;
  text-decoration: none;

.container .info span .fa 
  color: #EF3B3A;

body 
  background: #76b852; /* fallback for old browsers */
  background: -webkit-linear-gradient(right, #76b852, #8DC26F);
  background: -moz-linear-gradient(right, #76b852, #8DC26F);
  background: -o-linear-gradient(right, #76b852, #8DC26F);
  background: linear-gradient(to left, #76b852, #8DC26F);
  font-family: "Roboto", sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;      

【讨论】:

以上是关于VueJS 模板 - 在登录表单和注册表单之间切换的主要内容,如果未能解决你的问题,请参考以下文章

登录注册 页面

使用JavaScript或jquery实现动态交互效果: 点击登录和注册时,可以完成登录和注册tab的切换

在 Silverlight 中实现登录和注册表单动画

如何在 VueJS 文件中添加 Laravel CSRF 令牌? [复制]

登录表单,如何在一个登录表单中使用 3 个表登录?

scss “我们新手?”文字与登录表单上的注册按钮之间的空格