Vue组件分享|Vue中双向绑定实现的表单选择组件(按钮样式)

写在前面 表单中经常会用到选择框的组件,HTML自带的样式太丑了,第三方的组件也不满足项目的使用需求,而且样式也不好看,于是自己就撸了一个,代码很简单,可以实现单选和多选,且选择后不需要再对选择的数据进行处理。
我写的这个组件是按钮的样式,如果需要图标+文字的哪种,自行更改样式即可。
效果图 Vue组件分享|Vue中双向绑定实现的表单选择组件(按钮样式)
文章图片

选择子组件代码

> // 超出选择限制弹窗提示,请自行引入自己的弹窗 import { toast } from '../../../mixins/popup' export default { props: { // 必传,第一项是name,第二项是value propName: Array, // 非必传,限选项数 limit: { type: Number, default: 999 }, // 非必传,只读属性 readonly: Boolean, // 非必传,图中的红色提示文字 tips: String, // 非必传,默认单选,多选传checkbox type: { type: String, default () { return 'radio' } }, // 非必传,标题 title: String, // 必传,选项数据仅支持数组形式,如[{name: '选项一', value: 1}], // name和value即为propName中的第一个和第二项 options: { type: Array, default: [] }, // 必传,选中的值,支持三种类型,单选可传String、Number类型, // 多选只能传Array类型 value: [String, Array, Number] }, data () { return {} }, computed: { // 处理父组件传过来的数组,与双向绑定的vlaue值比较, // 选中项的要加上selected为true的属性 checkArr () { let checkArr = JSON.parse(JSON.stringify(this.options)) checkArr.forEach(item => { // 默认添加上selected为false的属性 this.$set(item, 'selected', false) // 单选 if (this.type === 'radio') { if (item[this.itemVal] === this.value) { item.selected = true } } else if (this.type === 'checkbox') { // 多选 this.value.forEach(val => { if (item[this.itemVal] === val[this.itemVal]) { item.selected = true } }) } }) return checkArr }, // 选项名,使用computed转换一下,方便处理 itemName () { return this.propName[0] }, // 选项值,使用computed转换一下,方便处理 itemVal () { return this.propName[1] } }, methods: { change (item) { // 只读属性则不可点击 if (this.readonly) return // 选中的值 let value = https://www.it610.com/article/item[this.itemVal] // 单选 if (this.type ==='radio') { this.$emit('input', value) console.log('单选选中的值', value) return } // 多选 if (this.type === 'checkbox') { let newValue = https://www.it610.com/article/JSON.parse(JSON.stringify(this.value)) if (item.selected) { let index = 0 newValue.forEach((newVal, i) => { if (value =https://www.it610.com/article/== newVal[this.itemVal]) { index = i } }) newValue.splice(index, 1) } else { // 超出选择 if (this.value.length === this.limit) { console.log(`最多选择${this.limit}个`) return toast('warn', `最多选择${this.limit}个`) } newValue.push(item) } console.log('多选选中的值', newValue) this.$emit('input', newValue) } } } } ='less' scoped> .selectBtn{ padding: 0 24/75rem; // 标题 h1{ font-size:28/75rem; color:#222222; line-height:28/75rem; background: #fff; padding-top: 30/75rem; display: flex; align-items: cneter; background:#fff; margin-bottom: 6/75rem; &:before { display: inline-block; content: '*'; width: 6/75rem; color: #ff6633; // background: #ff6633; height: 25/75rem; border-radius: 2/75rem; margin-right: 12/75rem; margin-top: 4/75rem; } } ul{ &.readonly{ opacity: 0.65; } min-height: 84/75rem; display: flex; align-items: center; padding-left:6/75rem; flex-wrap: wrap; li{ margin-right: 20/75rem; margin-top: 18/75rem; button{ padding: 0 20/75rem; height: 54/75rem; border-radius: 4/75rem; color: fff; font-size: 26/75rem; background: #fff; border: 1px solid #ccc; color: #666; &.selected{ color: #fff; border: 1px solid #079ff7; background: #079ff7; } } } } .tips{ color: #ff6633; font-size: 26/75rem; line-height: 36/75rem; margin-top: 12/75rem; padding-left:6/75rem; } }

父组件调用代码
> // 引入选择框组件 import MeSelect from './MeSelect'export default { data () { return { // 单选 // selectData: 1, // 多选 selectData: [{name: '选项一', value: 1}], options: [ {name: '选项一', value: 1}, {name: '选项二', value: 2}, {name: '选项三', value: 3}, {name: '选项四', value: 4}, {name: '选项五', value: 5} ] } }, components: { MeSelect } } ="less" scoped>

【Vue组件分享|Vue中双向绑定实现的表单选择组件(按钮样式)】有问题就评论问我吧,(●ˇ?ˇ●)
个人联系方式(添加请备注):
QQ:332983810
微信:hu_jiliang

    推荐阅读