Selaa lähdekoodia

tags-input组件代码提交

liuyao 1 vuosi sitten
vanhempi
commit
5b0781e40e

+ 284 - 0
src/components/base/dk-tags-input/dk-tags-input.vue

@@ -0,0 +1,284 @@
+<!--
+ * @Author: 刘尧
+ * @Date: 2024-08-09 13:33:39
+ * @LastEditors: Please set LastEditors
+ * @LastEditTime: 2024-08-12 15:22:24
+-->
+<template>
+    <div class="content-view">
+        <div class="input-view">
+            <div v-if="tagValues.length > 0" style="max-width:50%;white-space:nowrap;display:flex;">
+                <Tag v-for="(item, index) in tagOrderValues" class="pop-tag-class" :key="index"
+                    :closable="tagValues.length <= 2" @on-close="handleClose(index)">
+                    {{ item }}</Tag>
+            </div>
+            <Poptip popper-class="input-popper-class" ref="pop" transfer trigger="focus" placement="top-start"
+                v-model="visible" :disabled="!visible">
+                <Input v-model="inputValue" size="small" ref="input" :border="false" :disabled="disabled" placeholder="按Enter键结束输入" @on-blur="handleBlur"
+                    @on-focus="handleFocus" @on-enter="inputEnter" @dblclick.native="copyValue()"
+                    style="width: auto;min-width:10%;" />
+                <div slot="content" class="pop-content">
+                    <Tag v-for="(item, index) in tagValues" class="tag-class" :key="index" closable
+                        @on-close="handleClose(index)">
+                        {{ item }}</Tag>
+                </div>
+            </Poptip>
+        </div>
+    </div>
+</template>
+
+<script>
+export default {
+    name: 'DkTagsInput',
+    inject: {
+        prop: {
+            type: String,
+            default: null
+        },
+        required: {
+            type: Boolean,
+            default: false
+        },
+        dkFormItem: {
+            type: Object,
+            default: null
+        }
+    },
+    props: {
+        //input值
+        value: {
+            type: String,
+            default: ''
+        },
+        // 以下为iview 中input组件原本参数
+        type: {
+            type: String,
+            default: 'text'
+        },
+        size: {
+            type: String
+        },
+        placeholder: {
+            type: String
+        },
+        clearable: {
+            type: Boolean,
+            default: false
+        },
+        border: {
+            type: Boolean,
+            default: false
+        },
+        maxLength: {
+            type: Number
+        },
+        disabled: {
+            type: Boolean,
+            default: false
+        }
+    },
+    data() {
+        return {
+            inputValue: '',// 输入框输入值
+            tagValues: [],// tag组件显示值
+            tagStrings: '',// 存储值
+            visible: false,
+            tagOrderValues: []//tag显示组件
+        }
+    },
+    watch: {
+        value(n, o) {
+            if (n == null || n == 'null' || n == undefined) {
+                this.tagStrings = ''
+            } else {
+                this.tagStrings = n
+            }
+        },
+    },
+    mounted() {
+
+    },
+    created() {
+        this.updateTagValues(this.value)
+    },
+    methods: {
+        /**
+         * @desc   : 复制单元格
+         * @author : 周兴
+         * @date   : 2022/6/9 9:31
+         */
+        copyValue() {
+            if (this.tagStrings) {
+                this.$message.success(vm.$t('copySuccess') + ':' + this.tagStrings);
+                //创建一个input框
+                const input = document.createElement("input");
+                input.setAttribute("style", "z-index:-1000;position: absolute;bottom:0;")
+                //将指定的DOM节点添加到body的末尾
+                document.body.appendChild(input);
+                //设置input框的value值为直播地址
+                input.setAttribute("value", this.tagStrings);
+                //选取文本域中的内容
+                input.select();
+                //copy的意思是拷贝当前选中内容到剪贴板
+                //返回值为一个Boolean,如果是 false 则表示操作不被支持或未被启用
+                if (document.execCommand("copy")) {
+                    document.execCommand("copy");
+                }
+            }
+        },
+        /**
+         * @desc   : tag关闭事件
+         * @author : 刘尧
+         * @date   : 2024/8/9 15:45
+         */
+        handleClose(index) {
+            let tagValues = this.tagValues.filter((res, resIndex) => resIndex != index)
+            let tagOrderValues = this.tagOrderValues.filter((res) => res != this.tagValues[index])
+            console.log('tagValues', tagValues)
+            this.tagValues = tagValues
+            if (tagValues.length <= 2) {
+                this.tagOrderValues = tagValues
+            }
+            if (tagOrderValues.length < 2) {
+                this.tagOrderValues = this.tagValues.slice(-2)
+            }
+            let arrString = ''
+            tagValues.forEach(res => {
+                arrString = res + ';'
+            })
+            this.tagStrings = arrString
+            this.$emit('input', this.tagStrings.trim())
+        },
+        /**
+         * @desc   : 光标离开事件
+         * @author : 刘尧
+         * @date   : 2024/8/9 15:45
+         */
+        handleBlur(e) {
+            this.visible = false;
+            if (this.inputValue && this.inputValue != '') {
+                this.updateTagValues(this.inputValue)
+            }
+        },
+        /**
+         * @desc   : 焦点移入事件
+         * @author : 刘尧
+         * @date   : 2024/8/9 15:45
+         */
+        handleFocus(e) {
+            console.log('handleFocus');
+            this.setPopVisible();  //设置tip是否可见
+        },
+        /**
+         * @desc   : 设置pop是否可见
+         * @author : 刘尧
+         * @date   : 2024/8/9 15:45
+         */
+        setPopVisible() {
+            if (this.maxLength && this.tagValues.length > this.maxLength) {
+                this.visible = true;
+                // 设置pop的宽度
+                this.setPopWidth();
+            } else {
+                this.visible = false;
+            }
+        },
+        /**
+         * @desc   : 设置pop的宽度
+         * @author : 周兴
+         * @date   : 2023/11/17 8:31
+         */
+        setPopWidth() {
+            let inputWidth = this.$refs['input'].$el.offsetWidth;
+            if (inputWidth < 200) {
+                this.popWidth = '200px';
+            } else {
+                this.popWidth = inputWidth + 'px';
+            }
+        },
+        /**
+         * @desc   : 更新tag显示内容
+         * @author : 刘尧
+         * @date   : 2024/8/9 15:45
+         */
+        updateTagValues(stringValue) {
+            if (stringValue && stringValue != ' ') {
+                if (this.tagStrings === '') {
+                    this.tagStrings = stringValue
+                } else {
+                    this.tagStrings = this.tagStrings + ';' + stringValue
+                }
+            }
+            this.tagValues = this.tagStrings.split(';').filter(item => item != '')
+            if (this.tagValues.length <= this.maxLength) {
+                this.tagOrderValues = this.tagValues
+            } else {
+                this.tagOrderValues = this.tagValues.slice(-2)
+            }
+            this.inputValue = ''
+            this.$emit('input', this.tagStrings.trim())
+        },
+        /**
+         * @desc   : 回车事件调用
+         * @author : 刘尧
+         * @date   : 2024/8/9 15:45
+         */
+        inputEnter(text) {
+            this.updateTagValues(this.inputValue)
+        },
+    }
+}
+</script>
+
+<style scoped>
+.content-view {
+    width: calc(100% - 16px) !important;
+    display: flex;
+    justify-content: center;
+    align-items: center;
+    border: 1px solid #dcdee2;
+}
+
+.content-view:hover {
+    border: 1px solid #2d8cf0;
+}
+
+.input-view {
+    width: 100%;
+    display: flex;
+    flex-direction: row;
+    justify-content: start;
+    align-items: center;
+}
+
+.input-view >>> .ivu-poptip{
+    width: 100%;
+}
+
+/deep/ .ivu-poptip-rel{
+    width: 100%;
+}
+
+.ivu-input-wrapper{
+    width: 100% !important;
+}
+
+.pop-tag-class {
+    display: flex;
+    align-items: center;
+    max-width: 100%;
+    /* 隐藏超出部分 */
+    overflow: hidden;
+}
+
+.pop-tag-class>>>.ivu-tag-text {
+    /* 使文本占据剩余空间 */
+    flex: 1;
+    /* 防止换行 */
+    white-space: nowrap;
+    /* 隐藏超出部分 */
+    overflow: hidden;
+    /* 超出部分显示省略号 */
+    text-overflow: ellipsis;
+}
+</style>

+ 8 - 0
src/components/base/dk-tags-input/index.js

@@ -0,0 +1,8 @@
+/*
+ * @Author: 刘尧
+ * @Date: 2024-08-09 13:39:03
+ * @LastEditors: 
+ * @LastEditTime: 2024-08-09 13:39:03
+ */
+import DkTagsInput  from './dk-tags-input.vue'
+export default DkTagsInput;

+ 3 - 0
src/main.js

@@ -186,6 +186,9 @@ import DkTree from '_c/table/dk-tree'
 
 Vue.component('DkTree', DkTree)
 
+import DkTagsInput from '_c/base/dk-tags-input'
+Vue.component('DkTagsInput', DkTagsInput)
+
 import PrependTransparent from '_c/base/prepend-transparent'
 Vue.component('PrependTransparent', PrependTransparent)