index.vue 1.45 KB
<template>
  <div class="flex gap-2 flex-wrap">
    <el-tag v-for="tag in internalTags" :key="tag" closable @close="removeTag(tag)" size="large">
      {{ tag }}
    </el-tag>

    <el-input v-if="inputVisible" v-model="inputValue" @keyup.enter="addTag" @blur="addTag" size="default" class="w-20"
      placeholder="输入标签" />
    <el-button v-else size="default" @click="inputVisible = true">
      <el-icon>
        <Plus />
      </el-icon>
      新增
    </el-button>
  </div>
</template>

<script setup lang="ts">
import { ref, computed } from 'vue'
import { Plus } from '@element-plus/icons-vue'

const props = defineProps<{
  modelValue?: string[]  // 改为可选
}>()

const emit = defineEmits<{
  'update:modelValue': [value: string[]]
}>()

const inputValue = ref('')
const inputVisible = ref(false)

// 修复:添加默认值
const internalTags = computed({
  get: () => props.modelValue || [],  // 添加默认空数组
  set: (value) => emit('update:modelValue', value)
})

const addTag = () => {
  const tag = inputValue.value.trim()

  // 修复:添加安全检查
  if (!tag) return

  // 修复:确保 internalTags.value 存在
  if (!internalTags.value?.includes(tag)) {
    internalTags.value = [...(internalTags.value || []), tag]
  }

  inputVisible.value = false
  inputValue.value = ''
}

const removeTag = (tag: string) => {
  // 修复:添加安全检查
  internalTags.value = (internalTags.value || []).filter(t => t !== tag)
}
</script>