Vue多标签输入框

10 篇文章 0 订阅

Vue实现输入框输入多个值

多标签输入框

要求:输入框在失去焦点或者回车的时候生成标签,实现输入框输入多个值的操作

子组件

<template>
<!-- 爷爷盒子 -->
  <div class="grad_father_box">
    <!-- 父盒子 --> 
    <div class="father_box" ref="fatherBox" @click="onclick" :style="{'height': height}" @mousedown="spanMouseDown">
        <!-- 生成的标签 -->
        <div v-for="(item,index) in TagsAll" :key="index" class="spanbox">
            <span class="tagspan">{{item}}</span>
            <span class="span_close" @click="removeTag(index,item)" @mousedown="spanMouseDown">
              <Icon type="md-close" />
            </span>
        </div>
        <!-- 输入框 -->
        <input
            :placeholder="!TagsAll.length ? `请输入${placeholder}` : ''"
            v-model="currentval"
            @keyup.enter="addTags"
            @keyup.delete = "deleteTags"
            @blur="addTags"
            :style="inputStyle"
            class="inputTag"
            ref="inputTag"
            type="text" 
        />
    </div>
  </div>
</template>
 
<script>
export default {
    name: 'inputTags',
    props: {
        initValue: {
            type: String,
            default: '张三,李四'
        },
        placeholder: {
          type: String,
          default: '姓名'
        },
        limit: {
          // 最多生成标签数,这里可以设置最多生成的标签数量
        type: Number,
        },
    },
    data () {
        return {
            currentval: '',
            TagsAll: [],
            inputLength: '',
            height: '32px'
        }
    },
    watch: {
        TagsAll () {
            this.$emit('on-change', this.finall)
        },
        currentval () {
            // 实时改变input输入框宽度,防止输入内容超出input默认宽度显示不全
            this.inputLength = this.$refs.inputTag.value.length * 12 + 50;
        },
    },
    computed: {
        inputStyle () {
            let style = {};
            style.width = `${this.inputLength}px`;
            return style;
        },
        //将生成的数据拼接成字符串,因为我们公司后台需要这种格式的数据。
        finall(){
            return this.TagsAll.join(',')
        }
    },
    mounted() {
        // this.TagsAll = this.initValue;
        this.TagsAll = this.initValue ? this.initValue.split(',') : []
    },
    methods: {
      removeTag (index) {
          this.TagsAll.splice(index, 1)
      },
      spanMouseDown(e) {
        e.preventDefault()
      },
      //回车-- 增加tag
      addTags () {
          this.$refs.fatherBox.style.borderColor= '#dcdee2'
          this.$refs.boxShadow = '0'
          this.height = '32px'
          this.validInput()
         
      },
      // 增加校验规则
      validInput() {
        if(this.currentval){
          if (this.limit && this.TagsAll.length === this.limit) {
              this.$Message.info(`最多可输入${this.limit}个标签`)
              return
          }
          this.TagsAll.push(this.currentval);
          this.currentval = '';
        }
      },
      //键盘删除键删除tag
      deleteTags(){
        if (this.currentval) return
        this.TagsAll.pop()
      },
      onclick() {
        this.validInput()
        this.$nextTick(()=>{
          this.$refs.inputTag.focus();
          this.$refs.fatherBox.style.borderColor= '#57a3f3'
          this.$refs.fatherBox.style.outline = 0
          this.$refs.boxShadow = '0 0 0 2px #57a3f3 0.2'
          this.height = 'auto'
        })
      },

    }
}
</script>
 
<style scoped>
.grad_father_box{
  width: 250px;
  position: relative;
  min-height: 32px;
}
  /* 外层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;
      border-radius: 5px;
      position: absolute;
      width: 100%;
  }
  .father_box:focus{
    border-color: #57a3f3;
    /* outline: 0; */
    box-shadow: 0 0 0 2px #57a3f3 0.2;
  }

  /* 标签 */
  .spanbox {
      margin-right: 5px;
      cursor: pointer;
      display: inline-table;
      background: #e3f2fd;
      padding: 2px 0;
      border: 1px solid transparent;
      border-radius: 2px;
      color: #039be5;
      font-size: 12px;
      vertical-align: top;
      padding: 3px;
      margin-bottom: 4px;
      margin-top: 2px;
  }
  .tagspan {
      padding-right: 5px;
  }
  .span_close {
      padding-left: 3px;
      border-left: 2px solid #fff;
  }
  .span_close:hover{
    color: red;
  }
  /* input */
  .inputTag {
      font-size: 12px;
      border: none;
      box-shadow: none;
      outline: none;
      background-color: transparent;
      padding: 0;
      width: auto;
      width: 50px;
      vertical-align: top;
      height: 30px;
      color: #495060;
      line-height: 30px;
      display: inline-block;
  }
</style>
 

父组件

<template>
  <div class="hello">
    <h1>自定义输入框</h1>
    <div class="prop-box">
    <jade-input @on-change="getValue" :initValue="label" :limit="5"></jade-input>
    </div>
    <Button type="primary" style="margin-top: 10px">頂頂頂</Button>
  </div>
</template>

<script>
import jadeInput from './jade-input.vue'
export default {
  name: 'HelloWorld',
  props: {
    msg: String
  },
  components: {
    jadeInput
  },
  data() {
    return {
      label: '张三,李四,王五,赵六'
    }
  },
  methods: {
    getValue(val) {      
      console.log(val, 666);
    }
  }
}
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
.prop-box{
  display: flex;
  justify-content: center;

}
</style>

聚焦输入状态

在这里插入图片描述

失焦状态

在这里插入图片描述

  • 1
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值