|
|
<template> <view class="uni-data-pickerview"> <scroll-view v-if="!isCloudDataList" class="selected-area" scroll-x="true"> <view class="selected-list"> <view class="selected-item" v-for="(item,index) in selected" :key="index" :class="{ 'selected-item-active':index == selectedIndex }" @click="handleSelect(index)" > <text>{{item.text || ''}}</text> </view> </view> </scroll-view> <view class="tab-c"> <scroll-view class="list" :scroll-y="true"> <view class="item" :class="{'is-disabled': !!item.disable}" v-for="(item, j) in dataList[selectedIndex]" :key="j" @click="handleNodeClick(item, selectedIndex, j)"> <text class="item-text">{{item[map.text]}}</text> <view class="check" v-if="selected.length > selectedIndex && item[map.value] == selected[selectedIndex].value"></view> </view> </scroll-view>
<view class="loading-cover" v-if="loading"> <uni-load-more class="load-more" :contentText="loadMore" status="loading"></uni-load-more> </view> <view class="error-message" v-if="errorMessage"> <text class="error-text">{{errorMessage}}</text> </view> </view> </view> </template>
<script> import dataPicker from "./uni-data-picker.js"
/** * DataPickerview * @description uni-data-pickerview * @tutorial https://ext.dcloud.net.cn/plugin?id=3796
* @property {Array} localdata 本地数据,参考 * @property {Boolean} step-searh = [true|false] 是否分布查询 * @value true 启用分布查询,仅查询当前选中节点 * @value false 关闭分布查询,一次查询出所有数据 * @property {String|DBFieldString} self-field 分布查询当前字段名称 * @property {String|DBFieldString} parent-field 分布查询父字段名称 * @property {String|DBCollectionString} collection 表名 * @property {String|DBFieldString} field 查询字段,多个字段用 `,` 分割 * @property {String} orderby 排序字段及正序倒叙设置 * @property {String|JQLString} where 查询条件 */ export default { name: 'UniDataPickerView', emits: ['nodeclick', 'change', 'datachange', 'update:modelValue'], mixins: [dataPicker], props: { managedMode: { type: Boolean, default: false }, ellipsis: { type: Boolean, default: true } }, created() { if (!this.managedMode) { this.$nextTick(() => { this.loadData(); }) } }, methods: { onPropsChange() { this._treeData = []; this.selectedIndex = 0; this.$nextTick(() => { this.loadData(); }) }, handleSelect(index) { this.selectedIndex = index; }, handleNodeClick(item, i, j) { if (item.disable) { return; }
const node = this.dataList[i][j]; const text = node[this.map.text]; const value = node[this.map.value];
if (i < this.selected.length - 1) { this.selected.splice(i, this.selected.length - i) this.selected.push({ text, value }) } else if (i === this.selected.length - 1) { this.selected.splice(i, 1, { text, value }) }
if (node.isleaf) { this.onSelectedChange(node, node.isleaf) return }
const { isleaf, hasNodes } = this._updateBindData()
// 本地数据
if (this.isLocalData) { this.onSelectedChange(node, (!hasNodes || isleaf)) } else if (this.isCloudDataList) { // Cloud 数据 (单列)
this.onSelectedChange(node, true) } else if (this.isCloudDataTree) { // Cloud 数据 (树形)
if (isleaf) { this.onSelectedChange(node, node.isleaf) } else if (!hasNodes) { // 请求一次服务器以确定是否为叶子节点
this.loadCloudDataNode((data) => { if (!data.length) { node.isleaf = true } else { this._treeData.push(...data) this._updateBindData(node) } this.onSelectedChange(node, node.isleaf) }) } } }, updateData(data) { this._treeData = data.treeData this.selected = data.selected if (!this._treeData.length) { this.loadData() } else { //this.selected = data.selected
this._updateBindData() } }, onDataChange() { this.$emit('datachange'); }, onSelectedChange(node, isleaf) { if (isleaf) { this._dispatchEvent() }
if (node) { this.$emit('nodeclick', node) } }, _dispatchEvent() { this.$emit('change', this.selected.slice(0)) } } } </script>
<style lang="scss"> $uni-primary: #007aff !default;
.uni-data-pickerview { flex: 1; /* #ifndef APP-NVUE */ display: flex; /* #endif */ flex-direction: column; overflow: hidden; height: 100%; }
.error-text { color: #DD524D; }
.loading-cover { position: absolute; left: 0; top: 0; right: 0; bottom: 0; background-color: rgba(255, 255, 255, .5); /* #ifndef APP-NVUE */ display: flex; /* #endif */ flex-direction: column; align-items: center; z-index: 1001; }
.load-more { /* #ifndef APP-NVUE */ margin: auto; /* #endif */ }
.error-message { background-color: #fff; position: absolute; left: 0; top: 0; right: 0; bottom: 0; padding: 15px; opacity: .9; z-index: 102; }
/* #ifdef APP-NVUE */ .selected-area { width: 750rpx; } /* #endif */
.selected-list { /* #ifndef APP-NVUE */ display: flex; flex-wrap: nowrap; /* #endif */ flex-direction: row; padding: 0 5px; border-bottom: 1px solid #f8f8f8; }
.selected-item { margin-left: 10px; margin-right: 10px; padding: 12px 0; text-align: center; /* #ifndef APP-NVUE */ white-space: nowrap; /* #endif */ }
.selected-item-text-overflow { width: 168px; /* fix nvue */ overflow: hidden; /* #ifndef APP-NVUE */ width: 6em; white-space: nowrap; text-overflow: ellipsis; -o-text-overflow: ellipsis; /* #endif */ }
.selected-item-active { border-bottom: 2px solid $uni-primary; }
.selected-item-text { color: $uni-primary; }
.tab-c { position: relative; flex: 1; /* #ifndef APP-NVUE */ display: flex; /* #endif */ flex-direction: row; overflow: hidden; }
.list { flex: 1; }
.item { padding: 12px 15px; /* border-bottom: 1px solid #f0f0f0; */ /* #ifndef APP-NVUE */ display: flex; /* #endif */ flex-direction: row; justify-content: space-between; }
.is-disabled { opacity: .5; }
.item-text { /* flex: 1; */ color: #333333; }
.item-text-overflow { width: 280px; /* fix nvue */ overflow: hidden; /* #ifndef APP-NVUE */ width: 20em; white-space: nowrap; text-overflow: ellipsis; -o-text-overflow: ellipsis; /* #endif */ }
.check { margin-right: 5px; border: 2px solid $uni-primary; border-left: 0; border-top: 0; height: 12px; width: 6px; transform-origin: center; /* #ifndef APP-NVUE */ transition: all 0.3s; /* #endif */ transform: rotate(45deg); } </style>
|