123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256 |
- <template>
- <view :class="['lb-picker', inline ? 'lb-picker-inline' : '']">
- <view class="lb-picker-mask"
- v-show="visible && !inline"
- :style="{ 'background-color': maskColor }"
- @tap.stop="handleMaskTap"
- @touchmove.stop.prevent="moveHandle">
- </view>
- <view :class="['lb-picker-container', visible ? 'lb-picker-toggle' : '']"
- :style="{ borderRadius: `${radius} ${radius} 0 0` }">
- <view v-if="showHeader"
- class="lb-picker-header"
- :style="{
- height: pickerHeaderHeight,
- 'line-height': pickerHeaderHeight
- }">
- <view class="lb-picker-action lb-picker-left">
- <view class="lb-picker-action-cancel"
- @tap.stop="handleCancel">
- <slot v-if="$slots['cancel-text']"
- name="cancel-text"> </slot>
- <view v-else
- class="action-cancel-text"
- :style="{ color: cancelColor }">
- {{ cancelText }}
- </view>
- </view>
- </view>
- <view class="lb-picker-action lb-picker-center"
- v-if="$slots['action-center']">
- <slot name="action-center"></slot>
- </view>
- <view class="lb-picker-action lb-picker-right">
- <view class="lb-picker-action-confirm"
- @tap.stop="handleConfirm">
- <slot v-if="$slots['confirm-text']"
- name="confirm-text"> </slot>
- <view v-else
- class="action-confirm-text"
- :style="{ color: confirmColor }">
- {{ confirmText }}
- </view>
- </view>
- </view>
- </view>
- <view class="lb-picker-content"
- :style="{ height: pickerContentHeight }">
- <!-- loading -->
- <view v-if="loading"
- class="lb-picker-loading">
- <slot name="loading">
- <view class="lb-picker-loading-img"></view>
- </slot>
- </view>
- <!-- 暂无数据 -->
- <view v-if="isEmpty && !loading"
- class="lb-picker-empty">
- <slot name="empty">
- <text class="lb-picker-empty-text"
- :style="{ color: emptyColor }">
- {{ emptyText }}
- </text>
- </slot>
- </view>
- <!-- 单选 -->
- <selector-picker v-if="mode === 'selector' && !loading && !isEmpty"
- :value="22"
- :list="list"
- :props="pickerProps"
- :height="pickerContentHeight"
- :inline="inline"
- @change="handleChange">
- </selector-picker>
- <!-- 多列联动 -->
- <multi-selector-picker v-if="mode === 'multiSelector' && !loading && !isEmpty"
- :value="value"
- :list="list"
- :level="level"
- :visible="visible"
- :props="pickerProps"
- :height="pickerContentHeight"
- :inline="inline"
- @change="handleChange">
- </multi-selector-picker>
- <!-- 非联动选择 -->
- <unlinked-selector-picker v-if="mode === 'unlinkedSelector' && !loading && !isEmpty"
- :value="value"
- :list="list"
- :visible="visible"
- :props="pickerProps"
- :height="pickerContentHeight"
- :inline="inline"
- @change="handleChange">
- </unlinked-selector-picker>
- </view>
- </view>
- </view>
- </template>
- <script>
- const defaultProps = {
- label: 'name',
- value: 'id',
- children: 'children'
- }
- import { getIndicatorHeight } from './utils'
- import SelectorPicker from './pickers/selector-picker'
- import MultiSelectorPicker from './pickers/multi-selector-picker'
- import UnlinkedSelectorPicker from './pickers/unlinked-selector-picker'
- const indicatorHeight = getIndicatorHeight()
- export default {
- components: {
- SelectorPicker,
- MultiSelectorPicker,
- UnlinkedSelectorPicker
- },
- props: {
- value: [String, Number, Array],
- list: Array,
- mode: {
- type: String,
- default: 'selector'
- },
- level: {
- type: Number,
- default: 1
- },
- props: {
- type: Object
- },
- cancelText: {
- type: String,
- default: '取消'
- },
- cancelColor: String,
- confirmText: {
- type: String,
- default: '确定'
- },
- confirmColor: String,
- canHide: {
- type: Boolean,
- default: true
- },
- emptyColor: String,
- emptyText: {
- type: String,
- default: '暂无数据'
- },
- radius: String,
- columnNum: {
- type: Number,
- default: 5
- },
- loading: Boolean,
- closeOnClickMask: {
- type: Boolean,
- default: true
- },
- maskColor: {
- type: String,
- default: 'rgba(0, 0, 0, 0.4)'
- },
- dataset: Object,
- inline: Boolean,
- showHeader: {
- type: Boolean,
- default: true
- }
- },
- data () {
- return {
- visible: false,
- myValue: this.value,
- picker: {},
- pickerProps: Object.assign({}, defaultProps, this.props),
- pickerHeaderHeight: indicatorHeight + 'px',
- pickerContentHeight: indicatorHeight * this.columnNum + 'px'
- }
- },
- computed: {
- isEmpty () {
- if (!this.list) return true
- if (this.list && !this.list.length) return true
- return false
- }
- },
- methods: {
- show () {
- if (this.inline) return
- this.visible = true
- },
- hide () {
- if (this.inline) return
- this.visible = false
- },
- handleCancel () {
- this.$emit('cancel', this.picker)
- if (this.canHide && !this.inline) {
- this.hide()
- }
- },
- handleConfirm () {
- if (this.isEmpty) {
- this.$emit('confirm', null)
- this.hide()
- } else {
- const picker = JSON.parse(JSON.stringify(this.picker))
- this.myValue = picker.value
- this.$emit('confirm', this.picker)
- if (this.canHide) this.hide()
- }
- },
- handleChange ({ value, item, index, change }) {
- this.picker.value = value
- this.picker.item = item
- this.picker.index = index
- this.picker.change = change
- this.picker.dataset = this.dataset || {}
- this.$emit('change', this.picker)
-
- },
- handleMaskTap () {
- if (this.closeOnClickMask) {
- this.visible = false
- }
- },
- moveHandle () {}
- },
- watch: {
- value (newVal) {
- this.myValue = newVal
- },
- myValue (newVal) {
- this.$emit('input', newVal)
- },
- visible (newVisible) {
- if (newVisible) {
- this.$emit('show')
- } else {
- this.$emit('hide')
- }
- }
- }
- }
- </script>
- <style lang="scss" scoped>
- @import "./style/picker.scss";
- </style>
|