返回

多选标签组件:轻松实现Vue3+TypeScript中的多选功能

前端

前言

欢迎来到“每周一个小组件”系列文章的第一篇,在这个系列中,我将分享一些使用Vue3和TypeScript构建的小组件。本周,我们将创建一个多选标签组件。

组件的基本结构

首先,我们来了解一下多选标签组件的基本结构。组件的HTML结构如下:

<template>
  <div class="multi-select">
    <label v-for="option in options" :key="option.value">
      <input type="checkbox" :value="option.value" @change="handleChange">
      <span>{{ option.label }}</span>
    </label>
  </div>
</template>

在这个模板中,我们创建了一个<div>容器来包含标签,然后使用<label>元素来创建每个标签。每个<label>元素包含一个<input>元素和一个<span>元素,<input>元素是一个复选框,<span>元素用于显示标签的文本。

组件的脚本部分如下:

import { defineComponent } from 'vue'

export default defineComponent({
  props: {
    options: {
      type: Array,
      required: true
    }
  },
  data() {
    return {
      selectedOptions: []
    }
  },
  methods: {
    handleChange(event: Event) {
      const target = event.target as HTMLInputElement
      const value = target.value
      if (target.checked) {
        this.selectedOptions.push(value)
      } else {
        this.selectedOptions = this.selectedOptions.filter(option => option !== value)
      }
    }
  }
})

在脚本部分,我们定义了组件的属性、数据和方法。属性options是一个数组,它包含了标签的数据,每个标签的数据是一个对象,对象中包含了标签的值和文本。数据selectedOptions是一个数组,它保存了当前选中的标签的值。方法handleChange是当标签被点击时触发的事件处理函数,它会根据标签的状态更新selectedOptions数组。

添加样式

接下来,我们来添加一些样式来美化组件。在CSS文件中,我们可以添加以下样式:

.multi-select {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
}

.multi-select label {
  display: flex;
  align-items: center;
  cursor: pointer;
}

.multi-select input {
  margin-right: 5px;
}

.multi-select span {
  user-select: none;
}

.multi-select input:checked + span {
  color: blue;
}

这些样式将使组件看起来更美观,它将标签排列成一行,并使标签可点击。当标签被选中时,标签的文本将变成蓝色。

添加交互

现在,我们已经完成了组件的基本结构和样式,接下来,我们需要添加一些交互来使组件能够正常工作。在组件的脚本部分,我们可以添加以下代码:

mounted() {
  // 初始化选中的标签
  this.selectedOptions = this.options.filter(option => option.selected)
}

这段代码将在组件挂载时初始化选中的标签。它会过滤options数组,只留下那些被标记为选中的标签,并将这些标签的值保存到selectedOptions数组中。

数据绑定

最后,我们需要将组件与Vue实例的数据进行绑定。在Vue实例的模板中,我们可以添加以下代码:

<multi-select :options="options" v-model="selectedOptions"></multi-select>

这段代码将组件的options属性绑定到Vue实例的options数据,并将组件的selectedOptions数据绑定到Vue实例的selectedOptions数据。这样,当Vue实例的optionsselectedOptions数据发生变化时,组件也会相应地更新。

完整示例代码

以下是完整的示例代码:

<template>
  <div class="multi-select">
    <label v-for="option in options" :key="option.value">
      <input type="checkbox" :value="option.value" @change="handleChange">
      <span>{{ option.label }}</span>
    </label>
  </div>
</template>

<script>
import { defineComponent } from 'vue'

export default defineComponent({
  props: {
    options: {
      type: Array,
      required: true
    }
  },
  data() {
    return {
      selectedOptions: []
    }
  },
  methods: {
    handleChange(event: Event) {
      const target = event.target as HTMLInputElement
      const value = target.value
      if (target.checked) {
        this.selectedOptions.push(value)
      } else {
        this.selectedOptions = this.selectedOptions.filter(option => option !== value)
      }
    }
  },
  mounted() {
    // 初始化选中的标签
    this.selectedOptions = this.options.filter(option => option.selected)
  }
})
</script>

<style>
.multi-select {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
}

.multi-select label {
  display: flex;
  align-items: center;
  cursor: pointer;
}

.multi-select input {
  margin-right: 5px;
}

.multi-select span {
  user-select: none;
}

.multi-select input:checked + span {
  color: blue;
}
</style>

您可以将这段代码复制到您的Vue项目中,然后使用<multi-select>组件来创建多选标签。

结语

在本篇文章中,我们学习了如何在Vue3+TypeScript中实现一个多选标签组件。我们从组件的基本结构开始,逐步讲解了如何添加样式、交互和数据绑定,最后提供了一个完整的示例代码。希望这篇文章对您有所帮助,也欢迎您在评论区留言交流。