uniapp⾃定义picker城市多级联动组件uniapp⾃定义picker城市多级联动组件
⽀持多端——h5、app、⼩程序、⽀付宝⼩程序...
⽀持⾃定义配置picker插件级数
⽀持⽆限级
注意事项:插件传⼊数据格式为children树形格式,内部包含:id、name
参数类型描述默认值必选
title string标题''否
layer number控制⼏级联动1否
data arr数据如:[{text: '', adcode: '', children: [{text: '', adcode: ''}]}][]否
组件运⾏图⽰:
组件选择后返回数据如:
引⽤⽰例:
<template>
<view class="content">
<view class="aui-content" :>
<view class="aui-btn aui-btn-blue" @click.stop="showPicker($event)">picker⽆限级联动</view>
</view>
<aui-picker
ref="picker"
:title="auiPicker.title"
:layer="auiPicker.layer"
:data="auiPicker.data"
@callback="pickerCallback"
></aui-picker>
</view>
</template>
<script>
import auiPicker from '@/components/aui-picker/aui-picker.vue'; export default {
components: {
auiPicker
},
data() {
return {
auiPicker: {
title: 'picker多级联动',
layer: null,
data: []
},
}
},
created(){
},
mounted() {
},
methods: {
//显⽰picker多级联动弹窗
showPicker(e){
const _this = this;
_this.auiPicker.data=[{
id: "1001",
name: "⼀级菜单1",
children: [{
id: "1002",
name: "⼆级菜单1-1",
children: [{
id: "1003",
name: "三级菜单1-1",
children: [{
id: "1004",
name: "四级菜单1-1"
}]
}]
}]
},
{
id: "1005",
name: "⼀级菜单2",
children: [{
id: "1006",
name: "⼆级菜单2-1",
children: [{
id: "1007",
name: "三级菜单2-1",
children: [{
id: "1008",
name: "四级菜单2-1"
}]
}]
}]
}];
_this.$refs.picker.open().then(function(){
console.log('picker打开');
});
},
/
/picker多级联动回调
pickerCallback(e){
const _this = this;
console.log(e);
let result = '';
e.data.forEach(function(item, index){
result += item.name + '  ';
});
uni.showModal({
title: '提⽰',
content: result,
success: function (res) {
if (firm) {
console.log('⽤户点击确定');
} else if (res.cancel) {
console.log('⽤户点击取消');
}
}
});
}
}
}
</script>
<style>
.aui-content{padding: 15px 0 0 0;}
</style>
aui-picker组件完整代码:
项⽬components⽂件夹下创建aui-picker夹,此⽂件夹下创建aui-picker.vue——多级联动组件<template name="aui-picker">
<view class="aui-picker" v-if="SHOW" :class="{
'aui-picker-in': FADE==1,
'aui-picker-out': FADE==0}"
>
<view class="aui-mask" @click.stop="close"></view>
<view class="aui-picker-main">
<view class="aui-picker-header">
<view class="aui-picker-title" v-if="title">{{title}}</view>
<view class="aui-picker-close iconfont iconclose" @click.stop="close"></view>
</view>
<view class="aui-picker-nav">
<view class="aui-picker-navitem"
v-if="nav.length>0"
v-for="(item, index) in nav"
:key="index"
:data-index="index"
:
uniapp 字符串转数组class="[index==navCurrentIndex ? 'active' : '', 'aui-picker-navitem-'+index]"
:
@click.stop="_changeNav($event)"
>{{item.name}}</view>
<view class="aui-picker-navitem"
:key="nav.length"
:data-index="nav.length"
:class="[nav.length==navCurrentIndex ? 'active' : '', 'aui-picker-navitem-'+nav.length]"
:
@click.stop="_changeNav($event)"
>请选择</view>
<view class="aui-picker-navborder" :></view>
</view>
<view class="aui-picker-content">
<view class="aui-picker-lists">
<view class="aui-picker-list"
v-for="(list, index) in queryItems.length + 1"
:key="index"
:data-index="index"
:class="[index==navCurrentIndex ? 'active' : '']"
>
<view class="aui-picker-list-warp" v-if="index == 0">
<view class="aui-picker-item"
v-for="(item, key) in items"
v-if="item.pid=='0'"
:key="key"
:data-pindex="index"
:data-index="key"
:data-id="item.id"
:data-pid="item.pid"
:data-name="item.name"
:class="{'active': result.length>index && result[index].id==item.id}"
:        @click.stop="_chooseItem($event)"
@touchstart="_btnTouchStart($event)"
@touchmove="_btnTouchEnd($event)"
@touchend="_btnTouchEnd($event)"
>{{item.name}}</view>
</view>
<view class="aui-picker-list-warp" v-else>
<view class="aui-picker-item"
v-for="(item, key) in queryItems[index-1]"
:key="key"
:data-pindex="index"
:data-index="key"
:
data-id="item.id"
:data-pid="item.pid"
:data-name="item.name"
:class="{'active': result.length>index && result[index].id==item.id}"
:        @click.stop="_chooseItem($event)"
@touchstart="_btnTouchStart($event)"
@touchmove="_btnTouchEnd($event)"
@touchend="_btnTouchEnd($event)"
>{{item.name}}</view>
</view>
</view>
</view>
</view>
</view>
</view>
</template>
<script>
export default {
name: 'aui-picker',
props: {
title: { //标题
type: String,
default: ''
},
layer: { //控制⼏级联动,默认⽆限级(跟随数据有⽆下级)
type: Number,
default: null
},
data: { //数据如:[{id: '', name: '', children: [{id: '', name: ''}]}]
type: Array,
default (){
return [
// [{id: '', name: '', children: [{id: '', name: ''}]}]
]
}
}
},
data(){
return {
SHOW: false,
FADE: -1,
nav: [],
items: [],
queryItems: [],
navCurrentIndex: 0,
navBorderLeft: 40,
result: [],
touchConfig: {
index: -1,
pindex: -1,
style: {
color: '#197DE0',
background: '#EFEFEF'
}
}
}
},
created(){
const _this = this;
},
watch:{
data(){
const _this = this;
const data = _this.data;
_this.items = _this._flatten(data, '0')
    } 
  },
mounted(){
},
methods:{
// 打开
open(){
const _this = this;
_set(); //打开时重置picker
return new Promise(function(resolve, reject){
_this.SHOW = true;
_this.FADE = 1;
resolve();
});
},
// 关闭
close(){
const _this = this;
return new Promise(function(resolve, reject){
_this.FADE = 0;
const _hidetimer = setTimeout(()=>{
_this.SHOW = false;
_this.FADE = -1;
clearTimeout(_hidetimer);
resolve();
},100)
});
},
//重置
reset(){
const _this = this;
_this.queryItems = [];
_this.nav = [];
_this.navBorderLeft = 40;
_this.navCurrentIndex = 0;
_sult = [];
},
//导航栏切换
_changeNav(e){
const _this = this;
const index = Number(e.currentTarget.dataset.index);
_this.navCurrentIndex = index;
const _el = ateSelectorQuery().in(this).select(".aui-picker-navitem-"+index);
_el.boundingClientRect(data => {
_this.navBorderLeft = data.left + 20;
}).exec();
},
//数据选择
_chooseItem(e){
const _this = this;
const id = e.currentTarget.dataset.id;
const name = e.currentTarget.dataset.name;
const pid = e.currentTarget.dataset.pid;
const _arr = [];
_sult[_this.navCurrentIndex] = {id: id, name: name, pid: pid};
if(
(!_this._isDefine(_this.layer) && _this._isDefine(_this._deepQuery(_this.data, id).children))
||
(_this.navCurrentIndex < (Number(_this.layer) - 1) && _this._isDefine(_this._deepQuery(_this.data, id).children))    )
{ //有下级数据
_this._deepQuery(_this.data, id).children.forEach(function(item, index){
_arr.push({id: item.id, name: item.name, pid: id});
});
if(_this.navCurrentIndex == _this.queryItems.length)
{ //选择数据
_this.queryItems.push(_arr);
_this.nav.push({name: name});
}
else
{ //重新选择数据
_this.queryItems.splice(_this.navCurrentIndex+1, 1);
_this.nav.splice(_this.navCurrentIndex+1, 1);
_this.queryItems.splice(_this.navCurrentIndex, 1, _arr);
_this.nav.splice(_this.navCurrentIndex, 1, {name: name});
}
_this.navCurrentIndex = _this.navCurrentIndex + 1;
const _el = ateSelectorQuery().in(this).select(".aui-picker-navitem-"+_this.navCurrentIndex);
setTimeout(()=>{
_el.boundingClientRect(data => {
_this.navBorderLeft = data.left + 20;
}).exec();
},100)
}
else
{ //⽆下级数据
_this.close().then(()=>{
_this.$emit("callback", {status: 0, data: _sult});
});
}
},
/
/递归遍历——将树形结构数据转化为数组格式
_flatten(tree, pid) {
duce((arr, {id, name, children = []}) =>
},
//根据id查询对应的数据(如查询id=10100对应的对象)
_deepQuery(tree, id) {
let isGet = false;
let retNode = null;
function deepSearch(tree, id){
for(let i = 0; i < tree.length; i++) {
if(tree[i].children && tree[i].children.length > 0) {
deepSearch(tree[i].children, id);

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。