textarea与标签组合,点击标签填入标签内容,再次点击删除内容(vue)

需求:将textarea与span标签组合,点击标签自动填入标签文本内容,再次点击删除标签文本对应内容

原理:点击标签时,将标签内容作为参数,将内容拼接在textarea的value后面,再次点击标签,使用js的replace替换(这里只能替换找到的第一个与标签内容相同的值)

实现代码如下:

<template>
    <div class="relative-element">
        <textarea v-model="myForm.remark" type="textarea" :maxlength="300" placeholder="请输入备注,300字以内"></textarea>
        <div class="bottom-labels" ref="remarkLabels">
            <span title="九零后" @click.stop="autoFillIn('九零后', $event)">九零后</span>
            <span title="小说迷" @click.stop="autoFillIn('小说迷', $event)">小说迷</span>
            <span title="天真无邪" @click.stop="autoFillIn('天真无邪', $event)">天真无邪</span>
            <span title="可爱迷人" @click.stop="autoFillIn('可爱迷人', $event)">可爱迷人</span>
            <span title="帅气逼人" @click.stop="autoFillIn('帅气逼人', $event)">帅气逼人</span>
        </div>
    </div>
</template>
<script>
    export default {
        data() {
            return {
                myForm: {
                    remark: '小说迷 '
                }
            }
        },
        mounted() {
            this.initLabelsCheck(this.myForm.remark);
        },
        methods: {
            // textarea初始化(标签根据内容是否选中)
            initLabelsCheck(remark) {
                if(remark){
                    let remarkArr = remark.split(" ");
                    if(remarkArr.length > 0 && this.$refs.remarkLabels){
                        let labels = this.$refs.remarkLabels.querySelectorAll("span");
                        for(let i=0; i<remarkArr.length; i++){
                            for(let l=0; l<labels.length; l++) {
                                if(remarkArr[i].trim()!=='' && remarkArr[i] === labels[l].getAttribute("title")){
                                    labels[l].classList.add('active');
                                }
                            }
                        }
                    }
                }
            },
            // textarea点击标签自动填入
            autoFillIn(text, event){
                let target = event.target;
                if(target.classList.contains("active")){
                    // 再次点击删除
                    text = text + " ";
                    this.myForm.remark = this.myForm.remark.replace(text, '');
                } else {
                    if(this.myForm.remark.length === 0){
                        this.myForm.remark += text + " ";
                    } else {
                        this.myForm.remark = this.myForm.remark.trim() + " " + text + " ";
                    }
                }
                target.classList.toggle("active");
            }
        }
    }
</script>
<style lang="scss" scoped>
    .relative-element {
        position: relative;
        margin: 30px 40px;
        width: 400px;
        textarea {
            display: block;
            padding: 5px 15px;
            width: 100%;
            height: 150px;
            resize: vertical;
            line-height: 1.5;
            box-sizing: border-box;
            font-size: inherit;
            color: #606266;
            background-color: #fff;
            border: 1px solid #dcdfe6;
            border-radius: 4px;
            transition: border-color .2s cubic-bezier(.645,.045,.355,1);
        }
        .bottom-labels {
            position: absolute;
            left: 10px;
            right: 10px;
            bottom: 3px;
            line-height: 18px;
            background-color: #fff;
            user-select: none;

            span {
                display: inline-block;
                margin: 0 3px;
                padding: 0 6px;
                font-size: 12px;
                background-color: #f3f3f3;
                vertical-align: middle;
                &:hover {
                    cursor: pointer;
                }
                &.active {
                    color: #29e;
                }
            }
        }
    }
</style>
原文地址:https://www.cnblogs.com/yeqrblog/p/9699709.html