input输入框输入内容后回车生成标签组件

最近有一个需求,在input中输入内容后回车生成tag标签,其实这个功能已经有现成的组件库了,但是咱英语不好看不明白文档,还是自己封装一个吧。话不多说,开始。

拿到一个项目或者需求的时候,最好的方式应该是先去构思,最好是整理出一个思维导图,第一步该做什么,第二步做什么,要有一个清晰的轮廓,这样开发起来会更省事。而不是接到需求之后噼里啪啦就开始写。

首先看一下我们要实现的效果

1.用一个父盒子包起来,里面包含一个输入框,和回车后生成的tag标签,便签在前,input输入框在后

2.输入内容后回车--触发事件keyup.enter.

3.对输入框做一个事件监听,将输入的值存在一个数组中。

4.用span标签加css实现生成的标签,样式自定义。

5.在生成的标签上增加删除图标,实现删除功能。

<template>
    <!-- 父盒子 -->
    <div class="father_box" @click="onclick">
        <!-- 生成的标签 -->
        <div v-for="(item,index) in TagsAll" :key="index" class="spanbox">
            <span class="tagspan">{{item}}</span>
            <i class="span_close" @click="removeTag(index,item)"></i>
        </div>
        <!-- 输入框 -->
        <input
            placeholder="请输入,按<回车>以分隔"
            v-model="currentval"
            @keyup.enter="addTags"
            @keyup.delete = "deleteTags"
            :style="inputStyle"
            class="inputTag"
            ref="inputTag"
            type="text" 
        />
    </div>
</template>

<script>
export default {
    name: 'inputTags',
    props: {
        parentArr: {
            type: Array,
            default () {
                return ['我是','默认值']
            }
        },
        limit: { // 最多生成标签数,这里可以设置最多生成的标签数量
			type: Number,
           
        },
        
    },
    data () {
        return {
            currentval: '',
            TagsAll: [],
            inputLength: '',
        }
    },
    watch: {
        TagsAll () {
            this.$emit('on-change', this.TagsAll)
        },
        currentval (val) {
            console.log(val)
            // 实时改变input输入框宽度,防止输入内容超出input默认宽度显示不全
            this.inputLength = this.$refs.inputTag.value.length * 12 + 50;
            
        },
        parentArr () {
            this.TagsAll = this.parentArr.length ? this.parentArr : []
        }
    },
    computed: {
        inputStyle () {
            let style = {};
            style.width = `${this.inputLength}px`;
            return style;
        },
        //将生成的数据拼接成字符串,因为我们公司后台需要这种格式的数据。
        finall(){
            return this.TagsAll.join(',')
        }
    },
    mounted() {
        this.TagsAll = this.parentArr;
    },
    methods: {
        removeTag (index, item) {
            console.log(item)
            this.TagsAll.splice(index, 1)
        },

    //    回车-- 增加tag
        addTags () {
           //新增函数中可以加一些你所需要的校验规则。比如只能是数子,或者不能输入‘,’等
            if(this.currentval){
                this.TagsAll.push(this.currentval);
            this.currentval = '';
            }
            
        },

        //键盘删除键删除tag
        deleteTags(){
           
            this.TagsAll.pop()
        },
        onclick() {
            this.$nextTick(()=>{
                this.$refs.inputTag.focus();
            })
        }
    }
}
</script>

<style>
    /* 外层div */
    .father_box {
        /* width: 300px; */
        box-sizing:border-box;
        background-color: white;
        border: 1px solid #dcdee2;
        border-radius: 4px;
        font-size: 12px;
        text-align: left;
        padding-left: 5px;
        word-wrap: break-word;
        overflow: hidden;
    }
    /* 标签 */
    .spanbox {
        display: inline-block;
        font-size: 14px;
        margin: 3px 4px 3px 0;
        background-color: rgb(229,229,229);
        border: 1px solid #e8eaec;
        border-radius: 3px;
    }
    .tagspan {
        height: 24px;
        line-height: 22px;
        max-width: 99%;
        position: relative;
        display: inline-block;
        padding-left: 8px;
        color: #495060;
        font-size: 14px;
        cursor: pointer;
        opacity: 1;
        vertical-align: middle;
        overflow: hidden;
        transition: 0.25s linear;
        color: rgb(26, 26, 26);
        font-weight: 600;
    }
    .span_close {
        padding: 0 4px 0 4px;
        opacity: 1;
        -webkit-filter: none;
        filter: none;
        color: rgb(26, 26, 26);
        font-weight: 600;
    }
    .span_close:after {
        content: "\00D7";
        -webkit-font-smoothing: antialiased;
        -moz-osx-font-smoothing: grayscale;
        /* line-height: 27px; */
        transition: .3s,color 0s;
    }
    /* input */
    .inputTag {
        font-size: 16px;
        border: none;
        box-shadow: none;
        outline: none;
        background-color: transparent;
        padding: 0;
        width: auto;
        min-width: 250px;
        vertical-align: top;
        height: 32px;
        color: #495060;
        line-height: 32px;
    }
</style>

  • 6
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值