上圖:javascript
組件代碼:java
<!-- Created by Locke Ou on 2018/6/20. --> <template> <div> <div class="pp-input-wrapper" :class="{'pp-input-has-focus': hasFocus, 'actived': actived}"> <div class="label" ref="label" :class="{'actived': actived}"><span class="required" v-if="isRequired">*</span>{{label}}</div> <slot></slot> <input :type="type" class="pp-input" @focus="ppFocus" @blur="ppBlur" v-model="model[prop]" @input="oninput"> </div> <div class="error-message" :class="{'actived': isError}">{{errorMessage}}</div> </div> </template> <script> export default { data () { return { hasFocus: false, actived: false, isError: false, errorMessage: 'Something Wrong' } }, props: { // label描述 label: { type: String }, // 父組件傳進來的model model: { type: Object, default: function () { return {} } }, // 要修改父組件model的字段名稱 prop: { type: String }, // input的type設置 type: { type: String, default: 'text' }, // label的X軸偏移 x: { type: String, default: '0' }, // 檢查規則 validate: { type: Function, default: function (n) { if (n) { return true } else { return false } } }, // 是否顯示紅色星號 isRequired: { type: Boolean, default: false } }, methods: { ppFocus () { this.hasFocus = true }, ppBlur () { if (this.model[this.prop]) { if (!this.validate(this.model[this.prop])) { this.errorMessage = 'Please type in 11 digit numbers' this.isError = true } else { this.isError = false } return } this.isError = false this.hasFocus = false }, oninput () { if (this.validate(this.model[this.prop])) { this.actived = true } else { this.actived = false } } }, mounted () { const x = this.x / 100 this.$refs.label.style.transform = `translate3d(${x}rem, 0.4rem, 0)` } } </script> <style lang="stylus" scoped> .pp-input-wrapper position relative border-bottom: 1px solid #C1CCD5; padding-bottom: 0.18rem &.actived border-bottom: 1px solid #6308C7; .label transition: transform 150ms ease-in-out transform: translate3d(0, 0.4rem, 0); transform-origin: left top; width: auto; max-width: 100%; pointer-events: none; font-size 0.28rem padding-bottom 0.08rem color: #6F7B85; &.actived color: #6308C7; .pp-input border: none height 0.4rem font-size 0.28rem outline: none; .pp-input-has-focus > .label transform: translate3d(0, 0, 0) scale(0.8) !important; .error-message background url('../../assets/images/Warning.png') no-repeat left center background-size 0.32rem 0.32rem padding: 0.1rem 0 padding-left: 0.42rem color: #F44E4E; font-family: Avenir-Medium; font-size 0.22rem opacity 0 &.actived opacity 1 .required color: #F44E4E </style>
用法:git
先註冊組件app
import ppInput from '@/components/pp-input'
components:{
ppInput
}
<pp-input label="One Time Code" :model="form" prop="test2" type="number" class="code">
</pp-input>
<pp-input label="Mobile Number" :model="form" prop="test" type="tel" x="120" :validate="validateMoblie"> <div class="country-code" @click="aaa">+234 ∨</div> <div class="send-code" @click="sendCode">{{sendCodeText}}</div></pp-input>組件裏面添加了slot插槽,能夠在插入一些本身須要的按鈕或者其餘東西。樣式和方法在父組件定義便可,組件裏的errorMessage能夠單獨提出來,我還沒寫。其餘能夠再按需求再拓展下。