这是使用 Vue 制作的信用卡制卡表单,该表单的交互设计出色,除了表单之外,还有一张示例卡,在表单里输入任何信息,如卡号、持有人、到期日等,都会有动画框聚焦到示例卡的对应区域,让用户更清楚的知道当前输入的是什么信息,在银行信用卡申请页面展示是一个很好的选择。
查看效果:Vue制作良好交互的信用卡表单演示
制作过程
1、HTML
<div class="wrapper" id="dowebok">
<div class="card-form">
...
<div class="card-form__inner">
<div class="card-input">
<label for="cardNumber" class="card-input__label">信用卡号码</label>
<input type="text" id="cardNumber" class="card-input__input" v-mask="generateCardNumberMask"
v-model="cardNumber" v-on:focus="focusInput" v-on:blur="blurInput" data-ref="cardNumber"
autocomplete="off">
</div>
<div class="card-input">
<label for="cardName" class="card-input__label">持有者姓名</label>
<input type="text" id="cardName" class="card-input__input" v-model="cardName"
v-on:focus="focusInput" v-on:blur="blurInput" data-ref="cardName" autocomplete="off">
</div>
<div class="card-form__row">
<div class="card-form__col">
<div class="card-form__group">
<label for="cardMonth" class="card-input__label">到期日</label>
<select class="card-input__input -select" id="cardMonth" v-model="cardMonth"
v-on:focus="focusInput" v-on:blur="blurInput" data-ref="cardDate">
<option value="" disabled selected>月</option>
<option v-bind:value="n < 10 ? '0' + n : n" v-for="n in 12"
v-bind:disabled="n < minCardMonth" v-bind:key="n">
{{n < 10 ? '0' + n : n}}
</option>
</select>
<select class="card-input__input -select" id="cardYear" v-model="cardYear"
v-on:focus="focusInput" v-on:blur="blurInput" data-ref="cardDate">
<option value="" disabled selected>年</option>
<option v-bind:value="$index + minCardYear" v-for="(n, $index) in 12" v-bind:key="n">
{{$index + minCardYear}}
</option>
</select>
</div>
</div>
<div class="card-form__col -cvv">
<div class="card-input">
<label for="cardCvv" class="card-input__label">校验码</label>
<input type="text" class="card-input__input" id="cardCvv" v-mask="'####'" maxlength="4"
v-model="cardCvv" v-on:focus="flipCard(true)" v-on:blur="flipCard(false)"
autocomplete="off">
</div>
</div>
</div>
<button class="card-form__button">提 交</button>
</div>
</div>
</div>
2、CSS
CSS 代码我们也只展示表单部分:
...
.card-form {
max-width: 570px;
margin: auto;
width: 100%;
}
.card-form__inner {
background: #fff;
box-shadow: 0 30px 60px 0 rgba(90, 116, 148, 0.4);
border-radius: 10px;
padding: 35px;
padding-top: 180px;
}
.card-form__row {
display: flex;
align-items: flex-start;
}
.card-form__col {
flex: auto;
margin-right: 35px;
}
.card-form__col:last-child {
margin-right: 0;
}
.card-form__col.-cvv {
max-width: 150px;
}
.card-form__group {
display: flex;
align-items: flex-start;
flex-wrap: wrap;
}
.card-form__group .card-input__input {
flex: 1;
margin-right: 15px;
}
.card-form__group .card-input__input:last-child {
margin-right: 0;
}
.card-form__button {
width: 100%;
height: 55px;
background: #2364d2;
border: none;
border-radius: 5px;
font-size: 22px;
font-weight: 500;
font-family: "Source Sans Pro", sans-serif;
box-shadow: 3px 10px 20px 0px rgba(35, 100, 210, 0.3);
color: #fff;
margin-top: 20px;
cursor: pointer;
}
...
3、Javascript
JS 代码我们展示全部代码:
new Vue({
el: "#dowebok",
data() {
return {
currentCardBackground: Math.floor(Math.random() * 25 + 1),
cardName: "",
cardNumber: "",
cardMonth: "",
cardYear: "",
cardCvv: "",
minCardYear: new Date().getFullYear(),
amexCardMask: "#### ###### #####",
otherCardMask: "#### #### #### ####",
cardNumberTemp: "",
isCardFlipped: false,
focusElementStyle: null,
isInputFocused: false
};
},
mounted() {
this.cardNumberTemp = this.otherCardMask;
document.getElementById("cardNumber").focus();
},
computed: {
getCardType() {
let number = this.cardNumber;
let re = new RegExp("^4");
if (number.match(re) != null) return "visa";
re = new RegExp("^(34|37)");
if (number.match(re) != null) return "amex";
re = new RegExp("^5[1-5]");
if (number.match(re) != null) return "mastercard";
re = new RegExp("^6011");
if (number.match(re) != null) return "discover";
re = new RegExp('^9792')
if (number.match(re) != null) return 'troy'
return "visa";
},
generateCardNumberMask() {
return this.getCardType === "amex" ? this.amexCardMask : this.otherCardMask;
},
minCardMonth() {
if (this.cardYear === this.minCardYear) return new Date().getMonth() + 1;
return 1;
}
},
watch: {
cardYear() {
if (this.cardMonth < this.minCardMonth) {
this.cardMonth = "";
}
}
},
methods: {
flipCard(status) {
this.isCardFlipped = status;
},
focusInput(e) {
this.isInputFocused = true;
let targetRef = e.target.dataset.ref;
let target = this.$refs[targetRef];
this.focusElementStyle = {
width: `${target.offsetWidth}px`,
height: `${target.offsetHeight}px`,
transform: `translateX(${target.offsetLeft}px) translateY(${target.offsetTop}px)`
}
},
blurInput() {
let vm = this;
setTimeout(() => {
if (!vm.isInputFocused) {
vm.focusElementStyle = null;
}
}, 300);
vm.isInputFocused = false;
}
}
})
到这里就制作完了,如需下载代码,请前往:Vue制作良好交互的信用卡表单
网友评论