当前位置:首页 > VUE

vue实现selected组件

2026-02-18 14:29:02VUE

实现基础下拉选择组件

使用Vue的v-modelv-for指令创建基础下拉选择框。通过select元素绑定值,option元素动态渲染选项列表。

<template>
  <select v-model="selectedValue">
    <option 
      v-for="option in options" 
      :key="option.value" 
      :value="option.value"
    >
      {{ option.label }}
    </option>
  </select>
</template>

<script>
export default {
  data() {
    return {
      selectedValue: '',
      options: [
        { value: '1', label: '选项1' },
        { value: '2', label: '选项2' }
      ]
    }
  }
}
</script>

添加自定义样式和功能

使用div模拟下拉框实现更灵活的样式控制。通过v-show控制下拉列表显示状态,添加点击事件处理展开/收起逻辑。

<template>
  <div class="custom-select">
    <div 
      class="selected-option"
      @click="toggleDropdown"
    >
      {{ selectedLabel }}
      <span class="arrow">▼</span>
    </div>
    <div 
      class="options-list"
      v-show="isOpen"
    >
      <div
        v-for="option in options"
        :key="option.value"
        @click="selectOption(option)"
      >
        {{ option.label }}
      </div>
    </div>
  </div>
</template>

<script>
export default {
  data() {
    return {
      isOpen: false,
      selectedValue: '',
      selectedLabel: '请选择',
      options: [
        { value: '1', label: '选项1' },
        { value: '2', label: '选项2' }
      ]
    }
  },
  methods: {
    toggleDropdown() {
      this.isOpen = !this.isOpen
    },
    selectOption(option) {
      this.selectedValue = option.value
      this.selectedLabel = option.label
      this.isOpen = false
    }
  }
}
</script>

<style>
.custom-select {
  position: relative;
  width: 200px;
}
.selected-option {
  padding: 8px;
  border: 1px solid #ccc;
  cursor: pointer;
}
.options-list {
  position: absolute;
  width: 100%;
  border: 1px solid #ccc;
  max-height: 200px;
  overflow-y: auto;
}
.options-list div {
  padding: 8px;
  cursor: pointer;
}
.options-list div:hover {
  background-color: #f0f0f0;
}
.arrow {
  float: right;
}
</style>

封装为可复用组件

将选择器封装为独立组件,通过props接收选项列表,通过emit事件传递选择结果。

<!-- Select.vue -->
<template>
  <div class="custom-select">
    <div class="selected-option" @click="toggleDropdown">
      {{ selectedLabel || placeholder }}
      <span class="arrow">▼</span>
    </div>
    <div class="options-list" v-show="isOpen">
      <div
        v-for="option in options"
        :key="option.value"
        @click="selectOption(option)"
      >
        {{ option.label }}
      </div>
    </div>
  </div>
</template>

<script>
export default {
  props: {
    options: {
      type: Array,
      required: true
    },
    value: {
      type: [String, Number],
      default: ''
    },
    placeholder: {
      type: String,
      default: '请选择'
    }
  },
  data() {
    return {
      isOpen: false,
      selectedValue: this.value,
      selectedLabel: ''
    }
  },
  methods: {
    toggleDropdown() {
      this.isOpen = !this.isOpen
    },
    selectOption(option) {
      this.selectedValue = option.value
      this.selectedLabel = option.label
      this.$emit('input', option.value)
      this.$emit('change', option)
      this.isOpen = false
    }
  },
  watch: {
    value(newVal) {
      this.selectedValue = newVal
      const selectedOption = this.options.find(opt => opt.value === newVal)
      this.selectedLabel = selectedOption ? selectedOption.label : ''
    }
  }
}
</style>

在父组件中使用

通过v-model绑定选择器值,监听change事件获取完整选项对象。

<template>
  <div>
    <Select 
      v-model="selectedValue"
      :options="options"
      placeholder="选择城市"
      @change="handleChange"
    />
    <p>当前选择的值: {{ selectedValue }}</p>
  </div>
</template>

<script>
import Select from './Select.vue'

export default {
  components: { Select },
  data() {
    return {
      selectedValue: '',
      options: [
        { value: 'bj', label: '北京' },
        { value: 'sh', label: '上海' }
      ]
    }
  },
  methods: {
    handleChange(option) {
      console.log('选择的完整对象:', option)
    }
  }
}
</script>

添加搜索过滤功能

扩展选择器组件,增加搜索框过滤选项功能。

<template>
  <div class="custom-select">
    <div class="selected-option" @click="toggleDropdown">
      {{ selectedLabel || placeholder }}
      <span class="arrow">▼</span>
    </div>
    <div class="options-list" v-show="isOpen">
      <input 
        v-model="searchText"
        class="search-input"
        placeholder="搜索..."
        @click.stop
      />
      <div
        v-for="option in filteredOptions"
        :key="option.value"
        @click="selectOption(option)"
      >
        {{ option.label }}
      </div>
    </div>
  </div>
</template>

<script>
export default {
  props: {
    options: Array,
    value: [String, Number],
    placeholder: String
  },
  data() {
    return {
      isOpen: false,
      selectedValue: this.value,
      selectedLabel: '',
      searchText: ''
    }
  },
  computed: {
    filteredOptions() {
      return this.options.filter(option => 
        option.label.toLowerCase().includes(this.searchText.toLowerCase())
      )
    }
  },
  methods: {
    toggleDropdown() {
      this.isOpen = !this.isOpen
      if (this.isOpen) {
        this.searchText = ''
      }
    },
    selectOption(option) {
      this.selectedValue = option.value
      this.selectedLabel = option.label
      this.$emit('input', option.value)
      this.$emit('change', option)
      this.isOpen = false
    }
  },
  watch: {
    value(newVal) {
      this.selectedValue = newVal
      const selectedOption = this.options.find(opt => opt.value === newVal)
      this.selectedLabel = selectedOption ? selectedOption.label : ''
    }
  }
}
</script>

<style>
.search-input {
  width: 100%;
  padding: 8px;
  box-sizing: border-box;
}
</style>

vue实现selected组件

标签: 组件vue
分享给朋友:

相关文章

vue实现多人视频

vue实现多人视频

实现多人视频通话的Vue方案 使用WebRTC技术结合Vue框架可以构建多人视频通话应用。以下是核心实现方法: 技术栈选择 Vue 2/3作为前端框架 WebRTC用于实时通信 Socket.io…

jquery实现vue

jquery实现vue

jQuery 和 Vue.js 是两种不同理念的前端工具,jQuery 以 DOM 操作和事件驱动为核心,而 Vue.js 是数据驱动的现代化框架。如果想用 jQuery 实现类似 Vue 的功能(如…

vue拖拽实现

vue拖拽实现

Vue 拖拽实现方法 使用 HTML5 原生拖拽 API HTML5 提供了原生拖拽 API,可以通过 draggable 属性、dragstart、dragend、dragover 和 drop 事…

vue实现海报

vue实现海报

Vue 实现海报生成方案 使用 html2canvas 库 html2canvas 是一个将 HTML 元素转换为 Canvas 的库,适合将 Vue 组件渲染为海报图片 安装依赖: npm in…

vue diff实现

vue diff实现

Vue Diff 算法实现原理 Vue 的虚拟 DOM Diff 算法(即 patch 过程)是其高效渲染的核心,主要通过对比新旧虚拟节点的差异,最小化 DOM 操作。以下是关键实现要点: 同层级…

vue computed实现

vue computed实现

计算属性的基本用法 在Vue中,计算属性通过computed选项定义,用于声明依赖于其他属性的动态值。计算属性基于它们的依赖进行缓存,只有依赖发生变化时才会重新计算。 new Vue({ dat…