簡體   English   中英

VueJS 模板 - 在登錄表單和注冊表單之間翻轉

[英]VueJS template - Flip between Login Form & Register Form

我正在嘗試在“登錄表單”和“注冊表單”之間切換。 我嘗試使用在 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 作為庫和 Vue 作為框架。 看起來,您實際上是在嘗試使用 Vue 作為庫,所以我相應地更改了代碼,這里是 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;      
}

雖然@Fred 接受了@chr 的回答,但這(仍然)是對 Vue 的誤用。
(請注意,這不是試圖重現工作小提琴,而是回答如何使用更面向 Vue 的方法在“登錄表單”和“注冊表單”之間翻轉的一般問題)

在 Vue 的處理方式中,登錄表單和注冊表單之間的切換應該通過標記完成,使用Vue 條件渲染而不是調用函數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的答案以獲得更通用的方法。

@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;
        },
    },
}

Stephen P 的代碼也工作得很好,而且更整潔,除了第一種形式應該有單引號中的寄存器,即“寄存器”,下面更正了。

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;      
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM