init
This commit is contained in:
		
							
								
								
									
										75
									
								
								uni_modules/uni-data-picker/changelog.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										75
									
								
								uni_modules/uni-data-picker/changelog.md
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,75 @@
 | 
			
		||||
## 1.1.2(2023-04-11)
 | 
			
		||||
- 修复 更改 modelValue 报错的 bug
 | 
			
		||||
- 修复 v-for 未使用 key 值控制台 warning
 | 
			
		||||
## 1.1.1(2023-02-21)
 | 
			
		||||
- 修复代码合并时引发 value 属性为空时不渲染数据的问题
 | 
			
		||||
## 1.1.0(2023-02-15)
 | 
			
		||||
- 修复 localdata 不支持动态更新的bug
 | 
			
		||||
## 1.0.9(2023-02-15)
 | 
			
		||||
- 修复 localdata 不支持动态更新的bug
 | 
			
		||||
## 1.0.8(2022-09-16)
 | 
			
		||||
- 可以使用 uni-scss 控制主题色
 | 
			
		||||
## 1.0.7(2022-07-06)
 | 
			
		||||
- 优化 pc端图标位置不正确的问题
 | 
			
		||||
## 1.0.6(2022-07-05)
 | 
			
		||||
- 优化 显示样式
 | 
			
		||||
## 1.0.5(2022-07-04)
 | 
			
		||||
- 修复 uni-data-picker 在 uni-forms-item 中宽度不正确的bug
 | 
			
		||||
## 1.0.4(2022-04-19)
 | 
			
		||||
- 修复 字节小程序 本地数据无法选择下一级的Bug
 | 
			
		||||
## 1.0.3(2022-02-25)
 | 
			
		||||
- 修复 nvue 不支持的 v-show 的 bug
 | 
			
		||||
## 1.0.2(2022-02-25)
 | 
			
		||||
- 修复 条件编译 nvue 不支持的 css 样式
 | 
			
		||||
## 1.0.1(2021-11-23)
 | 
			
		||||
- 修复 由上个版本引发的map、v-model等属性不生效的bug
 | 
			
		||||
## 1.0.0(2021-11-19)
 | 
			
		||||
- 优化 组件 UI,并提供设计资源,详见:[https://uniapp.dcloud.io/component/uniui/resource](https://uniapp.dcloud.io/component/uniui/resource)
 | 
			
		||||
- 文档迁移,详见:[https://uniapp.dcloud.io/component/uniui/uni-data-picker](https://uniapp.dcloud.io/component/uniui/uni-data-picker)
 | 
			
		||||
## 0.4.9(2021-10-28)
 | 
			
		||||
- 修复 VUE2 v-model 概率无效的 bug
 | 
			
		||||
## 0.4.8(2021-10-27)
 | 
			
		||||
- 修复 v-model 概率无效的 bug
 | 
			
		||||
## 0.4.7(2021-10-25)
 | 
			
		||||
- 新增 属性 spaceInfo 服务空间配置 HBuilderX 3.2.11+
 | 
			
		||||
- 修复 树型 uniCloud 数据类型为 int 时报错的 bug
 | 
			
		||||
## 0.4.6(2021-10-19)
 | 
			
		||||
- 修复 非 VUE3 v-model 为 0 时无法选中的 bug
 | 
			
		||||
## 0.4.5(2021-09-26)
 | 
			
		||||
- 新增 清除已选项的功能(通过 clearIcon 属性配置是否显示按钮),同时提供 clear 方法以供调用,二者等效
 | 
			
		||||
- 修复 readonly 为 true 时报错的 bug
 | 
			
		||||
## 0.4.4(2021-09-26)
 | 
			
		||||
- 修复 上一版本造成的 map 属性失效的 bug
 | 
			
		||||
- 新增 ellipsis 属性,支持配置 tab 选项长度过长时是否自动省略
 | 
			
		||||
## 0.4.3(2021-09-24)
 | 
			
		||||
- 修复 某些情况下级联未触发的 bug
 | 
			
		||||
## 0.4.2(2021-09-23)
 | 
			
		||||
- 新增 提供 show 和 hide 方法,开发者可以通过 ref 调用
 | 
			
		||||
- 新增 选项内容过长自动添加省略号
 | 
			
		||||
## 0.4.1(2021-09-15)
 | 
			
		||||
- 新增 map 属性 字段映射,将 text/value 映射到数据中的其他字段
 | 
			
		||||
## 0.4.0(2021-07-13)
 | 
			
		||||
- 组件兼容 vue3,如何创建 vue3 项目,详见 [uni-app 项目支持 vue3 介绍](https://ask.dcloud.net.cn/article/37834)
 | 
			
		||||
## 0.3.5(2021-06-04)
 | 
			
		||||
- 修复 无法加载云端数据的问题
 | 
			
		||||
## 0.3.4(2021-05-28)
 | 
			
		||||
- 修复 v-model 无效问题
 | 
			
		||||
- 修复 loaddata 为空数据组时加载时间过长问题
 | 
			
		||||
- 修复 上个版本引出的本地数据无法选择带有 children 的 2 级节点
 | 
			
		||||
## 0.3.3(2021-05-12)
 | 
			
		||||
- 新增 组件示例地址
 | 
			
		||||
## 0.3.2(2021-04-22)
 | 
			
		||||
- 修复 非树形数据有 where 属性查询报错的问题
 | 
			
		||||
## 0.3.1(2021-04-15)
 | 
			
		||||
- 修复 本地数据概率无法回显时问题
 | 
			
		||||
## 0.3.0(2021-04-07)
 | 
			
		||||
- 新增 支持云端非树形表结构数据
 | 
			
		||||
- 修复 根节点 parent_field 字段等于 null 时选择界面错乱问题
 | 
			
		||||
## 0.2.0(2021-03-15)
 | 
			
		||||
- 修复 nodeclick、popupopened、popupclosed 事件无法触发的问题
 | 
			
		||||
## 0.1.9(2021-03-09)
 | 
			
		||||
- 修复 微信小程序某些情况下无法选择的问题
 | 
			
		||||
## 0.1.8(2021-02-05)
 | 
			
		||||
- 优化 部分样式在 nvue 上的兼容表现
 | 
			
		||||
## 0.1.7(2021-02-05)
 | 
			
		||||
- 调整为 uni_modules 目录规范
 | 
			
		||||
@@ -0,0 +1,45 @@
 | 
			
		||||
// #ifdef H5
 | 
			
		||||
export default {
 | 
			
		||||
  name: 'Keypress',
 | 
			
		||||
  props: {
 | 
			
		||||
    disable: {
 | 
			
		||||
      type: Boolean,
 | 
			
		||||
      default: false
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
  mounted () {
 | 
			
		||||
    const keyNames = {
 | 
			
		||||
      esc: ['Esc', 'Escape'],
 | 
			
		||||
      tab: 'Tab',
 | 
			
		||||
      enter: 'Enter',
 | 
			
		||||
      space: [' ', 'Spacebar'],
 | 
			
		||||
      up: ['Up', 'ArrowUp'],
 | 
			
		||||
      left: ['Left', 'ArrowLeft'],
 | 
			
		||||
      right: ['Right', 'ArrowRight'],
 | 
			
		||||
      down: ['Down', 'ArrowDown'],
 | 
			
		||||
      delete: ['Backspace', 'Delete', 'Del']
 | 
			
		||||
    }
 | 
			
		||||
    const listener = ($event) => {
 | 
			
		||||
      if (this.disable) {
 | 
			
		||||
        return
 | 
			
		||||
      }
 | 
			
		||||
      const keyName = Object.keys(keyNames).find(key => {
 | 
			
		||||
        const keyName = $event.key
 | 
			
		||||
        const value = keyNames[key]
 | 
			
		||||
        return value === keyName || (Array.isArray(value) && value.includes(keyName))
 | 
			
		||||
      })
 | 
			
		||||
      if (keyName) {
 | 
			
		||||
        // 避免和其他按键事件冲突
 | 
			
		||||
        setTimeout(() => {
 | 
			
		||||
          this.$emit(keyName, {})
 | 
			
		||||
        }, 0)
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
    document.addEventListener('keyup', listener)
 | 
			
		||||
    this.$once('hook:beforeDestroy', () => {
 | 
			
		||||
      document.removeEventListener('keyup', listener)
 | 
			
		||||
    })
 | 
			
		||||
  },
 | 
			
		||||
	render: () => {}
 | 
			
		||||
}
 | 
			
		||||
// #endif
 | 
			
		||||
@@ -0,0 +1,551 @@
 | 
			
		||||
<template>
 | 
			
		||||
  <view class="uni-data-tree">
 | 
			
		||||
    <view class="uni-data-tree-input" @click="handleInput">
 | 
			
		||||
      <slot :options="options" :data="inputSelected" :error="errorMessage">
 | 
			
		||||
        <view class="input-value" :class="{'input-value-border': border}">
 | 
			
		||||
          <text v-if="errorMessage" class="selected-area error-text">{{errorMessage}}</text>
 | 
			
		||||
          <view v-else-if="loading && !isOpened" class="selected-area">
 | 
			
		||||
            <uni-load-more class="load-more" :contentText="loadMore" status="loading"></uni-load-more>
 | 
			
		||||
          </view>
 | 
			
		||||
          <scroll-view v-else-if="inputSelected.length" class="selected-area" scroll-x="true">
 | 
			
		||||
            <view class="selected-list">
 | 
			
		||||
              <view class="selected-item" v-for="(item,index) in inputSelected" :key="index">
 | 
			
		||||
                <text class="text-color">{{item.text}}</text><text v-if="index<inputSelected.length-1"
 | 
			
		||||
                  class="input-split-line">{{split}}</text>
 | 
			
		||||
              </view>
 | 
			
		||||
            </view>
 | 
			
		||||
          </scroll-view>
 | 
			
		||||
          <text v-else class="selected-area placeholder">{{placeholder}}</text>
 | 
			
		||||
          <view v-if="clearIcon && !readonly && inputSelected.length" class="icon-clear" @click.stop="clear">
 | 
			
		||||
            <uni-icons type="clear" color="#c0c4cc" size="24"></uni-icons>
 | 
			
		||||
          </view>
 | 
			
		||||
          <view class="arrow-area" v-if="(!clearIcon || !inputSelected.length) && !readonly ">
 | 
			
		||||
            <view class="input-arrow"></view>
 | 
			
		||||
          </view>
 | 
			
		||||
        </view>
 | 
			
		||||
      </slot>
 | 
			
		||||
    </view>
 | 
			
		||||
    <view class="uni-data-tree-cover" v-if="isOpened" @click="handleClose"></view>
 | 
			
		||||
    <view class="uni-data-tree-dialog" v-if="isOpened">
 | 
			
		||||
      <view class="uni-popper__arrow"></view>
 | 
			
		||||
      <view class="dialog-caption">
 | 
			
		||||
        <view class="title-area">
 | 
			
		||||
          <text class="dialog-title">{{popupTitle}}</text>
 | 
			
		||||
        </view>
 | 
			
		||||
        <view class="dialog-close" @click="handleClose">
 | 
			
		||||
          <view class="dialog-close-plus" data-id="close"></view>
 | 
			
		||||
          <view class="dialog-close-plus dialog-close-rotate" data-id="close"></view>
 | 
			
		||||
        </view>
 | 
			
		||||
      </view>
 | 
			
		||||
      <data-picker-view class="picker-view" ref="pickerView" v-model="dataValue" :localdata="localdata"
 | 
			
		||||
        :preload="preload" :collection="collection" :field="field" :orderby="orderby" :where="where"
 | 
			
		||||
        :step-searh="stepSearh" :self-field="selfField" :parent-field="parentField" :managed-mode="true" :map="map"
 | 
			
		||||
        :ellipsis="ellipsis" @change="onchange" @datachange="ondatachange" @nodeclick="onnodeclick">
 | 
			
		||||
      </data-picker-view>
 | 
			
		||||
    </view>
 | 
			
		||||
  </view>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script>
 | 
			
		||||
  import dataPicker from "../uni-data-pickerview/uni-data-picker.js"
 | 
			
		||||
  import DataPickerView from "../uni-data-pickerview/uni-data-pickerview.vue"
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * DataPicker 级联选择
 | 
			
		||||
   * @description 支持单列、和多列级联选择。列数没有限制,如果屏幕显示不全,顶部tab区域会左右滚动。
 | 
			
		||||
   * @tutorial https://ext.dcloud.net.cn/plugin?id=3796
 | 
			
		||||
   * @property {String} popup-title 弹出窗口标题
 | 
			
		||||
   * @property {Array} localdata 本地数据,参考
 | 
			
		||||
   * @property {Boolean} border = [true|false] 是否有边框
 | 
			
		||||
   * @property {Boolean} readonly = [true|false] 是否仅读
 | 
			
		||||
   * @property {Boolean} preload = [true|false] 是否预加载数据
 | 
			
		||||
   * @value true 开启预加载数据,点击弹出窗口后显示已加载数据
 | 
			
		||||
   * @value false 关闭预加载数据,点击弹出窗口后开始加载数据
 | 
			
		||||
   * @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 查询条件
 | 
			
		||||
   * @event {Function} popupshow 弹出的选择窗口打开时触发此事件
 | 
			
		||||
   * @event {Function} popuphide 弹出的选择窗口关闭时触发此事件
 | 
			
		||||
   */
 | 
			
		||||
  export default {
 | 
			
		||||
    name: 'UniDataPicker',
 | 
			
		||||
    emits: ['popupopened', 'popupclosed', 'nodeclick', 'input', 'change', 'update:modelValue','inputclick'],
 | 
			
		||||
    mixins: [dataPicker],
 | 
			
		||||
    components: {
 | 
			
		||||
      DataPickerView
 | 
			
		||||
    },
 | 
			
		||||
    props: {
 | 
			
		||||
      options: {
 | 
			
		||||
        type: [Object, Array],
 | 
			
		||||
        default () {
 | 
			
		||||
          return {}
 | 
			
		||||
        }
 | 
			
		||||
      },
 | 
			
		||||
      popupTitle: {
 | 
			
		||||
        type: String,
 | 
			
		||||
        default: '请选择'
 | 
			
		||||
      },
 | 
			
		||||
      placeholder: {
 | 
			
		||||
        type: String,
 | 
			
		||||
        default: '请选择'
 | 
			
		||||
      },
 | 
			
		||||
      heightMobile: {
 | 
			
		||||
        type: String,
 | 
			
		||||
        default: ''
 | 
			
		||||
      },
 | 
			
		||||
      readonly: {
 | 
			
		||||
        type: Boolean,
 | 
			
		||||
        default: false
 | 
			
		||||
      },
 | 
			
		||||
      clearIcon: {
 | 
			
		||||
        type: Boolean,
 | 
			
		||||
        default: true
 | 
			
		||||
      },
 | 
			
		||||
      border: {
 | 
			
		||||
        type: Boolean,
 | 
			
		||||
        default: true
 | 
			
		||||
      },
 | 
			
		||||
      split: {
 | 
			
		||||
        type: String,
 | 
			
		||||
        default: '/'
 | 
			
		||||
      },
 | 
			
		||||
      ellipsis: {
 | 
			
		||||
        type: Boolean,
 | 
			
		||||
        default: true
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    data() {
 | 
			
		||||
      return {
 | 
			
		||||
        isOpened: false,
 | 
			
		||||
        inputSelected: []
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    created() {
 | 
			
		||||
      this.$nextTick(() => {
 | 
			
		||||
        this.load();
 | 
			
		||||
      })
 | 
			
		||||
    },
 | 
			
		||||
    watch: {
 | 
			
		||||
			localdata: {
 | 
			
		||||
				handler() {
 | 
			
		||||
					this.load()
 | 
			
		||||
				},
 | 
			
		||||
        deep: true
 | 
			
		||||
			},
 | 
			
		||||
    },
 | 
			
		||||
    methods: {
 | 
			
		||||
      clear() {
 | 
			
		||||
        this._dispatchEvent([]);
 | 
			
		||||
      },
 | 
			
		||||
      onPropsChange() {
 | 
			
		||||
        this._treeData = [];
 | 
			
		||||
        this.selectedIndex = 0;
 | 
			
		||||
 | 
			
		||||
        this.load();
 | 
			
		||||
      },
 | 
			
		||||
      load() {
 | 
			
		||||
        if (this.readonly) {
 | 
			
		||||
          this._processReadonly(this.localdata, this.dataValue);
 | 
			
		||||
          return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // 回显本地数据
 | 
			
		||||
        if (this.isLocalData) {
 | 
			
		||||
          this.loadData();
 | 
			
		||||
          this.inputSelected = this.selected.slice(0);
 | 
			
		||||
        } else if (this.isCloudDataList || this.isCloudDataTree) { // 回显 Cloud 数据
 | 
			
		||||
          this.loading = true;
 | 
			
		||||
          this.getCloudDataValue().then((res) => {
 | 
			
		||||
            this.loading = false;
 | 
			
		||||
            this.inputSelected = res;
 | 
			
		||||
          }).catch((err) => {
 | 
			
		||||
            this.loading = false;
 | 
			
		||||
            this.errorMessage = err;
 | 
			
		||||
          })
 | 
			
		||||
        }
 | 
			
		||||
      },
 | 
			
		||||
      show() {
 | 
			
		||||
        this.isOpened = true
 | 
			
		||||
        setTimeout(() => {
 | 
			
		||||
          this.$refs.pickerView.updateData({
 | 
			
		||||
            treeData: this._treeData,
 | 
			
		||||
            selected: this.selected,
 | 
			
		||||
            selectedIndex: this.selectedIndex
 | 
			
		||||
          })
 | 
			
		||||
        }, 200)
 | 
			
		||||
        this.$emit('popupopened')
 | 
			
		||||
      },
 | 
			
		||||
      hide() {
 | 
			
		||||
        this.isOpened = false
 | 
			
		||||
        this.$emit('popupclosed')
 | 
			
		||||
      },
 | 
			
		||||
      handleInput() {
 | 
			
		||||
        if (this.readonly) {
 | 
			
		||||
					this.$emit('inputclick')
 | 
			
		||||
          return
 | 
			
		||||
        }
 | 
			
		||||
        this.show()
 | 
			
		||||
      },
 | 
			
		||||
      handleClose(e) {
 | 
			
		||||
        this.hide()
 | 
			
		||||
      },
 | 
			
		||||
      onnodeclick(e) {
 | 
			
		||||
        this.$emit('nodeclick', e)
 | 
			
		||||
      },
 | 
			
		||||
      ondatachange(e) {
 | 
			
		||||
        this._treeData = this.$refs.pickerView._treeData
 | 
			
		||||
      },
 | 
			
		||||
      onchange(e) {
 | 
			
		||||
        this.hide()
 | 
			
		||||
        this.$nextTick(() => {
 | 
			
		||||
          this.inputSelected = e;
 | 
			
		||||
        })
 | 
			
		||||
        this._dispatchEvent(e)
 | 
			
		||||
      },
 | 
			
		||||
      _processReadonly(dataList, value) {
 | 
			
		||||
        var isTree = dataList.findIndex((item) => {
 | 
			
		||||
          return item.children
 | 
			
		||||
        })
 | 
			
		||||
        if (isTree > -1) {
 | 
			
		||||
          let inputValue
 | 
			
		||||
          if (Array.isArray(value)) {
 | 
			
		||||
            inputValue = value[value.length - 1]
 | 
			
		||||
            if (typeof inputValue === 'object' && inputValue.value) {
 | 
			
		||||
              inputValue = inputValue.value
 | 
			
		||||
            }
 | 
			
		||||
          } else {
 | 
			
		||||
            inputValue = value
 | 
			
		||||
          }
 | 
			
		||||
          this.inputSelected = this._findNodePath(inputValue, this.localdata)
 | 
			
		||||
          return
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (!this.hasValue) {
 | 
			
		||||
          this.inputSelected = []
 | 
			
		||||
          return
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        let result = []
 | 
			
		||||
        for (let i = 0; i < value.length; i++) {
 | 
			
		||||
          var val = value[i]
 | 
			
		||||
          var item = dataList.find((v) => {
 | 
			
		||||
            return v.value == val
 | 
			
		||||
          })
 | 
			
		||||
          if (item) {
 | 
			
		||||
            result.push(item)
 | 
			
		||||
          }
 | 
			
		||||
        }
 | 
			
		||||
        if (result.length) {
 | 
			
		||||
          this.inputSelected = result
 | 
			
		||||
        }
 | 
			
		||||
      },
 | 
			
		||||
      _filterForArray(data, valueArray) {
 | 
			
		||||
        var result = []
 | 
			
		||||
        for (let i = 0; i < valueArray.length; i++) {
 | 
			
		||||
          var value = valueArray[i]
 | 
			
		||||
          var found = data.find((item) => {
 | 
			
		||||
            return item.value == value
 | 
			
		||||
          })
 | 
			
		||||
          if (found) {
 | 
			
		||||
            result.push(found)
 | 
			
		||||
          }
 | 
			
		||||
        }
 | 
			
		||||
        return result
 | 
			
		||||
      },
 | 
			
		||||
      _dispatchEvent(selected) {
 | 
			
		||||
        let item = {}
 | 
			
		||||
        if (selected.length) {
 | 
			
		||||
          var value = new Array(selected.length)
 | 
			
		||||
          for (var i = 0; i < selected.length; i++) {
 | 
			
		||||
            value[i] = selected[i].value
 | 
			
		||||
          }
 | 
			
		||||
          item = selected[selected.length - 1]
 | 
			
		||||
        } else {
 | 
			
		||||
          item.value = ''
 | 
			
		||||
        }
 | 
			
		||||
        if (this.formItem) {
 | 
			
		||||
          this.formItem.setValue(item.value)
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        this.$emit('input', item.value)
 | 
			
		||||
        this.$emit('update:modelValue', item.value)
 | 
			
		||||
        this.$emit('change', {
 | 
			
		||||
          detail: {
 | 
			
		||||
            value: selected
 | 
			
		||||
          }
 | 
			
		||||
        })
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
<style>
 | 
			
		||||
  .uni-data-tree {
 | 
			
		||||
    flex: 1;
 | 
			
		||||
    position: relative;
 | 
			
		||||
    font-size: 14px;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  .error-text {
 | 
			
		||||
    color: #DD524D;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  .input-value {
 | 
			
		||||
    /* #ifndef APP-NVUE */
 | 
			
		||||
    display: flex;
 | 
			
		||||
    /* #endif */
 | 
			
		||||
    flex-direction: row;
 | 
			
		||||
    align-items: center;
 | 
			
		||||
    flex-wrap: nowrap;
 | 
			
		||||
    font-size: 14px;
 | 
			
		||||
    /* line-height: 35px; */
 | 
			
		||||
    padding: 0 10px;
 | 
			
		||||
    padding-right: 5px;
 | 
			
		||||
    overflow: hidden;
 | 
			
		||||
    height: 35px;
 | 
			
		||||
    /* #ifndef APP-NVUE */
 | 
			
		||||
    box-sizing: border-box;
 | 
			
		||||
    /* #endif */
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  .input-value-border {
 | 
			
		||||
    border: 1px solid #e5e5e5;
 | 
			
		||||
    border-radius: 5px;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  .selected-area {
 | 
			
		||||
    flex: 1;
 | 
			
		||||
    overflow: hidden;
 | 
			
		||||
    /* #ifndef APP-NVUE */
 | 
			
		||||
    display: flex;
 | 
			
		||||
    /* #endif */
 | 
			
		||||
    flex-direction: row;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  .load-more {
 | 
			
		||||
    /* #ifndef APP-NVUE */
 | 
			
		||||
    margin-right: auto;
 | 
			
		||||
    /* #endif */
 | 
			
		||||
    /* #ifdef APP-NVUE */
 | 
			
		||||
    width: 40px;
 | 
			
		||||
    /* #endif */
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  .selected-list {
 | 
			
		||||
    /* #ifndef APP-NVUE */
 | 
			
		||||
    display: flex;
 | 
			
		||||
    /* #endif */
 | 
			
		||||
    flex-direction: row;
 | 
			
		||||
    flex-wrap: nowrap;
 | 
			
		||||
    /* padding: 0 5px; */
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  .selected-item {
 | 
			
		||||
    flex-direction: row;
 | 
			
		||||
    /* padding: 0 1px; */
 | 
			
		||||
    /* #ifndef APP-NVUE */
 | 
			
		||||
    white-space: nowrap;
 | 
			
		||||
    /* #endif */
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  .text-color {
 | 
			
		||||
    color: #333;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  .placeholder {
 | 
			
		||||
    color: grey;
 | 
			
		||||
    font-size: 12px;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  .input-split-line {
 | 
			
		||||
    opacity: .5;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  .arrow-area {
 | 
			
		||||
    position: relative;
 | 
			
		||||
    width: 20px;
 | 
			
		||||
    /* #ifndef APP-NVUE */
 | 
			
		||||
    margin-bottom: 5px;
 | 
			
		||||
    margin-left: auto;
 | 
			
		||||
    display: flex;
 | 
			
		||||
    /* #endif */
 | 
			
		||||
    justify-content: center;
 | 
			
		||||
    transform: rotate(-45deg);
 | 
			
		||||
    transform-origin: center;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  .input-arrow {
 | 
			
		||||
    width: 7px;
 | 
			
		||||
    height: 7px;
 | 
			
		||||
    border-left: 1px solid #999;
 | 
			
		||||
    border-bottom: 1px solid #999;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  .uni-data-tree-cover {
 | 
			
		||||
    position: fixed;
 | 
			
		||||
    left: 0;
 | 
			
		||||
    top: 0;
 | 
			
		||||
    right: 0;
 | 
			
		||||
    bottom: 0;
 | 
			
		||||
    background-color: rgba(0, 0, 0, .4);
 | 
			
		||||
    /* #ifndef APP-NVUE */
 | 
			
		||||
    display: flex;
 | 
			
		||||
    /* #endif */
 | 
			
		||||
    flex-direction: column;
 | 
			
		||||
    z-index: 100;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  .uni-data-tree-dialog {
 | 
			
		||||
    position: fixed;
 | 
			
		||||
    left: 0;
 | 
			
		||||
    /* #ifndef APP-NVUE */
 | 
			
		||||
    top: 20%;
 | 
			
		||||
    /* #endif */
 | 
			
		||||
    /* #ifdef APP-NVUE */
 | 
			
		||||
    top: 200px;
 | 
			
		||||
    /* #endif */
 | 
			
		||||
    right: 0;
 | 
			
		||||
    bottom: 0;
 | 
			
		||||
    background-color: #FFFFFF;
 | 
			
		||||
    border-top-left-radius: 10px;
 | 
			
		||||
    border-top-right-radius: 10px;
 | 
			
		||||
    /* #ifndef APP-NVUE */
 | 
			
		||||
    display: flex;
 | 
			
		||||
    /* #endif */
 | 
			
		||||
    flex-direction: column;
 | 
			
		||||
    z-index: 102;
 | 
			
		||||
    overflow: hidden;
 | 
			
		||||
    /* #ifdef APP-NVUE */
 | 
			
		||||
    width: 750rpx;
 | 
			
		||||
    /* #endif */
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  .dialog-caption {
 | 
			
		||||
    position: relative;
 | 
			
		||||
    /* #ifndef APP-NVUE */
 | 
			
		||||
    display: flex;
 | 
			
		||||
    /* #endif */
 | 
			
		||||
    flex-direction: row;
 | 
			
		||||
    /* border-bottom: 1px solid #f0f0f0; */
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  .title-area {
 | 
			
		||||
    /* #ifndef APP-NVUE */
 | 
			
		||||
    display: flex;
 | 
			
		||||
    /* #endif */
 | 
			
		||||
    align-items: center;
 | 
			
		||||
    /* #ifndef APP-NVUE */
 | 
			
		||||
    margin: auto;
 | 
			
		||||
    /* #endif */
 | 
			
		||||
    padding: 0 10px;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  .dialog-title {
 | 
			
		||||
    /* font-weight: bold; */
 | 
			
		||||
    line-height: 44px;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  .dialog-close {
 | 
			
		||||
    position: absolute;
 | 
			
		||||
    top: 0;
 | 
			
		||||
    right: 0;
 | 
			
		||||
    bottom: 0;
 | 
			
		||||
    /* #ifndef APP-NVUE */
 | 
			
		||||
    display: flex;
 | 
			
		||||
    /* #endif */
 | 
			
		||||
    flex-direction: row;
 | 
			
		||||
    align-items: center;
 | 
			
		||||
    padding: 0 15px;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  .dialog-close-plus {
 | 
			
		||||
    width: 16px;
 | 
			
		||||
    height: 2px;
 | 
			
		||||
    background-color: #666;
 | 
			
		||||
    border-radius: 2px;
 | 
			
		||||
    transform: rotate(45deg);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  .dialog-close-rotate {
 | 
			
		||||
    position: absolute;
 | 
			
		||||
    transform: rotate(-45deg);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  .picker-view {
 | 
			
		||||
    flex: 1;
 | 
			
		||||
    overflow: hidden;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  .icon-clear {
 | 
			
		||||
    display: flex;
 | 
			
		||||
    align-items: center;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /* #ifdef H5 */
 | 
			
		||||
  @media all and (min-width: 768px) {
 | 
			
		||||
    .uni-data-tree-cover {
 | 
			
		||||
      background-color: transparent;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    .uni-data-tree-dialog {
 | 
			
		||||
      position: absolute;
 | 
			
		||||
      top: 55px;
 | 
			
		||||
      height: auto;
 | 
			
		||||
      min-height: 400px;
 | 
			
		||||
      max-height: 50vh;
 | 
			
		||||
      background-color: #fff;
 | 
			
		||||
      border: 1px solid #EBEEF5;
 | 
			
		||||
      box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
 | 
			
		||||
      border-radius: 4px;
 | 
			
		||||
      overflow: unset;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    .dialog-caption {
 | 
			
		||||
      display: none;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    .icon-clear {
 | 
			
		||||
      /* margin-right: 5px; */
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /* #endif */
 | 
			
		||||
 | 
			
		||||
  /* picker 弹出层通用的指示小三角, todo:扩展至上下左右方向定位 */
 | 
			
		||||
  /* #ifndef APP-NVUE */
 | 
			
		||||
  .uni-popper__arrow,
 | 
			
		||||
  .uni-popper__arrow::after {
 | 
			
		||||
    position: absolute;
 | 
			
		||||
    display: block;
 | 
			
		||||
    width: 0;
 | 
			
		||||
    height: 0;
 | 
			
		||||
    border-color: transparent;
 | 
			
		||||
    border-style: solid;
 | 
			
		||||
    border-width: 6px;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  .uni-popper__arrow {
 | 
			
		||||
    filter: drop-shadow(0 2px 12px rgba(0, 0, 0, 0.03));
 | 
			
		||||
    top: -6px;
 | 
			
		||||
    left: 10%;
 | 
			
		||||
    margin-right: 3px;
 | 
			
		||||
    border-top-width: 0;
 | 
			
		||||
    border-bottom-color: #EBEEF5;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  .uni-popper__arrow::after {
 | 
			
		||||
    content: " ";
 | 
			
		||||
    top: 1px;
 | 
			
		||||
    margin-left: -6px;
 | 
			
		||||
    border-top-width: 0;
 | 
			
		||||
    border-bottom-color: #fff;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /* #endif */
 | 
			
		||||
</style>
 | 
			
		||||
@@ -0,0 +1,622 @@
 | 
			
		||||
export default {
 | 
			
		||||
  props: {
 | 
			
		||||
    localdata: {
 | 
			
		||||
      type: [Array, Object],
 | 
			
		||||
      default () {
 | 
			
		||||
        return []
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    spaceInfo: {
 | 
			
		||||
      type: Object,
 | 
			
		||||
      default () {
 | 
			
		||||
        return {}
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    collection: {
 | 
			
		||||
      type: String,
 | 
			
		||||
      default: ''
 | 
			
		||||
    },
 | 
			
		||||
    action: {
 | 
			
		||||
      type: String,
 | 
			
		||||
      default: ''
 | 
			
		||||
    },
 | 
			
		||||
    field: {
 | 
			
		||||
      type: String,
 | 
			
		||||
      default: ''
 | 
			
		||||
    },
 | 
			
		||||
    orderby: {
 | 
			
		||||
      type: String,
 | 
			
		||||
      default: ''
 | 
			
		||||
    },
 | 
			
		||||
    where: {
 | 
			
		||||
      type: [String, Object],
 | 
			
		||||
      default: ''
 | 
			
		||||
    },
 | 
			
		||||
    pageData: {
 | 
			
		||||
      type: String,
 | 
			
		||||
      default: 'add'
 | 
			
		||||
    },
 | 
			
		||||
    pageCurrent: {
 | 
			
		||||
      type: Number,
 | 
			
		||||
      default: 1
 | 
			
		||||
    },
 | 
			
		||||
    pageSize: {
 | 
			
		||||
      type: Number,
 | 
			
		||||
      default: 500
 | 
			
		||||
    },
 | 
			
		||||
    getcount: {
 | 
			
		||||
      type: [Boolean, String],
 | 
			
		||||
      default: false
 | 
			
		||||
    },
 | 
			
		||||
    getone: {
 | 
			
		||||
      type: [Boolean, String],
 | 
			
		||||
      default: false
 | 
			
		||||
    },
 | 
			
		||||
    gettree: {
 | 
			
		||||
      type: [Boolean, String],
 | 
			
		||||
      default: false
 | 
			
		||||
    },
 | 
			
		||||
    manual: {
 | 
			
		||||
      type: Boolean,
 | 
			
		||||
      default: false
 | 
			
		||||
    },
 | 
			
		||||
    value: {
 | 
			
		||||
      type: [Array, String, Number],
 | 
			
		||||
      default () {
 | 
			
		||||
        return []
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    modelValue: {
 | 
			
		||||
      type: [Array, String, Number],
 | 
			
		||||
      default () {
 | 
			
		||||
        return []
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    preload: {
 | 
			
		||||
      type: Boolean,
 | 
			
		||||
      default: false
 | 
			
		||||
    },
 | 
			
		||||
    stepSearh: {
 | 
			
		||||
      type: Boolean,
 | 
			
		||||
      default: true
 | 
			
		||||
    },
 | 
			
		||||
    selfField: {
 | 
			
		||||
      type: String,
 | 
			
		||||
      default: ''
 | 
			
		||||
    },
 | 
			
		||||
    parentField: {
 | 
			
		||||
      type: String,
 | 
			
		||||
      default: ''
 | 
			
		||||
    },
 | 
			
		||||
    multiple: {
 | 
			
		||||
      type: Boolean,
 | 
			
		||||
      default: false
 | 
			
		||||
    },
 | 
			
		||||
    map: {
 | 
			
		||||
      type: Object,
 | 
			
		||||
      default () {
 | 
			
		||||
        return {
 | 
			
		||||
          text: "text",
 | 
			
		||||
          value: "value"
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
  data() {
 | 
			
		||||
    return {
 | 
			
		||||
      loading: false,
 | 
			
		||||
      errorMessage: '',
 | 
			
		||||
      loadMore: {
 | 
			
		||||
        contentdown: '',
 | 
			
		||||
        contentrefresh: '',
 | 
			
		||||
        contentnomore: ''
 | 
			
		||||
      },
 | 
			
		||||
      dataList: [],
 | 
			
		||||
      selected: [],
 | 
			
		||||
      selectedIndex: 0,
 | 
			
		||||
      page: {
 | 
			
		||||
        current: this.pageCurrent,
 | 
			
		||||
        size: this.pageSize,
 | 
			
		||||
        count: 0
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
  computed: {
 | 
			
		||||
    isLocalData() {
 | 
			
		||||
      return !this.collection.length;
 | 
			
		||||
    },
 | 
			
		||||
    isCloudData() {
 | 
			
		||||
      return this.collection.length > 0;
 | 
			
		||||
    },
 | 
			
		||||
    isCloudDataList() {
 | 
			
		||||
      return (this.isCloudData && (!this.parentField && !this.selfField));
 | 
			
		||||
    },
 | 
			
		||||
    isCloudDataTree() {
 | 
			
		||||
      return (this.isCloudData && this.parentField && this.selfField);
 | 
			
		||||
    },
 | 
			
		||||
    dataValue() {
 | 
			
		||||
      let isModelValue = Array.isArray(this.modelValue) ? (this.modelValue.length > 0) : (this.modelValue !== null ||
 | 
			
		||||
        this.modelValue !== undefined);
 | 
			
		||||
      return isModelValue ? this.modelValue : this.value;
 | 
			
		||||
    },
 | 
			
		||||
    hasValue() {
 | 
			
		||||
      if (typeof this.dataValue === 'number') {
 | 
			
		||||
        return true
 | 
			
		||||
      }
 | 
			
		||||
      return (this.dataValue != null) && (this.dataValue.length > 0)
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
  created() {
 | 
			
		||||
    this.$watch(() => {
 | 
			
		||||
      var al = [];
 | 
			
		||||
      ['pageCurrent',
 | 
			
		||||
        'pageSize',
 | 
			
		||||
        'spaceInfo',
 | 
			
		||||
        'value',
 | 
			
		||||
        'modelValue',
 | 
			
		||||
        'localdata',
 | 
			
		||||
        'collection',
 | 
			
		||||
        'action',
 | 
			
		||||
        'field',
 | 
			
		||||
        'orderby',
 | 
			
		||||
        'where',
 | 
			
		||||
        'getont',
 | 
			
		||||
        'getcount',
 | 
			
		||||
        'gettree'
 | 
			
		||||
      ].forEach(key => {
 | 
			
		||||
        al.push(this[key])
 | 
			
		||||
      });
 | 
			
		||||
      return al
 | 
			
		||||
    }, (newValue, oldValue) => {
 | 
			
		||||
      let needReset = false
 | 
			
		||||
      for (let i = 2; i < newValue.length; i++) {
 | 
			
		||||
        if (newValue[i] != oldValue[i]) {
 | 
			
		||||
          needReset = true
 | 
			
		||||
          break
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
      if (newValue[0] != oldValue[0]) {
 | 
			
		||||
        this.page.current = this.pageCurrent
 | 
			
		||||
      }
 | 
			
		||||
      this.page.size = this.pageSize
 | 
			
		||||
 | 
			
		||||
      this.onPropsChange()
 | 
			
		||||
    })
 | 
			
		||||
    this._treeData = []
 | 
			
		||||
  },
 | 
			
		||||
  methods: {
 | 
			
		||||
    onPropsChange() {
 | 
			
		||||
      this._treeData = [];
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    // 填充 pickview 数据
 | 
			
		||||
    async loadData() {
 | 
			
		||||
      if (this.isLocalData) {
 | 
			
		||||
        this.loadLocalData();
 | 
			
		||||
      } else if (this.isCloudDataList) {
 | 
			
		||||
        this.loadCloudDataList();
 | 
			
		||||
      } else if (this.isCloudDataTree) {
 | 
			
		||||
        this.loadCloudDataTree();
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    // 加载本地数据
 | 
			
		||||
    async loadLocalData() {
 | 
			
		||||
      this._treeData = [];
 | 
			
		||||
      this._extractTree(this.localdata, this._treeData);
 | 
			
		||||
 | 
			
		||||
      let inputValue = this.dataValue;
 | 
			
		||||
      if (inputValue === undefined) {
 | 
			
		||||
        return;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      if (Array.isArray(inputValue)) {
 | 
			
		||||
        inputValue = inputValue[inputValue.length - 1];
 | 
			
		||||
        if (typeof inputValue === 'object' && inputValue[this.map.value]) {
 | 
			
		||||
          inputValue = inputValue[this.map.value];
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      this.selected = this._findNodePath(inputValue, this.localdata);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    // 加载 Cloud 数据 (单列)
 | 
			
		||||
    async loadCloudDataList() {
 | 
			
		||||
      if (this.loading) {
 | 
			
		||||
        return;
 | 
			
		||||
      }
 | 
			
		||||
      this.loading = true;
 | 
			
		||||
 | 
			
		||||
      try {
 | 
			
		||||
        let response = await this.getCommand();
 | 
			
		||||
        let responseData = response.result.data;
 | 
			
		||||
 | 
			
		||||
        this._treeData = responseData;
 | 
			
		||||
 | 
			
		||||
        this._updateBindData();
 | 
			
		||||
        this._updateSelected();
 | 
			
		||||
 | 
			
		||||
        this.onDataChange();
 | 
			
		||||
      } catch (e) {
 | 
			
		||||
        this.errorMessage = e;
 | 
			
		||||
      } finally {
 | 
			
		||||
        this.loading = false;
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    // 加载 Cloud 数据 (树形)
 | 
			
		||||
    async loadCloudDataTree() {
 | 
			
		||||
      if (this.loading) {
 | 
			
		||||
        return;
 | 
			
		||||
      }
 | 
			
		||||
      this.loading = true;
 | 
			
		||||
 | 
			
		||||
      try {
 | 
			
		||||
        let commandOptions = {
 | 
			
		||||
          field: this._cloudDataPostField(),
 | 
			
		||||
          where: this._cloudDataTreeWhere()
 | 
			
		||||
        };
 | 
			
		||||
        if (this.gettree) {
 | 
			
		||||
          commandOptions.startwith = `${this.selfField}=='${this.dataValue}'`;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        let response = await this.getCommand(commandOptions);
 | 
			
		||||
        let responseData = response.result.data;
 | 
			
		||||
 | 
			
		||||
        this._treeData = responseData;
 | 
			
		||||
        this._updateBindData();
 | 
			
		||||
        this._updateSelected();
 | 
			
		||||
 | 
			
		||||
        this.onDataChange();
 | 
			
		||||
      } catch (e) {
 | 
			
		||||
        this.errorMessage = e;
 | 
			
		||||
      } finally {
 | 
			
		||||
        this.loading = false;
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    // 加载 Cloud 数据 (节点)
 | 
			
		||||
    async loadCloudDataNode(callback) {
 | 
			
		||||
      if (this.loading) {
 | 
			
		||||
        return;
 | 
			
		||||
      }
 | 
			
		||||
      this.loading = true;
 | 
			
		||||
 | 
			
		||||
      try {
 | 
			
		||||
        let commandOptions = {
 | 
			
		||||
          field: this._cloudDataPostField(),
 | 
			
		||||
          where: this._cloudDataNodeWhere()
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        let response = await this.getCommand(commandOptions);
 | 
			
		||||
        let responseData = response.result.data;
 | 
			
		||||
 | 
			
		||||
        callback(responseData);
 | 
			
		||||
      } catch (e) {
 | 
			
		||||
        this.errorMessage = e;
 | 
			
		||||
      } finally {
 | 
			
		||||
        this.loading = false;
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    // 回显 Cloud 数据
 | 
			
		||||
    getCloudDataValue() {
 | 
			
		||||
      if (this.isCloudDataList) {
 | 
			
		||||
        return this.getCloudDataListValue();
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      if (this.isCloudDataTree) {
 | 
			
		||||
        return this.getCloudDataTreeValue();
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    // 回显 Cloud 数据 (单列)
 | 
			
		||||
    getCloudDataListValue() {
 | 
			
		||||
      // 根据 field's as value标识匹配 where 条件
 | 
			
		||||
      let where = [];
 | 
			
		||||
      let whereField = this._getForeignKeyByField();
 | 
			
		||||
      if (whereField) {
 | 
			
		||||
        where.push(`${whereField} == '${this.dataValue}'`)
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      where = where.join(' || ');
 | 
			
		||||
 | 
			
		||||
      if (this.where) {
 | 
			
		||||
        where = `(${this.where}) && (${where})`
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      return this.getCommand({
 | 
			
		||||
        field: this._cloudDataPostField(),
 | 
			
		||||
        where
 | 
			
		||||
      }).then((res) => {
 | 
			
		||||
        this.selected = res.result.data;
 | 
			
		||||
        return res.result.data;
 | 
			
		||||
      });
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    // 回显 Cloud 数据 (树形)
 | 
			
		||||
    getCloudDataTreeValue() {
 | 
			
		||||
      return this.getCommand({
 | 
			
		||||
        field: this._cloudDataPostField(),
 | 
			
		||||
        getTreePath: {
 | 
			
		||||
          startWith: `${this.selfField}=='${this.dataValue}'`
 | 
			
		||||
        }
 | 
			
		||||
      }).then((res) => {
 | 
			
		||||
        let treePath = [];
 | 
			
		||||
        this._extractTreePath(res.result.data, treePath);
 | 
			
		||||
        this.selected = treePath;
 | 
			
		||||
        return treePath;
 | 
			
		||||
      });
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    getCommand(options = {}) {
 | 
			
		||||
      /* eslint-disable no-undef */
 | 
			
		||||
      let db = uniCloud.database(this.spaceInfo)
 | 
			
		||||
 | 
			
		||||
      const action = options.action || this.action
 | 
			
		||||
      if (action) {
 | 
			
		||||
        db = db.action(action)
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      const collection = options.collection || this.collection
 | 
			
		||||
      db = db.collection(collection)
 | 
			
		||||
 | 
			
		||||
      const where = options.where || this.where
 | 
			
		||||
      if (!(!where || !Object.keys(where).length)) {
 | 
			
		||||
        db = db.where(where)
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      const field = options.field || this.field
 | 
			
		||||
      if (field) {
 | 
			
		||||
        db = db.field(field)
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      const orderby = options.orderby || this.orderby
 | 
			
		||||
      if (orderby) {
 | 
			
		||||
        db = db.orderBy(orderby)
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      const current = options.pageCurrent !== undefined ? options.pageCurrent : this.page.current
 | 
			
		||||
      const size = options.pageSize !== undefined ? options.pageSize : this.page.size
 | 
			
		||||
      const getCount = options.getcount !== undefined ? options.getcount : this.getcount
 | 
			
		||||
      const getTree = options.gettree !== undefined ? options.gettree : this.gettree
 | 
			
		||||
 | 
			
		||||
      const getOptions = {
 | 
			
		||||
        getCount,
 | 
			
		||||
        getTree
 | 
			
		||||
      }
 | 
			
		||||
      if (options.getTreePath) {
 | 
			
		||||
        getOptions.getTreePath = options.getTreePath
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      db = db.skip(size * (current - 1)).limit(size).get(getOptions)
 | 
			
		||||
 | 
			
		||||
      return db
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _cloudDataPostField() {
 | 
			
		||||
      let fields = [this.field];
 | 
			
		||||
      if (this.parentField) {
 | 
			
		||||
        fields.push(`${this.parentField} as parent_value`);
 | 
			
		||||
      }
 | 
			
		||||
      return fields.join(',');
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _cloudDataTreeWhere() {
 | 
			
		||||
      let result = []
 | 
			
		||||
      let selected = this.selected
 | 
			
		||||
      let parentField = this.parentField
 | 
			
		||||
      if (parentField) {
 | 
			
		||||
        result.push(`${parentField} == null || ${parentField} == ""`)
 | 
			
		||||
      }
 | 
			
		||||
      if (selected.length) {
 | 
			
		||||
        for (var i = 0; i < selected.length - 1; i++) {
 | 
			
		||||
          result.push(`${parentField} == '${selected[i].value}'`)
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      let where = []
 | 
			
		||||
      if (this.where) {
 | 
			
		||||
        where.push(`(${this.where})`)
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      if (result.length) {
 | 
			
		||||
        where.push(`(${result.join(' || ')})`)
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      return where.join(' && ')
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _cloudDataNodeWhere() {
 | 
			
		||||
      let where = []
 | 
			
		||||
      let selected = this.selected;
 | 
			
		||||
      if (selected.length) {
 | 
			
		||||
        where.push(`${this.parentField} == '${selected[selected.length - 1].value}'`);
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      where = where.join(' || ');
 | 
			
		||||
 | 
			
		||||
      if (this.where) {
 | 
			
		||||
        return `(${this.where}) && (${where})`
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      return where
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _getWhereByForeignKey() {
 | 
			
		||||
      let result = []
 | 
			
		||||
      let whereField = this._getForeignKeyByField();
 | 
			
		||||
      if (whereField) {
 | 
			
		||||
        result.push(`${whereField} == '${this.dataValue}'`)
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      if (this.where) {
 | 
			
		||||
        return `(${this.where}) && (${result.join(' || ')})`
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      return result.join(' || ')
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _getForeignKeyByField() {
 | 
			
		||||
      let fields = this.field.split(',');
 | 
			
		||||
      let whereField = null;
 | 
			
		||||
      for (let i = 0; i < fields.length; i++) {
 | 
			
		||||
        const items = fields[i].split('as');
 | 
			
		||||
        if (items.length < 2) {
 | 
			
		||||
          continue;
 | 
			
		||||
        }
 | 
			
		||||
        if (items[1].trim() === 'value') {
 | 
			
		||||
          whereField = items[0].trim();
 | 
			
		||||
          break;
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
      return whereField;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _updateBindData(node) {
 | 
			
		||||
      const {
 | 
			
		||||
        dataList,
 | 
			
		||||
        hasNodes
 | 
			
		||||
      } = this._filterData(this._treeData, this.selected)
 | 
			
		||||
 | 
			
		||||
      let isleaf = this._stepSearh === false && !hasNodes
 | 
			
		||||
 | 
			
		||||
      if (node) {
 | 
			
		||||
        node.isleaf = isleaf
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      this.dataList = dataList
 | 
			
		||||
      this.selectedIndex = dataList.length - 1
 | 
			
		||||
 | 
			
		||||
      if (!isleaf && this.selected.length < dataList.length) {
 | 
			
		||||
        this.selected.push({
 | 
			
		||||
          value: null,
 | 
			
		||||
          text: "请选择"
 | 
			
		||||
        })
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      return {
 | 
			
		||||
        isleaf,
 | 
			
		||||
        hasNodes
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _updateSelected() {
 | 
			
		||||
      let dl = this.dataList
 | 
			
		||||
      let sl = this.selected
 | 
			
		||||
      let textField = this.map.text
 | 
			
		||||
      let valueField = this.map.value
 | 
			
		||||
      for (let i = 0; i < sl.length; i++) {
 | 
			
		||||
        let value = sl[i].value
 | 
			
		||||
        let dl2 = dl[i]
 | 
			
		||||
        for (let j = 0; j < dl2.length; j++) {
 | 
			
		||||
          let item2 = dl2[j]
 | 
			
		||||
          if (item2[valueField] === value) {
 | 
			
		||||
            sl[i].text = item2[textField]
 | 
			
		||||
            break
 | 
			
		||||
          }
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _filterData(data, paths) {
 | 
			
		||||
      let dataList = []
 | 
			
		||||
      let hasNodes = true
 | 
			
		||||
 | 
			
		||||
      dataList.push(data.filter((item) => {
 | 
			
		||||
        return (item.parent_value === null || item.parent_value === undefined || item.parent_value === '')
 | 
			
		||||
      }))
 | 
			
		||||
      for (let i = 0; i < paths.length; i++) {
 | 
			
		||||
        let value = paths[i].value
 | 
			
		||||
        let nodes = data.filter((item) => {
 | 
			
		||||
          return item.parent_value === value
 | 
			
		||||
        })
 | 
			
		||||
 | 
			
		||||
        if (nodes.length) {
 | 
			
		||||
          dataList.push(nodes)
 | 
			
		||||
        } else {
 | 
			
		||||
          hasNodes = false
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      return {
 | 
			
		||||
        dataList,
 | 
			
		||||
        hasNodes
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _extractTree(nodes, result, parent_value) {
 | 
			
		||||
      let list = result || []
 | 
			
		||||
      let valueField = this.map.value
 | 
			
		||||
      for (let i = 0; i < nodes.length; i++) {
 | 
			
		||||
        let node = nodes[i]
 | 
			
		||||
 | 
			
		||||
        let child = {}
 | 
			
		||||
        for (let key in node) {
 | 
			
		||||
          if (key !== 'children') {
 | 
			
		||||
            child[key] = node[key]
 | 
			
		||||
          }
 | 
			
		||||
        }
 | 
			
		||||
        if (parent_value !== null && parent_value !== undefined && parent_value !== '') {
 | 
			
		||||
          child.parent_value = parent_value
 | 
			
		||||
        }
 | 
			
		||||
        result.push(child)
 | 
			
		||||
 | 
			
		||||
        let children = node.children
 | 
			
		||||
        if (children) {
 | 
			
		||||
          this._extractTree(children, result, node[valueField])
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _extractTreePath(nodes, result) {
 | 
			
		||||
      let list = result || []
 | 
			
		||||
      for (let i = 0; i < nodes.length; i++) {
 | 
			
		||||
        let node = nodes[i]
 | 
			
		||||
 | 
			
		||||
        let child = {}
 | 
			
		||||
        for (let key in node) {
 | 
			
		||||
          if (key !== 'children') {
 | 
			
		||||
            child[key] = node[key]
 | 
			
		||||
          }
 | 
			
		||||
        }
 | 
			
		||||
        result.push(child)
 | 
			
		||||
 | 
			
		||||
        let children = node.children
 | 
			
		||||
        if (children) {
 | 
			
		||||
          this._extractTreePath(children, result)
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _findNodePath(key, nodes, path = []) {
 | 
			
		||||
      let textField = this.map.text
 | 
			
		||||
      let valueField = this.map.value
 | 
			
		||||
      for (let i = 0; i < nodes.length; i++) {
 | 
			
		||||
        let node = nodes[i]
 | 
			
		||||
        let children = node.children
 | 
			
		||||
        let text = node[textField]
 | 
			
		||||
        let value = node[valueField]
 | 
			
		||||
 | 
			
		||||
        path.push({
 | 
			
		||||
          value,
 | 
			
		||||
          text
 | 
			
		||||
        })
 | 
			
		||||
 | 
			
		||||
        if (value === key) {
 | 
			
		||||
          return path
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (children) {
 | 
			
		||||
          const p = this._findNodePath(key, children, path)
 | 
			
		||||
          if (p.length) {
 | 
			
		||||
            return p
 | 
			
		||||
          }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        path.pop()
 | 
			
		||||
      }
 | 
			
		||||
      return []
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,323 @@
 | 
			
		||||
<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>
 | 
			
		||||
							
								
								
									
										90
									
								
								uni_modules/uni-data-picker/package.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										90
									
								
								uni_modules/uni-data-picker/package.json
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,90 @@
 | 
			
		||||
{
 | 
			
		||||
  "id": "uni-data-picker",
 | 
			
		||||
  "displayName": "uni-data-picker 数据驱动的picker选择器",
 | 
			
		||||
  "version": "1.1.2",
 | 
			
		||||
  "description": "单列、多列级联选择器,常用于省市区城市选择、公司部门选择、多级分类等场景",
 | 
			
		||||
  "keywords": [
 | 
			
		||||
    "uni-ui",
 | 
			
		||||
    "uniui",
 | 
			
		||||
    "picker",
 | 
			
		||||
    "级联",
 | 
			
		||||
    "省市区",
 | 
			
		||||
    ""
 | 
			
		||||
],
 | 
			
		||||
  "repository": "https://github.com/dcloudio/uni-ui",
 | 
			
		||||
  "engines": {
 | 
			
		||||
    "HBuilderX": ""
 | 
			
		||||
  },
 | 
			
		||||
  "directories": {
 | 
			
		||||
    "example": "../../temps/example_temps"
 | 
			
		||||
  },
 | 
			
		||||
"dcloudext": {
 | 
			
		||||
    "sale": {
 | 
			
		||||
      "regular": {
 | 
			
		||||
        "price": "0.00"
 | 
			
		||||
      },
 | 
			
		||||
      "sourcecode": {
 | 
			
		||||
        "price": "0.00"
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    "contact": {
 | 
			
		||||
      "qq": ""
 | 
			
		||||
    },
 | 
			
		||||
    "declaration": {
 | 
			
		||||
      "ads": "无",
 | 
			
		||||
      "data": "无",
 | 
			
		||||
      "permissions": "无"
 | 
			
		||||
    },
 | 
			
		||||
    "npmurl": "https://www.npmjs.com/package/@dcloudio/uni-ui",
 | 
			
		||||
    "type": "component-vue"
 | 
			
		||||
  },
 | 
			
		||||
  "uni_modules": {
 | 
			
		||||
    "dependencies": [
 | 
			
		||||
      "uni-load-more",
 | 
			
		||||
			"uni-icons",
 | 
			
		||||
			"uni-scss"
 | 
			
		||||
    ],
 | 
			
		||||
    "encrypt": [],
 | 
			
		||||
    "platforms": {
 | 
			
		||||
      "cloud": {
 | 
			
		||||
        "tcb": "y",
 | 
			
		||||
        "aliyun": "y"
 | 
			
		||||
      },
 | 
			
		||||
      "client": {
 | 
			
		||||
        "App": {
 | 
			
		||||
          "app-vue": "y",
 | 
			
		||||
          "app-nvue": "u"
 | 
			
		||||
        },
 | 
			
		||||
        "H5-mobile": {
 | 
			
		||||
          "Safari": "y",
 | 
			
		||||
          "Android Browser": "y",
 | 
			
		||||
          "微信浏览器(Android)": "y",
 | 
			
		||||
          "QQ浏览器(Android)": "y"
 | 
			
		||||
        },
 | 
			
		||||
        "H5-pc": {
 | 
			
		||||
          "Chrome": "y",
 | 
			
		||||
          "IE": "y",
 | 
			
		||||
          "Edge": "y",
 | 
			
		||||
          "Firefox": "y",
 | 
			
		||||
          "Safari": "y"
 | 
			
		||||
        },
 | 
			
		||||
        "小程序": {
 | 
			
		||||
          "微信": "y",
 | 
			
		||||
          "阿里": "y",
 | 
			
		||||
          "百度": "y",
 | 
			
		||||
          "字节跳动": "y",
 | 
			
		||||
        "QQ": "y",
 | 
			
		||||
        "京东": "u"
 | 
			
		||||
        },
 | 
			
		||||
        "快应用": {
 | 
			
		||||
          "华为": "u",
 | 
			
		||||
          "联盟": "u"
 | 
			
		||||
        },
 | 
			
		||||
        "Vue": {
 | 
			
		||||
            "vue2": "y",
 | 
			
		||||
            "vue3": "y"
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										22
									
								
								uni_modules/uni-data-picker/readme.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								uni_modules/uni-data-picker/readme.md
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,22 @@
 | 
			
		||||
## DataPicker 级联选择
 | 
			
		||||
> **组件名:uni-data-picker**
 | 
			
		||||
> 代码块: `uDataPicker`
 | 
			
		||||
> 关联组件:`uni-data-pickerview`、`uni-load-more`。
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
`<uni-data-picker>` 是一个选择类[datacom组件](https://uniapp.dcloud.net.cn/component/datacom)。
 | 
			
		||||
 | 
			
		||||
支持单列、和多列级联选择。列数没有限制,如果屏幕显示不全,顶部tab区域会左右滚动。
 | 
			
		||||
 | 
			
		||||
候选数据支持一次性加载完毕,也支持懒加载,比如示例图中,选择了“北京”后,动态加载北京的区县数据。
 | 
			
		||||
 | 
			
		||||
`<uni-data-picker>` 组件尤其适用于地址选择、分类选择等选择类。
 | 
			
		||||
 | 
			
		||||
`<uni-data-picker>` 支持本地数据、云端静态数据(json),uniCloud云数据库数据。
 | 
			
		||||
 | 
			
		||||
`<uni-data-picker>` 可以通过JQL直连uniCloud云数据库,配套[DB Schema](https://uniapp.dcloud.net.cn/uniCloud/schema),可在schema2code中自动生成前端页面,还支持服务器端校验。
 | 
			
		||||
 | 
			
		||||
在uniCloud数据表中新建表“uni-id-address”和“opendb-city-china”,这2个表的schema自带foreignKey关联。在“uni-id-address”表的表结构页面使用schema2code生成前端页面,会自动生成地址管理的维护页面,自动从“opendb-city-china”表包含的中国所有省市区信息里选择地址。
 | 
			
		||||
 | 
			
		||||
### [查看文档](https://uniapp.dcloud.io/component/uniui/uni-data-picker)
 | 
			
		||||
#### 如使用过程中有任何问题,或者您对uni-ui有一些好的建议,欢迎加入 uni-ui 交流群:871950839 
 | 
			
		||||
		Reference in New Issue
	
	Block a user