UNPKG

miniprogram-picker

Version:

微信小程序自定义组件Picker。本组件对微信小程序原生Picker组件进行了二次封装,开发者只需要提供固定数据结构的sourceData,再进行一些必要配置,本组件就可以自动帮助开发者处理联动逻辑。

524 lines (468 loc) 17.6 kB
module.exports = /******/ (function(modules) { // webpackBootstrap /******/ // The module cache /******/ var installedModules = {}; /******/ /******/ // The require function /******/ function __webpack_require__(moduleId) { /******/ /******/ // Check if module is in cache /******/ if(installedModules[moduleId]) { /******/ return installedModules[moduleId].exports; /******/ } /******/ // Create a new module (and put it into the cache) /******/ var module = installedModules[moduleId] = { /******/ i: moduleId, /******/ l: false, /******/ exports: {} /******/ }; /******/ /******/ // Execute the module function /******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); /******/ /******/ // Flag the module as loaded /******/ module.l = true; /******/ /******/ // Return the exports of the module /******/ return module.exports; /******/ } /******/ /******/ /******/ // expose the modules object (__webpack_modules__) /******/ __webpack_require__.m = modules; /******/ /******/ // expose the module cache /******/ __webpack_require__.c = installedModules; /******/ /******/ // define getter function for harmony exports /******/ __webpack_require__.d = function(exports, name, getter) { /******/ if(!__webpack_require__.o(exports, name)) { /******/ Object.defineProperty(exports, name, { enumerable: true, get: getter }); /******/ } /******/ }; /******/ /******/ // define __esModule on exports /******/ __webpack_require__.r = function(exports) { /******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) { /******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' }); /******/ } /******/ Object.defineProperty(exports, '__esModule', { value: true }); /******/ }; /******/ /******/ // create a fake namespace object /******/ // mode & 1: value is a module id, require it /******/ // mode & 2: merge all properties of value into the ns /******/ // mode & 4: return value when already ns object /******/ // mode & 8|1: behave like require /******/ __webpack_require__.t = function(value, mode) { /******/ if(mode & 1) value = __webpack_require__(value); /******/ if(mode & 8) return value; /******/ if((mode & 4) && typeof value === 'object' && value && value.__esModule) return value; /******/ var ns = Object.create(null); /******/ __webpack_require__.r(ns); /******/ Object.defineProperty(ns, 'default', { enumerable: true, value: value }); /******/ if(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key)); /******/ return ns; /******/ }; /******/ /******/ // getDefaultExport function for compatibility with non-harmony modules /******/ __webpack_require__.n = function(module) { /******/ var getter = module && module.__esModule ? /******/ function getDefault() { return module['default']; } : /******/ function getModuleExports() { return module; }; /******/ __webpack_require__.d(getter, 'a', getter); /******/ return getter; /******/ }; /******/ /******/ // Object.prototype.hasOwnProperty.call /******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); }; /******/ /******/ // __webpack_public_path__ /******/ __webpack_require__.p = ""; /******/ /******/ /******/ // Load entry module and return exports /******/ return __webpack_require__(__webpack_require__.s = 0); /******/ }) /************************************************************************/ /******/ ([ /* 0 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; /* 参考文档: https://github.com/IceApriler/miniprogram-picker */ function isExist(field) { return field !== null && field !== undefined; } Component({ externalClasses: ['picker-class'], /** * 组件的属性列表 */ properties: { // 初始化时,是否需要自动返回结果给开发者 autoSelect: { type: Boolean, value: false }, // 源数组,sourceData有几维,Picker就可以有几阶 sourceData: { type: Array, value: [], observer: 'sourceDataChange' }, // 阶数 steps: { type: Number, value: 1 }, // 展示数据的字段名称 shownFieldName: { type: String, value: 'name' }, // 子节点名称, subsetFieldName: { type: String, value: 'subset' }, // 其他需要返回的字段 otherNeedFieldsName: { type: Array, value: [] }, // 选择了第n列后,是否将大于n的列的选择值自动初始化为0 initColumnSelectedIndex: { type: Boolean, value: false }, // 默认选中项的下标数组 defaultIndex: { type: Array, value: [] }, // 默认选中项的值数组 defaultValue: { type: Array, value: [] }, // 默认选中项的值数组的唯一字段,用来和源数组进行比对 defaultValueUniqueField: { type: String, value: '' }, // 是否禁用 disabled: { type: Boolean, value: false } }, /** * 组件的初始数据 */ data: { // Picker当前所选择的索引数组 => 比如:[0, 0, 2],表示第一列选择第0项,第二列选择第0项,第三列选择第2项。 multiIndex: { type: Array, value: [] }, // Picker当前所展示的数组 => 比如:[['河北', '山东'], ['石家庄', '保定'], ['桥西区', '裕华区', '长安区']]。 multiArray: { type: Array, value: [] }, // 用户点击确定后,所选择的值数组 => 比如: // [{name: '河北', id: '3110'}, {name: '石家庄', id: '3110xx'}, {name: '长安区', id: '3110xxx'}]。 selectedArray: { type: Array, value: [] } }, /** * 组件的方法列表 */ methods: { /** * 监听源数组更新变化 * * @param {Array} newSourceData 源数组,newSourceData有几维,Picker就可以有几阶。 */ sourceDataChange: function sourceDataChange(newSourceData) { var _data = this.data, shownFieldName = _data.shownFieldName, subsetFieldName = _data.subsetFieldName, steps = _data.steps; // 源数组更新,则需要更新multiIndex、multiArray var multiIndex = []; var multiArray = []; newSourceData = this.checkSourceData(newSourceData); console.warn(newSourceData); var defaultIndex = this.getDefaultIndex(newSourceData); var handle = function handle() { var source = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : []; var columnIndex = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0; // 当前遍历Picker的第columnIndex列, // 当columnIndex = 0时,source表示sourceData,其它则表示子集subset var _multiArrayColumn0 = []; source.forEach(function (item, index) { if (columnIndex === 0) { // newSourceData的第0维要单独处理,最后unshift到multiArray中 _multiArrayColumn0.push(item[shownFieldName]); } if (isExist(item[shownFieldName]) && index === (defaultIndex[columnIndex] || 0)) { // 选中的索引和值,默认取每列的第0个 multiIndex.push(index); if (columnIndex < steps - 1) { if (isExist(item[subsetFieldName])) { // 开始处理下一维的数据 var _subsetArr = item[subsetFieldName].map(function (sub) { return sub[shownFieldName]; }); multiArray.push(_subsetArr); handle(item[subsetFieldName], columnIndex + 1); } } } }); if (columnIndex === 0) { multiArray.unshift(_multiArrayColumn0); } }; handle(newSourceData); this.setData({ multiIndex: multiIndex, multiArray: multiArray }); if (this.data.autoSelect) { this.processData(); } }, /** * 获取默认值index * @param {Array} newSourceData 源数组 */ getDefaultIndex: function getDefaultIndex(newSourceData) { var _this = this; var _data2 = this.data, defaultIndex = _data2.defaultIndex, defaultValue = _data2.defaultValue, defaultValueUniqueField = _data2.defaultValueUniqueField, steps = _data2.steps, subsetFieldName = _data2.subsetFieldName; if (defaultIndex.length) { return defaultIndex; } else if (defaultValue.length) { if (defaultValue.length !== steps) { this.consoleError(new Error('你设置的"defaultValue"字段阶数与"steps"不符,请修改后再试。')); return []; } else if (!defaultValueUniqueField) { this.consoleError(new Error('你设置了"defaultValue"字段, 但是没有设置defaultValueUniqueField,这将无法识别默认选项,请补充后再试。')); return []; } else { defaultValue.forEach(function (def, key) { if (!def[defaultValueUniqueField]) { _this.consoleError(def, new Error('"defaultValue"\u4E2D\u7B2C' + key + '\u9879(\u4ECE0\u5F00\u59CB\u8BA1\u7B97)\u7684\u5BF9\u8C61\u4E2D\u7F3A\u5C11"' + defaultValueUniqueField + '"\u5B57\u6BB5')); } }); var _defaultIndex = []; var handle = function handle() { var source = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : []; var columnIndex = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0; // 默认值 _defaultIndex[columnIndex] = 0; source.forEach(function (item, index) { if (!item[defaultValueUniqueField]) { _this.consoleError(item, new Error('\u6E90\u6570\u7EC4\u7B2C' + columnIndex + '\u7EF4(\u4ECE0\u5F00\u59CB\u8BA1\u7B97)\u7684\u5BF9\u8C61\u4E2D\u7F3A\u5C11"' + defaultValueUniqueField + '"\u5B57\u6BB5')); } else if (defaultValue[columnIndex][defaultValueUniqueField] === item[defaultValueUniqueField]) { _defaultIndex[columnIndex] = index; if (columnIndex < steps - 1) { if (item[subsetFieldName]) { // 开始处理下一维的数据 handle(item[subsetFieldName], columnIndex + 1); } } } }); }; handle(newSourceData); return _defaultIndex; } } else { return []; } }, /** * 校验源数组是否正确 * * @param {Array} sourceData 源数组 */ checkSourceData: function checkSourceData(sourceData) { var _this2 = this; var _data3 = this.data, shownFieldName = _data3.shownFieldName, subsetFieldName = _data3.subsetFieldName, steps = _data3.steps; var handle = function handle() { var source = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : []; var columnIndex = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0; // 当前遍历Picker的第columnIndex列, // 当columnIndex = 0时,source表示sourceData,其它则表示子集subset if (!source.length) { var temp = {}; temp[shownFieldName] = ''; temp[subsetFieldName] = []; source.push(temp); } return source.map(function (item) { if (!isExist(item[shownFieldName])) { _this2.consoleError(item, new Error('\u6E90\u6570\u7EC4\u7B2C' + columnIndex + '\u7EF4(\u4ECE0\u5F00\u59CB\u8BA1\u7B97)\u7684\u5BF9\u8C61\u4E2D\u7F3A\u5C11"' + shownFieldName + '"\u5B57\u6BB5')); item[shownFieldName] = ''; } // 有shownFieldName字段才会去遍历subsetFieldName字段 if (columnIndex < steps - 1) { if (!isExist(item[subsetFieldName])) { _this2.consoleError(item, new Error('\u6E90\u6570\u7EC4\u7B2C' + columnIndex + '\u7EF4(\u4ECE0\u5F00\u59CB\u8BA1\u7B97)\u7684\u5BF9\u8C61\u4E2D\u7F3A\u5C11"' + subsetFieldName + '"\u5B57\u6BB5')); } // 开始处理下一维的数据 item[subsetFieldName] = handle(item[subsetFieldName], columnIndex + 1); } return item; }); }; return handle(sourceData); }, /** * 用户点击了确认。 * * @param {Object} e 事件对象,具体参考微信小程序api。 * @param {Array} e.detail.value 用户选择的下标数组。 */ pickerChange: function pickerChange(e) { // console.log('picker发送选择改变,携带值为', e.detail.value) this.setData({ multiIndex: e.detail.value }); this.processData(); }, /** * 处理最终数据,将返回给开发者。 * */ processData: function processData() { var _this3 = this; var _data4 = this.data, sourceData = _data4.sourceData, shownFieldName = _data4.shownFieldName, subsetFieldName = _data4.subsetFieldName, otherNeedFieldsName = _data4.otherNeedFieldsName, multiIndex = _data4.multiIndex; var selectedArray = []; var handle = function handle() { var source = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : []; var columnIndex = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0; source.forEach(function (item, index) { if (index === multiIndex[columnIndex]) { var selectedItem = {}; selectedItem[shownFieldName] = item[shownFieldName]; otherNeedFieldsName.forEach(function (key) { selectedItem[key] = item[key]; }); selectedArray.push(selectedItem); if (columnIndex < _this3.data.steps - 1) { handle(item[subsetFieldName], columnIndex + 1); } } }); }; handle(sourceData); this.setData({ selectedArray: selectedArray }); var detail = { selectedIndex: this.data.multiIndex, selectedArray: this.data.selectedArray }; this.triggerEvent('change', detail); }, /** * 用户滚动了某一列。 * * @param {Object} e 事件对象,具体参考微信小程序api。 */ pickerColumnChange: function pickerColumnChange(e) { var _data5 = this.data, shownFieldName = _data5.shownFieldName, subsetFieldName = _data5.subsetFieldName, multiArray = _data5.multiArray, sourceData = _data5.sourceData, steps = _data5.steps, initColumnSelectedIndex = _data5.initColumnSelectedIndex; var multiIndex = this.data.multiIndex; var _e$detail = e.detail, column = _e$detail.column, changeIndex = _e$detail.value; // console.log(`修改了Picker的第${column}列(从0开始计算),选中了第${changeIndex}个值(从0开始计算)`) // multiIndex变化了,所以也要同步更新multiArray multiIndex[column] = changeIndex; if (initColumnSelectedIndex) { // 每次重置之后的index为0,但是有bug,待定。 => 经检查,是编辑器的问题,真机上是没有问题的。 var _multiIndex = multiIndex.map(function (item, index) { if (column >= index) { return item; } else { return 0; } }); multiIndex = _multiIndex; } var handle = function handle() { var source = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : []; var columnIndex = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0; // 当前遍历第 columnIndex 列 source.forEach(function (item, index) { if (index === multiIndex[columnIndex]) { if (columnIndex < steps - 1) { if (!item[subsetFieldName]) { item[subsetFieldName] = []; } var multiArrayItem = item[subsetFieldName].map(function (sub) { return sub[shownFieldName]; }); // 从第1列开始,才有可能变化 multiArray[columnIndex + 1] = multiArrayItem; handle(item[subsetFieldName], columnIndex + 1); } } }); }; handle(sourceData); this.setData({ multiArray: multiArray, multiIndex: multiIndex }); this.triggerEvent('columnchange', e); }, /** * 用户点击了取消触发 * @param {Object} e 事件对象 */ pickerCancel: function pickerCancel(e) { this.triggerEvent('cancel', e); }, /** * 绑定console.error * @param {...any} arg 打印参数 */ consoleError: function consoleError() { var _console; (_console = console).error.apply(_console, arguments); console.warn('参考文档:https://github.com/IceApriler/miniprogram-picker'); } }, attached: function attached() { if (this.data.autoSelect) { this.processData(); } } }); /***/ }) /******/ ]);