美文网首页
vue input-tag组件封装

vue input-tag组件封装

作者: wxw_威 | 来源:发表于2023-05-15 17:17 被阅读0次

基于elementUI中的el-input 和 el-tag 组件,封装成一个input-tag组件。

效果:

输入aaa回车或失去焦点自动拼接@qq.com后缀名


1684228601022.png
代码如下:
<template>
  <div class="mail-input-tag" @click="handleTagInput">
    <el-tag
      v-for="(item, index) in tagList"
      :key="index"
      class="mail-tag"
      type="info"
      closable
      @close="handleTagClose(item)"
    >
      {{ item }}
    </el-tag>
    <el-input ref="contentInput" v-model.trim="inputWord" class="mail-input" @change="inputChange" />
  </div>
</template>

<script>
const MailAfter = '@qq.com'
export default {
  // type: 1:邮箱   2:企业微信, 邮箱用','分隔,企业微信用'|'分隔
  // eslint-disable-next-line vue/require-prop-types
  props: ['value', 'type'],
  data() {
    return {
      inputWord: ''
    }
  },
  computed: {
    // eslint-disable-next-line vue/return-in-computed-property
    tagList() {
      return this.value ? this.value.split(this.getSplitString()) : []
    }
  },
  methods: {
    // 点击最外层,input获取焦点
    handleTagInput() {
      this.$refs.contentInput.focus()
    },
    // 移除tag
    handleTagClose(tag) {
      // eslint-disable-next-line prefer-const
      let tagList = this.value.split(this.getSplitString())
      tagList = tagList.filter((item) => {
        return item !== tag
      })
      let resultString = ''
      if (tagList.length > 0) {
        resultString = tagList.join(this.getSplitString())
      } else {
        resultString = ''
      }
      this.$emit('input', resultString)
    },
    // 获取分隔符,通过type去判断
    getSplitString() {
      return this.type === '1' ? ',' : '|'
    },
    // 失去焦点或回车
    inputChange(val) {
      if (!val) {
        return
      }
      if (this.type === '1') {
        // 邮箱
        const valueString = this.value.replace(this.getReg(MailAfter), '')
        const valArr = valueString.split(this.getSplitString())
        if (this.judgementRepeat(valArr, val)) {
          this.alertView('重复数据,请重新添加', 'error')
          // 重新获取焦点
          this.$refs.contentInput.focus()
          return
        }
      } else {
        // 企业微信
        const qwArr = this.value.split(this.getSplitString())
        if (this.judgementRepeat(qwArr, val)) {
          this.alertView('重复数据,请重新添加', 'error')
          // 重新获取焦点
          this.$refs.contentInput.focus()
          return
        }
      }
      // type 1:拼接后缀  2:不拼接
      const mailString = this.type === '1' ? MailAfter : ''
      let resultStr = ''
      if (this.value) {
        resultStr = this.value + this.getSplitString() + val + mailString
      } else {
        resultStr = val + mailString
      }
      this.inputWord = ''
      this.$emit('input', resultStr)
    },
    // 动态获取正则
    getReg(val) {
      return new RegExp(val, 'gi')
    },
    // 判断是否重复
    judgementRepeat(list, key) {
      if (list.length > 0) {
        const filterArr = list.filter(item => {
          return item === key
        })
        return filterArr.length > 0
      } else {
        return false
      }
    },
    // 提示框
    alertView(message, type) {
      this.$message({
        message: message,
        type: type
      })
    }
  }
}
</script>

<style lang="scss" scoped>
.mail-input-tag {
  width: 100%;
  padding: 4px;
  display: flex;
  flex-wrap: wrap;
  border-radius: 4px;
  border: 1px solid #DCDFE6;
}
.mail-tag {
  margin-right: 4px;
  margin-bottom: 4px;
}
.mail-input {
  min-width: 120px;
  flex: 1;
}
.mail-input ::v-deep .el-input__inner {
  border: 0 !important;
}
</style>
组件调用

获取到的数据是字符串

<InputTag v-model="groupForm.mail" :type="groupForm.effectiveChannelType" />

相关文章

网友评论

      本文标题:vue input-tag组件封装

      本文链接:https://www.haomeiwen.com/subject/gytvsdtx.html