级联选择器,用于多层级数据的选择,典型场景为省市区选择
1 简易版
1.1效果展示
1.2 组件源码
<template>
<div>
<!-- 遮罩层,支持点击遮罩关闭级联选择 -->
<div
v-show="visible"
class="mask"
@click="close"
/>
<transition name="fade">
<!-- 级联选择部分 -->
<div
v-show="visible"
class="cascader"
>
<!-- 顶部标题 -->
<div class="title">
{
{ title }}
<!-- 关闭按钮 -->
<i
v-if="leftIcon"
:class="['back', {
'arrow': leftIcon === 'arrow', 'cross': leftIcon === 'cross'}]"
@click="close"
/>
</div>
<!-- 展示各级选择的结果 -->
<ul class="nav-list line">
<template v-for="(item, index) in (tabIndex + 1)">
<li
:key="index"
:class="['nav-list-item', {
'active': index === tabIndex, 'more-hidden': moreHidden}]"
@click="changeIndex(index)"
>
{
{ (selectedOptions[index] && selectedOptions[index][fieldNames.text]) || placeholderText }}
</li>
</template>
</ul>
<!-- 展示当前级列表数据 -->
<ol
class="select-list"
ref="selectListRef"
>
<template v-for="(item, index) in pickerDataArr[tabIndex]">
<li
:key="index"
class="select-list-item line"
@click="selectItem(item)"
>
{
{ item[fieldNames.text] }}
</li>
</template>
</ol>
</div>
</transition>
</div>
</template>
<script>
export default {
name: 'cascaderPicker',
props: {
// 是否显示级联选择器,支持 .sync 修饰符
visible: {
type: Boolean,
default: false
},
// 可选项数据源
options: {
type: Array,
default: () => []
},
// 顶部标题
title: {
type: String,
default: ''
},
// 各级未选中时的提示文案
placeholderText: {
type: String,
default: '请选择'
},
// 各级选择的结果文字展示溢出是否隐藏
moreHidden: {
type: Boolean,
default: false
},
// 自定义选择层级数
level: {
type: Number,
default: 3
},
// 自定义options结构中的字段
fieldNames: {
type: Object,
default: () => ({
text: 'text',
value: 'value',
chlidren: 'children'
})
},
// 关闭图标:arrow(左箭头)/cross(交叉)
leftIcon: {
type: String,
default: 'arrow'
}
},
data() {
return {
// 当前选择级索引
tabIndex: 0,
// 各级选择的结果组合
selectedOptions: [],
// 每一级列表组合
pickerDataArr: []
}
},
watch: {
tabIndex () {
// 列表滚动置零
this.$refs['selectListRef'].scrollTop = 0
},
// 每次弹起组件时重置数据
visible (val) {
if (val) {
this.tabIndex = 0
this.selectedOptions = []
this.pickerDataArr = []
// 默认展示第一级列表数据(最外层)
this.pickerDataArr.push(this.options)
}
}
},
methods: {
changeIndex (index) {
// 往回从新选择,加visible条件防止关闭级联选择器动画误触
if (this.visible && index < this.tabIndex) {
// 删除选中当前级开始的结果
this.selectedOptions.splice(index)
// 删除选中当前级下一级的列表数据
this.pickerDataArr.splice(index + 1)
this.tabIndex = index
}
},
selectItem (item) {
// 关闭级联选择器动画防重
if(!this.visible) return