当前位置:首页 > VUE

vue简单实现picker效果

2026-02-20 21:53:27VUE

实现基础 Picker 组件

使用 Vue 的 v-model 和事件绑定实现基础选择器。以下是一个基于原生下拉菜单的简单实现:

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

<script>
export default {
  props: {
    options: {
      type: Array,
      default: () => []
    }
  },
  data() {
    return {
      selectedValue: ''
    }
  },
  methods: {
    handleChange() {
      this.$emit('change', this.selectedValue)
    }
  }
}
</script>

自定义样式 Picker

通过 CSS 隐藏原生 <select> 元素,用 <div> 模拟选择器效果:

<template>
  <div class="custom-picker" @click="togglePicker">
    <div class="selected-item">{{ displayValue }}</div>
    <div class="picker-options" v-show="isOpen">
      <div 
        v-for="item in options" 
        :key="item.value" 
        @click="selectItem(item)"
      >
        {{ item.label }}
      </div>
    </div>
  </div>
</template>

<script>
export default {
  props: {
    options: Array,
    value: [String, Number]
  },
  data() {
    return {
      isOpen: false,
      selectedValue: this.value
    }
  },
  computed: {
    displayValue() {
      const selected = this.options.find(item => item.value === this.selectedValue)
      return selected ? selected.label : '请选择'
    }
  },
  methods: {
    togglePicker() {
      this.isOpen = !this.isOpen
    },
    selectItem(item) {
      this.selectedValue = item.value
      this.$emit('input', item.value)
      this.isOpen = false
    }
  }
}
</script>

<style>
.custom-picker {
  position: relative;
  border: 1px solid #ccc;
  padding: 8px;
  cursor: pointer;
}
.picker-options {
  position: absolute;
  top: 100%;
  left: 0;
  right: 0;
  background: white;
  border: 1px solid #eee;
  z-index: 10;
}
.picker-options div {
  padding: 8px;
}
.picker-options div:hover {
  background: #f5f5f5;
}
</style>

使用第三方库实现

对于更复杂的需求,可以使用现成的 Vue Picker 组件库:

vue简单实现picker效果

  1. 安装 vant 库:

    npm install vant
  2. 使用 Picker 组件:

    vue简单实现picker效果

    
    <template>
    <van-picker
     v-model="currentValue"
     :columns="columns"
     @change="onChange"
    />
    </template>
import { Picker } from 'vant'

export default { components: {

}, data() { return { currentValue: '', columns: ['杭州', '宁波', '温州', '嘉兴', '湖州'] } }, methods: { onChange(picker, value, index) { console.log(当前值:${value}, 当前索引:${index}) } } }

```

移动端优化实现

针对移动端添加触摸事件和动画效果:

<template>
  <div class="mobile-picker">
    <div class="picker-mask" v-show="visible" @click="hide"></div>
    <transition name="picker-slide">
      <div class="picker-panel" v-show="visible">
        <div class="picker-header">
          <button @click="hide">取消</button>
          <button @click="confirm">确定</button>
        </div>
        <div class="picker-content">
          <div class="picker-wheel" ref="wheel">
            <div v-for="(item, index) in data" :key="index">
              {{ item }}
            </div>
          </div>
        </div>
      </div>
    </transition>
  </div>
</template>

<script>
import Hammer from 'hammerjs'

export default {
  props: {
    data: Array,
    value: [String, Number],
    visible: Boolean
  },
  mounted() {
    this.initTouchEvents()
  },
  methods: {
    initTouchEvents() {
      const hammer = new Hammer(this.$refs.wheel)
      hammer.get('pan').set({ direction: Hammer.DIRECTION_VERTICAL })

      hammer.on('panstart panmove panend', (ev) => {
        // 处理触摸滚动逻辑
      })
    },
    hide() {
      this.$emit('update:visible', false)
    },
    confirm() {
      this.$emit('input', this.selectedValue)
      this.hide()
    }
  }
}
</script>

<style>
.picker-slide-enter-active, .picker-slide-leave-active {
  transition: transform 0.3s;
}
.picker-slide-enter, .picker-slide-leave-to {
  transform: translateY(100%);
}
.picker-mask {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background: rgba(0,0,0,0.5);
}
.picker-panel {
  position: fixed;
  bottom: 0;
  left: 0;
  right: 0;
  background: #fff;
}
.picker-header {
  display: flex;
  justify-content: space-between;
  padding: 10px;
  border-bottom: 1px solid #eee;
}
.picker-content {
  height: 200px;
  overflow: hidden;
  position: relative;
}
.picker-wheel {
  transition-timing-function: cubic-bezier(0.23, 1, 0.32, 1);
}
</style>

这些实现方式覆盖了从基础到高级的 Picker 组件需求,可以根据项目具体需求选择合适的方案。

标签: 效果简单
分享给朋友:

相关文章

简单实现vue github

简单实现vue github

实现一个简单的 Vue 项目并上传到 GitHub 创建 Vue 项目 使用 Vue CLI 快速初始化一个 Vue 项目,确保已安装 Node.js 和 npm/yarn。运行以下命令创建项目:…

vue实现吸附效果

vue实现吸附效果

Vue实现吸附效果的方法 吸附效果通常指页面滚动时,某个元素固定在特定位置(如顶部或底部)。以下是几种实现方式: 使用CSS的position: sticky 通过CSS的sticky定位实现吸附效…

vue增删改查简单实现

vue增删改查简单实现

Vue 增删改查简单实现 以下是一个基于 Vue 3 的简单增删改查(CRUD)实现示例,使用 Vue 的 Composition API 和响应式数据管理。 初始化项目 确保已安装 Vue 3…

简单实现vue

简单实现vue

实现一个简易 Vue 框架 以下是一个基于 JavaScript 的简易 Vue 实现,核心功能包括数据响应式、模板编译和依赖收集。 数据响应式 通过 Object.defineProperty…

js实现滚动条效果

js实现滚动条效果

实现滚动条效果的方法 使用原生JavaScript实现滚动条 通过监听滚动事件,可以动态调整滚动条的位置和样式。以下是一个基础实现示例: // 获取DOM元素 const container = d…

vue实现气泡效果

vue实现气泡效果

实现气泡效果的方法 在Vue中实现气泡效果可以通过CSS动画、第三方库或自定义组件完成。以下是几种常见方法: 使用纯CSS动画 通过CSS的@keyframes和transform属性创建气泡上升动…