index.vue 3 KB
<template>
  <view class="zui-input-field">
    <view class="zui-input-field__label">
      <view class="zui-input-field__label-title">
        <text class="zui-input-field__label-text">{{ label }}</text>
        <zui-icon v-if="required" class="zui-input-field__label-asterisk" name="asterisk"></zui-icon>
      </view>
      <text v-if="showError" class="zui-input-field__label-error">{{ errorMessage }}</text>
    </view>
    <view class="zui-input-field__input">
      <zui-input class="zui-input-field__input-input" v-model="model" @input="onInput" :placeholder="placeholder" clearable></zui-input>
      <view v-if="$slots['input-right']" class="zui-input-field__input-right">
        <slot name="input-right"></slot>
      </view>
    </view>
  </view>
</template>

<script>
import ZuiIcon from '../icon';
import ZuiInput from '../input';

export default {
  components: {
    ZuiIcon,
    ZuiInput
  },
  props: {
    value: [String, Number],
    regExp: String,
    label: String,
    required: Boolean,
    placeholder: String,
    errorMessage: String,
  },
  data: function() {
    return {
      model: this.value,
    };
  },
  watch: {
    value: function(val) {
      console.log(val)
      this.model = val;
    }
  },
  computed: {
    showError: function() {
      if (this.regExp) {
        const regExp = new RegExp(this.regExp.replace(/^(\s|\/)+|(\s|\/)+$/g, ''));
        return !regExp.test(this.model);
      } else {
        return !!this.errorMessage;
      }
    }
  },
  methods: {
    onInput: function(value) {
      this.model = value;
      this.$emit('input', value);
    }
  }
}
</script>

<style lang="scss">
.zui-input-field {
  width: 100%;
  position: relative;
  background-color: $color-white;
  &__label {
    display: flex;
    align-items: center;
    justify-content: space-between;
    font-size: $font-md * 0.9;
    color: $color-text-minor;
    padding: $h-gap-sm $v-gap-md 0;
    &-title {
      display: flex;
      align-items: center;
      text-wrap: none;
      white-space: nowrap;
      word-break: break-all;
      box-sizing: border-box;
    }
    &-text {
      color: $color-black;
    }
    &-asterisk {
      color: #FF0000;
      font-size: $font-sm * 0.9;
      padding-left: 10upx;
      padding-bottom: 3upx;
    }
    &-error {
      flex: auto;
      display: flex;
      justify-content: flex-end;
      color: #FF5257;
      padding-left: $v-gap-sm;
    }
  }
  &::after {
  	position: absolute; 
  	content: '';
  	width: 100%;
  	left: 0;
  	bottom: 0;
  	height: 1px;
  	background-color: $color-border;
  	transform: scale(1, 0.5);
  	transform-origin: center bottom;
  }
  &__input {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: $h-gap-sm $v-gap-md;
    box-sizing: border-box;
    &-input {
      flex: auto;
    }
    &-placeholder {
      color: $color-border;
    }
    &-right {
      padding-left: $v-gap-sm;
      text-wrap: none;
      white-space: nowrap;
      word-break: break-all;
      box-sizing: border-box;
    }
  }
}
</style>