Alpine js 获取 "tag input" 作为数组

Alpine js get "tag input" as array

我发现了一个非常酷的带有 alpine js 和 tailwind 的标签输入代码 css。它工作得很好,但是当我尝试用我的表单发送它时,我总是只得到最后一个标签。我想将它们推入一个数组并与表单中的其他元素一起发送,但我不知道该怎么做。这是我使用的标签输入的工作示例:https://codepen.io/atomgiant/pen/QWjWgKz

这是 html 部分:

<div data-tags='[]'
            class="mb-8">
        <div x-data="tagSelect()" x-init="init('parentEl')" @click.away="clearSearch()"
                @keydown.escape="clearSearch()">
            <div class="relative" @keydown.enter.prevent="addTag(textInput)">
                <input x-model="textInput" x-ref="textInput"
                        @input="search($event.target.value)"
                        class="block w-full px-4 py-2 mt-2 rounded bg-gray-200 text-gray-600 border-gray-600 focus:border-blue-500 focus:outline-none focus:ring"
                        placeholder="Enter some tags">
                <div :class="[open ? 'block' : 'hidden']">
                    <div class="absolute z-40 left-0 mt-2 w-full">
                        <div class="py-1 text-sm bg-white rounded shadow-lg border border-gray-300">
                            <a @click.prevent="addTag(textInput)"
                                class="block py-1 px-5 cursor-pointer hover:bg-indigo-600 hover:text-white">Add tag: "<span class="font-semibold"
                                                    x-text="textInput"></span>"</a>
                        </div>
                    </div>
                </div>
                <!-- selections -->
                <template x-for="(tag, index) in tags">
                    <div class="bg-indigo-100 inline-flex items-center text-sm rounded mt-2 mr-1">
                        <span class="ml-2 mr-1 leading-relaxed truncate max-w-xs"
                                x-text="tag"></span>
                        <button @click.prevent="removeTag(index)"
                                class="w-6 h-8 inline-block align-middle text-gray-500 hover:text-gray-600 focus:outline-none">
                            <svg class="w-6 h-6 fill-current mx-auto"
                                    xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
                                <path fill-rule="evenodd"
                                        d="M15.78 14.36a1 1 0 0 1-1.42 1.42l-2.82-2.83-2.83 2.83a1 1 0 1 1-1.42-1.42l2.83-2.82L7.3 8.7a1 1 0 0 1 1.42-1.42l2.83 2.83 2.82-2.83a1 1 0 0 1 1.42 1.42l-2.83 2.83 2.83 2.82z"/>
                            </svg>
                        </button>
                    </div>
                </template>
            </div>
        </div>
    </div>

这是标签输入的JS部分:

function tagSelect() {
    return {
        open: false,
        textInput: '',
        tags: [],
        init() {
            this.tags = JSON.parse(this.$el.parentNode.getAttribute('data-tags'));
        },
        addTag(tag) {
            tag = tag.trim()
            if (tag != "" && !this.hasTag(tag)) {
                this.tags.push( tag )
            }
            this.clearSearch()
            this.$refs.textInput.focus()
            this.fireTagsUpdateEvent()
        },
        fireTagsUpdateEvent() {
            this.$el.dispatchEvent(new CustomEvent('tags-update', {
                detail: { tags: this.tags },
                bubbles: true,
            }));
        },
        hasTag(tag) {
            var tag = this.tags.find(e => {
                return e.toLowerCase() === tag.toLowerCase()
            })
            return tag != undefined
        },
        removeTag(index) {
            this.tags.splice(index, 1)
            this.fireTagsUpdateEvent()
        },
        search(q) {
            if ( q.includes(",") ) {
                q.split(",").forEach(function(val) {
                    this.addTag(val)
                }, this)
            }
            this.toggleSearch()
        },
        clearSearch() {
            this.textInput = ''
            this.toggleSearch()
        },
        toggleSearch() {
            this.open = this.textInput != ''
        }
    }
}

这是我获取表格的地方。我想获取 tags[] 数组中的数据。

function contentUploadModal() {
    return {
        contentForm: {
            title: "",
            content: "",
            public: "",
            tags: [],
            detail: {
            }
        },
        errorMessage: "",
        createSuccess: false,
        sendContentUpload(contentForm) {
            console.log(contentForm)
            this.errorMessage = ""
            this.createSuccess = false
            fetch('/api/content', {
                method: 'POST',
                cache: "no-cache",
                headers: {
                    'Content-Type': 'application/json'
                },
                redirect: "follow",
                body: JSON.stringify(contentForm)
            })
                .then(response => {
                    response.json()
                        .then(json => {
                            if (json['success'] === true) {
                                this.createSuccess = true
                                setTimeout((() => window.location.reload()), 100)
                            } else {
                                this.errorMessage = json['error']
                            }
                        })
                        .catch(() => this.errorMessage = 'Error. Check again!')
                })
                .catch(err => this.errorMessage = 'Unknown error!')
        }
    }
}

容器 div 上有一个内置事件侦听器,当您添加或删除标签时会触发该事件侦听器。您可以在其中放置一个函数,也可以让它设置一个变量。

在你脚本的某处,实例化数组

let myTags = []

然后在你的主容器中设置它

<div x-data @tags-update="myTags= $event.detail.tags" data-tags='[]' class="max-w-lg m-6">

然后在你的表单提交中,捕获函数启动后的值

sendContentUpload(contentForm) {
  contentForm.tags = myTags;    
  console.log('contentForm',contentForm)

唯一需要注意的是,我不知道如何用 myTags 初始化 data-tags。您可以像以前那样对其进行硬编码 (["aaa","bbb"]),但我删除了它。看看我的笔

示例:https://codepen.io/john-tyner/pen/jOBxGNo?editors=1111