Vue 开发邮箱输入组件

Email.vue

<template>
  <div class="email2" :class="!!error?'email2__error':''">
    <div class="email-box" ref="email-box">
      <el-tag
        :key="tag"
        size="mini"
        style="margin-right: 2px;margin-bottom: 1px;"
        type="info"
        v-for="tag in activeList"
        closable
        :disable-transitions="false"
        @close="handleClose(tag)">
        {{tag}}
      </el-tag>
      <el-input
        style="width: 180px;"
        size="mini"
        v-model="email"
        ref="saveTagInput"
        @keyup.enter.native="handleInputConfirm"
        @keyup.delete.native="handleDeleteConfirm"
        @blur="handleInputConfirm"
        @input.native="handleInput"
        placeholder="请输入邮箱"
      >
      </el-input>
    </div>
    <div v-if="!!error" class="tip">{{error}}</div>
  </div>
</template>

<script>
import { isEmail } from '@_public/utils'
export default {
  name: 'Email2',
  props: {
    activeList: Array,
    // 邮箱是否必填
    required: {
      type: Boolean,
      default: false
    }
  },
  model: {
    prop: 'activeList',
    event: 'valueEvent'
  },
  created () {
  },
  data () {
    return {
      emailList: [],
      inputVisible: false,
      email: '',
      // 默认点击一次backspace就会从activeList中删除最后一个
      deleteCount: 1,
      error: '',
      isPaste: false
    }
  },
  computed: {
  },
  mounted () {
    this.$refs['email-box'].onclick = function () {
      this.classList.add('email-box--active')
      const input = this.querySelector('input')
      input.focus()

      input.onblur = () => {
        this.classList.remove('email-box--active')
      }
    }

    const me = this
    // 监听粘贴事件
    document.addEventListener('paste', function (event) {
      me.isPaste = true
      let text = (event.clipboardData || window.clipboardData).getData('text')
      let list = text.split(/,|;|,|;/).map(e => e.trim()).filter(e => e && isEmail(e))
      list = Array.from(new Set(me.activeList.concat(list)))
      me.$emit('valueEvent', list)
    })
  },
  methods: {
    handleClose (tag) {
      this.activeList.splice(this.activeList.indexOf(tag), 1)
    },

    handleInput (e) {
      if (this.isPaste) {
        this.error = ''
        this.email = ''
        this.isPaste = false
      } else {
        const s = e.data
        if (s === ',' || s === ',') {
          this.handleInputConfirm()
        }
        this.error = ''
      }
    },

    handleInputConfirm () {
      if (this.required && this.activeList.length === 0 && !this.email) {
        this.error = '请输入邮箱'
      } else {
        this.email && this.validateEmail()
      }
    },

    validateEmail () {
      const email = this.email.trim().replace(/(,$)|(,$)/g, '')

      const isExist = (n) => {
        return this.activeList.some(v => v === n)
      }

      if (isEmail(email)) {
        if (!isExist(email)) {
          this.activeList.push(email)
          this.email = ''
          this.deleteCount = 1
          this.error = ''
        } else {
          this.error = '邮箱已存在'
        }
      } else {
        this.error = '邮箱格式错误'
      }
    },

    handleDeleteConfirm () {
      if (!this.email) {
        if (this.deleteCount === 1) {
          this.activeList.pop()
        } else {
          this.deleteCount -= 1
        }
      }
    },

    /**
     * @function 验证邮箱是否输入通过,没有error就代表通过
     * */
    validation () {
      this.handleInputConfirm()
      return !this.error
    }
  },
  watch: {
    activeList (val) {
      this.$emit('valueEvent', val)
    },
    email (newVal, oldVal) {
      if (!newVal && oldVal.length === 1) {
        // 在email为空后还需点一次backspace才能删除
        this.deleteCount = 2
      }
    }
  }
}
</script>

<style lang="scss">
  .email-box{
    display: flex;
    /*margin-top: 4px;*/
    padding: 1px;
    flex-wrap: wrap;
    border-radius: 5px;
    box-sizing: border-box;
    align-items: center;
    border: 1px solid #d9d9d9;
    min-height: 32px;
    max-height: 160px;
    overflow-y: auto;
    cursor: text;
    &:hover{
      border-color: #bfbfbf;
    }
    div.el-input.el-input--mini {
      flex: auto;
      height: 28px;
    }
    .el-input__inner{
      border: none!important;
    }
  }
  .email-box--active{
    border-color: #268DFF!important;
  }

  .email2 {
    >.tip{
      line-height: 1.5;
      font-size: 12px;
      color: #fa2a31;
    }
    &.email2__error {
      >.email-box {
        border: 1px solid #fa2a31!important;
      }
    }
  }
</style>

utils.js文件中有isEmail方法

export const isEmail = (val) => {
  let regEmail = /^([a-zA-Z0-9]+[_|\-|\.]?)*[a-zA-Z0-9]+@([a-zA-Z0-9]+[_|\-|\.]?)*[a-zA-Z0-9]+\.[a-zA-Z]{2,}$/
  return regEmail.test(val)
}

效果截图
在这里插入图片描述在这里插入图片描述

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值