# tui-picker 联动选择 开源组件
# picker组件联动
picker
组件的具体使用请参考 官方文档 (opens new window)。
设置mode = multiSelector,多列选择器。
change
事件:value 改变时触发 change 事件,event.detail = {value: value}
columnchange
事件:某一列的值改变时触发 columnchange 事件,event.detail = {column: column, value: value},column 的值表示改变了第几列(下标从0开始),value 的值表示变更值的下标
<template>
<view class="container">
<picker :value="value" mode="multiSelector" @change="picker" @columnchange="columnPicker" :range="multiArray">
<tui-button shape="circle">请选择</tui-button>
</picker>
<view class="result">
{{text}}
</view>
</view>
</template>
<script>
//数据请看介绍获取,或拷贝示例中的js文件
import cityData from '@/utils/picker.city.js'
export default {
data() {
return {
selectList: cityData, //接口返回picker数据,此处就直接使用本地测试数据
multiArray: [], //picker数据
value: [0, 0, 0],
text: "",
id: ""
}
},
onLoad: function() {
this.multiArray = [
this.toArr(this.selectList),
this.toArr(this.selectList[0].children),
this.toArr(this.selectList[0].children[0].children)
]
},
methods: {
picker: function(e) {
let value = e.detail.value;
if (this.selectList.length > 0) {
let provice = this.selectList[value[0]].text
let city = this.selectList[value[0]].children[value[1]].text
let district = this.selectList[value[0]].children[value[1]].children[value[2]].text
this.text = provice + " " + city + " " + district;
this.id = this.selectList[value[0]].children[value[1]].children[value[2]].value
}
},
toArr(object) {
let arr = [];
for (let i in object) {
arr.push(object[i].text);
}
return arr;
},
columnPicker: function(e) {
//第几列 下标从0开始
let column = e.detail.column;
//第几行 下标从0开始
let value = e.detail.value;
if (column === 0) {
this.multiArray = [
this.multiArray[0],
this.toArr(this.selectList[value].children),
this.toArr(this.selectList[value].children[0].children)
];
this.value = [value, 0, 0]
} else if (column === 1) {
this.multiArray = [
this.multiArray[0],
this.multiArray[1],
this.toArr(this.selectList[this.value[0]].children[value].children)
];
this.value = [this.value[0], value, 0]
}
}
}
}
</script>
<style>
.container {
padding: 100rpx 30rpx
}
.result {
padding: 60rpx 20rpx;
font-size: 30rpx;
color: #333
}
</style>
<view class="container">
<picker value="{{value}}" mode="multiSelector" bindchange="picker" bindcolumnchange="columnPicker" range="{{multiArray}}">
<tui-button shape="circle">请选择</tui-button>
</picker>
<view class="result">
{{text}}
</view>
</view>
//数据请看介绍获取,或拷贝示例中的js文件
const cityData = require('../../../utils/picker.city.js')
Page({
data: {
selectList: cityData, //接口返回picker数据,此处就直接使用本地测试数据
multiArray: [], //picker数据
value: [0, 0, 0],
text: "",
id: ""
},
onLoad: function (options) {
let multiArray = [
this.toArr(this.data.selectList),
this.toArr(this.data.selectList[0].children),
this.toArr(this.data.selectList[0].children[0].children)
]
this.setData({
multiArray: multiArray
})
},
picker: function (e) {
let value = e.detail.value;
if (this.data.selectList.length > 0) {
let provice = this.data.selectList[value[0]].text
let city = this.data.selectList[value[0]].children[value[1]].text
let district = this.data.selectList[value[0]].children[value[1]].children[value[2]].text
this.setData({
text:provice + " " + city + " " + district,
id:this.data.selectList[value[0]].children[value[1]].children[value[2]].value
})
}
},
toArr(object) {
let arr = [];
for (let i in object) {
arr.push(object[i].text);
}
return arr;
},
columnPicker: function (e) {
//第几列 下标从0开始
let column = e.detail.column;
//第几行 下标从0开始
let value = e.detail.value;
if (column === 0) {
let multiArray = [
this.data.multiArray[0],
this.toArr(this.data.selectList[value].children),
this.toArr(this.data.selectList[value].children[0].children)
];
this.setData({
multiArray:multiArray,
value:[value, 0, 0]
})
} else if (column === 1) {
let multiArray = [
this.data.multiArray[0],
this.data.multiArray[1],
this.toArr(this.data.selectList[this.data.value[0]].children[value].children)
];
this.setData({
multiArray:multiArray,
value:[this.data.value[0], value, 0]
})
}
}
})
.container {
padding: 100rpx 30rpx
}
.result {
padding: 60rpx 20rpx;
font-size: 30rpx;
color: #333
}
// Make sure to add code blocks to your code group
约定好数据格式,联动逻辑实现主要根据事件触发进行相关数据处理。
# picker-view组件联动
picker-view
组件的具体使用请参考 官方文档 (opens new window)。
change
事件:当滚动选择,value 改变时触发 change 事件,event.detail = {value: value};value为数组,表示 picker-view 内的 picker-view-column 当前选择的是第几项(下标从 0 开始)
<template>
<view class="conatiner">
<view class="btn-select">
<tui-button shape="circle" @click="showPicker">请选择</tui-button>
</view>
<!--picker-view start-->
<view class="tui-mask-screen" :class="[showPickerStatus?'tui-mask-show':'']" @tap="hidePicker"></view>
<view class="tui-picker-box" :class="[showPickerStatus?'tui-pickerbox-show':'']">
<view class="picker-header tui-list-item">
<view class="btn-cancle" hover-class="tui-opcity" :hover-stay-time="150" @tap.stop="hidePicker">取消</view>
<view class="btn-sure" hover-class="tui-opcity" :hover-stay-time="150" @tap.stop="picker">确定</view>
</view>
<picker-view indicator-style="height: 50px;" class="picker-view" :value="value" @change="columnPicker">
<picker-view-column>
<view v-for="(item,index) in proviceArr" :key="index" class="item">{{item}}</view>
</picker-view-column>
<picker-view-column>
<view v-for="(item,index) in cityArr" :key="index" class="item">{{item}}</view>
</picker-view-column>
<picker-view-column>
<view v-for="(item,index) in districtArr" :key="index" class="item">{{item}}</view>
</picker-view-column>
</picker-view>
</view>
<!--picker-view end-->
</view>
</template>
<script>
import cityData from '@/utils/picker.city.js'
export default {
data() {
return {
proviceArr: [],
cityArr: [],
districtArr: [],
value: [0, 0, 0],
iconHidden: true,
showPickerStatus: false,
text: ["请选择", "请选择", "请选择"]
}
},
onLoad: function() {
//初始化数据
this.proviceArr = this.toArr(cityData);
this.cityArr = this.toArr(cityData[0].children);
this.districtArr = this.toArr(cityData[0].children[0].children)
},
methods: {
toArr(object) {
let arr = [];
for (let i in object) {
arr.push(object[i].text);
}
return arr;
},
//picker change切换事件
columnPicker: function(e) {
let value = e.detail.value;
//如果两者下标不一致,表示滚动过
if (this.value[0] !== value[0]) {
this.proviceArr = this.proviceArr;
this.cityArr = this.toArr(cityData[value[0]].children);
this.districtArr = this.toArr(cityData[value[0]].children[0].children);
this.value = [value[0], 0, 0]
} else if (this.value[1] !== value[1]) {
this.proviceArr = this.proviceArr;
this.cityArr = this.cityArr;
this.districtArr = this.toArr(cityData[value[0]].children[value[1]].children);
this.value = [value[0], value[1], 0]
} else {
this.value = value
}
},
//确定按钮
picker: function(e) {
let value = this.value;
if (cityData.length > 0) {
let provice = cityData[value[0]].text;
let city = cityData[value[0]].children[value[1]].text;
let district = cityData[value[0]].children[value[1]].children[value[2]].text;
this.text = [provice, city, district];
this.showPickerStatus = false
}
},
// 显示picker-view
showPicker: function() {
this.showPickerStatus = true
},
// 隐藏picker-view
hidePicker: function() {
this.showPickerStatus = false
}
}
}
</script>
<style>
/* picker start*/
.tui-mask-screen {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: rgba(0, 0, 0, 0.6);
z-index: 99996;
transition: all 0.3s ease-in-out;
opacity: 0;
visibility: hidden;
}
.tui-mask-show {
opacity: 1;
visibility: visible;
}
.tui-picker-box {
width: 100%;
position: fixed;
left: 0;
right: 0;
bottom: 0;
z-index: 99999;
visibility: hidden;
transform: translate3d(0, 100%, 0);
transform-origin: center;
transition: all 0.3s ease-in-out;
min-height: 20rpx;
background: #fff;
}
.tui-pickerbox-show {
transform: translate3d(0, 0, 0);
visibility: visible;
}
.picker-header {
width: 100%;
height: 90rpx;
padding: 0 46rpx;
display: flex;
justify-content: space-between;
align-items: center;
box-sizing: border-box;
font-size: 32rpx;
background: #fff;
}
.tui-list-item::after {
left: 0;
}
.btn-cancle {
padding: 20rpx;
color: #888;
}
.btn-sure {
padding: 20rpx;
color: #5677fc;
}
.picker-view {
width: 100%;
height: 260px;
}
.item {
line-height: 50px;
text-align: center;
}
/* picker end*/
.btn-select {
width: 100%;
padding: 20rpx 40rpx;
box-sizing: border-box;
}
</style>
<!--微信小程序-->
<view class="conatiner">
<view class="btn-select">
<tui-button shape="circle" bindclick="showPicker">请选择</tui-button>
</view>
<!--picker-view start-->
<view class="tui-mask-screen {{showPickerStatus?'tui-mask-show':''}}" bindtap="hidePicker"></view>
<view class="tui-picker-box {{showPickerStatus?'tui-pickerbox-show':''}}">
<view class="picker-header tui-list-item">
<view class="btn-cancle" hover-class="tui-opcity" hover-stay-time="150" catchtap="hidePicker">取消</view>
<view class="btn-sure" hover-class="tui-opcity" hover-stay-time="150" catchtap="picker">确定</view>
</view>
<picker-view indicator-style="height: 50px;" class="picker-view" value="{{value}}" bindchange="columnPicker">
<picker-view-column>
<view wx:for="{{proviceArr}}" wx:key="index" class="item">{{item}}</view>
</picker-view-column>
<picker-view-column>
<view wx:for="{{cityArr}}" wx:key="index" class="item">{{item}}</view>
</picker-view-column>
<picker-view-column>
<view wx:for="{{districtArr}}" wx:key="index" class="item">{{item}}</view>
</picker-view-column>
</picker-view>
</view>
<!--picker-view end-->
</view>
// data 数据 及 方法
const cityData = require('../../../utils/picker.city.js')
Page({
data: {
proviceArr: [],
cityArr: [],
districtArr: [],
value: [0, 0, 0],
iconHidden: true,
showPickerStatus: false,
text: ["请选择", "请选择", "请选择"]
},
onLoad: function (options) {
//初始化数据
this.setData({
proviceArr: this.toArr(cityData),
cityArr: this.toArr(cityData[0].children),
districtArr: this.toArr(cityData[0].children[0].children)
})
},
toArr(object) {
let arr = [];
for (let i in object) {
arr.push(object[i].text);
}
return arr;
},
//picker change切换事件
columnPicker: function (e) {
let value = e.detail.value;
//如果两者下标不一致,表示滚动过
if (this.data.value[0] !== value[0]) {
this.setData({
proviceArr: this.data.proviceArr,
cityArr: this.toArr(cityData[value[0]].children),
districtArr: this.toArr(cityData[value[0]].children[0].children),
value: [value[0], 0, 0]
})
} else if (this.data.value[1] !== value[1]) {
this.setData({
proviceArr: this.data.proviceArr,
cityArr: this.data.cityArr,
districtArr: this.toArr(cityData[value[0]].children[value[1]].children),
value: [value[0], value[1], 0]
})
} else {
this.setData({
value: value
})
}
},
//确定按钮
picker: function (e) {
let value = this.data.value;
if (cityData.length > 0) {
let provice = cityData[value[0]].text;
let city = cityData[value[0]].children[value[1]].text;
let district = cityData[value[0]].children[value[1]].children[value[2]].text;
this.setData({
text: [provice, city, district],
showPickerStatus: false
})
}
},
// 显示picker-view
showPicker: function () {
this.setData({
showPickerStatus: true
})
},
// 隐藏picker-view
hidePicker: function () {
this.setData({
showPickerStatus: false
})
}
})
/* picker start*/
.tui-mask-screen {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: rgba(0, 0, 0, 0.6);
z-index: 99996;
transition: all 0.3s ease-in-out;
opacity: 0;
visibility: hidden;
}
.tui-mask-show {
opacity: 1;
visibility: visible;
}
.tui-picker-box {
width: 100%;
position: fixed;
left: 0;
right: 0;
bottom: 0;
z-index: 99999;
visibility: hidden;
transform: translate3d(0, 100%, 0);
transform-origin: center;
transition: all 0.3s ease-in-out;
min-height: 20rpx;
background: #fff;
}
.tui-pickerbox-show {
transform: translate3d(0, 0, 0);
visibility: visible;
}
.picker-header {
width: 100%;
height: 90rpx;
padding: 0 46rpx;
display: flex;
justify-content: space-between;
align-items: center;
box-sizing: border-box;
font-size: 32rpx;
background: #fff;
}
.tui-list-item::after {
left: 0;
}
.btn-cancle {
padding: 20rpx;
color: #888;
}
.btn-sure {
padding: 20rpx;
color: #5677fc;
}
.picker-view {
width: 100%;
height: 260px;
}
.item {
line-height: 50px;
text-align: center;
}
/* picker end*/
.btn-select {
width: 100%;
padding: 20rpx 40rpx;
box-sizing: border-box;
}
// Make sure to add code blocks to your code group
约定好数据格式,联动逻辑实现主要根据事件触发进行相关数据处理。
TIP
此内容为官方组件示例,建议使用ThorUI 封装组件 tui-picker。
# 预览
完整的全国省市区数据下载 city-data
(opens new window)
# 特别说明
# 线上程序扫码预览
![]() | ![]() | ![]() |
---|---|---|
ThorUI组件库小程序码 | H5二维码 | ThorUI示例小程序码 |