基于elementUI中的el-input 和 el-tag 组件,封装成一个input-tag组件。
效果:
输入aaa回车或失去焦点自动拼接@qq.com后缀名
代码如下:
<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" />