[vue开发记录]float label输入框

上图:

 

组件代码:

  

<!--
  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>

  

 用法:

 先注册组件

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可以单独提出来,我还没写。其他可以再按需求再拓展下。


 

posted @ 2018-06-20 17:29  小葱葱葱包  Views(496)  Comments(0Edit  收藏  举报