From c0710442ed8a5ee4e9b2d67b7cdc5a82aa5e634a Mon Sep 17 00:00:00 2001 From: lgyg <1370861456@qq.com> Date: Sat, 26 Aug 2023 13:39:51 +0800 Subject: [PATCH] new --- src/App.vue | 13 + src/api/index.js | 2 +- src/components/da-tree-vue2/changelog.md | 110 +++ src/components/da-tree-vue2/index.vue | 1108 ++++++++++++++++++++++ src/components/da-tree-vue2/props.js | 183 ++++ src/components/da-tree-vue2/readme.md | 303 ++++++ src/components/da-tree-vue2/utils.js | 151 +++ src/package.json | 19 + src/pages.json | 9 + src/pages/system/role.vue | 351 +++++++ src/pages/user/user.vue | 2 +- 11 files changed, 2249 insertions(+), 2 deletions(-) create mode 100644 src/components/da-tree-vue2/changelog.md create mode 100644 src/components/da-tree-vue2/index.vue create mode 100644 src/components/da-tree-vue2/props.js create mode 100644 src/components/da-tree-vue2/readme.md create mode 100644 src/components/da-tree-vue2/utils.js create mode 100644 src/package.json create mode 100644 src/pages/system/role.vue diff --git a/src/App.vue b/src/App.vue index 8a1ee82..b955e45 100644 --- a/src/App.vue +++ b/src/App.vue @@ -35,6 +35,10 @@ .mr30{ margin-right: 30rpx; } + .pdlr30{ + padding-left: 30rpx; + padding-right: 30rpx; + } .pdlr18{ padding-left: 18rpx; padding-right: 18rpx; @@ -54,6 +58,9 @@ display: flex; flex-direction: row; } + .flex-1{ + flex: 1; + } .clamp { overflow: hidden; text-overflow: ellipsis; @@ -147,4 +154,10 @@ background: url('./static/img/my_arrow_right.png') no-repeat center; background-size: 100%; } + .uni-input-input:disabled{ + background-color: #f8f8f8; + } + .bg_colorf8{ + background-color: #f8f8f8; + } diff --git a/src/api/index.js b/src/api/index.js index 1d63636..3c6abb1 100644 --- a/src/api/index.js +++ b/src/api/index.js @@ -38,7 +38,7 @@ http.interceptors.response.use((response) => { /* 请求之后拦截器*/ if(code ==4024){ toast(response.data.msg) }else if(code ==401){ - toast('请关闭小程序,重新进入') + toast('请关闭,重新进入') } else{ } diff --git a/src/components/da-tree-vue2/changelog.md b/src/components/da-tree-vue2/changelog.md new file mode 100644 index 0000000..aef338d --- /dev/null +++ b/src/components/da-tree-vue2/changelog.md @@ -0,0 +1,110 @@ +# 1.4.1 + +## 版本调整 + +建议更新,但需要注意,异步数据的时候,后台需返回 leaf 字段来判断是否末项数据 + +1. **调整数据项格式,新增 `leaf` 字段,来判断是否为末节点** +2. **调整数据项格式,新增 `sort` 字段,来排序节点位置** +3. **注意:异步加载数据,当为末项的时候,需要服务端数据返回 `leaf` 字段** +4. 新增 `alwaysFirstLoad` ,即异步数据总会在第一次展开节点时,拉取一次后台数据,来比对是否一致 +5. 拆分 `field` 属性,**注意: 1.5.0 版本后将移除 `field` 属性** +6. 新增 `labelField` 同 `field.label`,指定节点对象中某个属性为**标签**字段,默认`label` +7. 新增 `valueField` 同 `field.key`,指定节点对象中某个属性为**值**字段,默认`value` +8. 新增 `childrenField` 同 `field.children`,指定节点对象中某个属性为**子树节点**字段,默认`children` +9. 新增 `disabledField` 同 `field.disabled`,指定节点对象中某个属性为**禁用**字段,默认`disabled` +10. 新增 `appendField` 同 `field.append`,指定节点对象中某个属性为**副标签**字段,默认`append` +11. 新增 `leafField` 同 `field.label`,指定节点对象中某个属性为**末级节点**字段,默认`leaf` +12. 新增 `sortField` 同 `field.label`,指定节点对象中某个属性为**排序**字段,默认`sort` +13. 新增 `isLeafFn` ,用来自定义控制数据项的末项 +14. 更多的项目示例 +15. 支持单选取消选中 +16. 修复节点展开时可能存在的 bug +17. 修复节点选择可能存在的 bug +18. 调整为子节点默认继承父节点禁用属性 +19. `setExpandedKeys` 添加参数一为 `all` 即可支持一键展开/收起全部节点 +20. 其它更多优化 + +# 1.3.4 + +优化 + +1. 优化图标字体命名 + +# 1.3.3 + +版本同步于 Vue3 版,[查看 Vue3 版更新日志](https://ext.dcloud.net.cn/plugin?id=12384&update_log) + +# 1.3.2 + +版本同步于 Vue3 版,[查看 Vue3 版更新日志](https://ext.dcloud.net.cn/plugin?id=12384&update_log) + +# 1.3.1.1 + +修复 + +1. 修复 APP 兼容性引起的报错 + +# 1.3.1 + +## 建议更新 + +### 1.2.2~1.3.1 更新预览 + +1. 新增支持主题换色 +2. 新增支持点击标签也能选中节点 +3. 新增`field`字段 `append` 用于在标签后面显示小提示 +4. 方法`setExpandedKeys`支持加载动态数据 +5. 支持单选的`onlyRadioLeaf`为`true`时可点父节点展开/收起 +6. 新增 `expandChecked`,控制选择时是否展开当前已选的所有下级节点 +7. 新增 `checkedDisabled`,支持渲染禁用值 +8. 新增 `packDisabledkey`,支持返回已选中的禁用的 key +9. 更多细节修复、优化请移步 Vue3 版的更新日志 + +后续版本仍不会实时同步 Vue3 版本,如急需新功能,请移步 Vue3 版 + +版本同步于 Vue3 版,[查看 Vue3 版更新日志](https://ext.dcloud.net.cn/plugin?id=12384&update_log) + +# 1.2.2 + +## 建议更新,优化诸多问题 + +版本同步于 Vue3 版,[查看 Vue3 版更新日志](https://ext.dcloud.net.cn/plugin?id=12384&update_log) + +# 1.2.1 + +版本同步于 Vue3 版,[查看 Vue3 版更新日志](https://ext.dcloud.net.cn/plugin?id=12384&update_log) + +# 1.2.0.1 + +优化 + +1. 优化小程序兼容 + +# 1.2.0 + +版本同步于 Vue3 版,[查看 Vue3 版更新日志](https://ext.dcloud.net.cn/plugin?id=12384&update_log) + +# 1.1.1.1 + +修复 + +1. 修复同步版本的错误写法引起的报错 + +# 1.1.1 + +版本同步于 Vue3 版,[查看 Vue3 版更新日志](https://ext.dcloud.net.cn/plugin?id=12384&update_log) + +# 1.1.0 + +版本同步于 Vue3 版,[查看 Vue3 版更新日志](https://ext.dcloud.net.cn/plugin?id=12384&update_log) + +# 1.0.6 + +新增 + +版本同步于 Vue3 版,[查看 Vue3 版更新日志](https://ext.dcloud.net.cn/plugin?id=12384&update_log) + +# 1.0.5 + +版本同步于 Vue3 版,[查看 Vue3 版更新日志](https://ext.dcloud.net.cn/plugin?id=12384),基于 Vue2 进行开发,支持单选、多选,全平台兼容。 diff --git a/src/components/da-tree-vue2/index.vue b/src/components/da-tree-vue2/index.vue new file mode 100644 index 0000000..5144cc5 --- /dev/null +++ b/src/components/da-tree-vue2/index.vue @@ -0,0 +1,1108 @@ + + + + + diff --git a/src/components/da-tree-vue2/props.js b/src/components/da-tree-vue2/props.js new file mode 100644 index 0000000..44c45a0 --- /dev/null +++ b/src/components/da-tree-vue2/props.js @@ -0,0 +1,183 @@ +// @ts-nocheck +export default { + /** + * 树的数据 + */ + data: { + type: Array, + default: () => [], + }, + /** + * 主题色 + */ + themeColor: { + type: String, + default: '#007aff', + }, + /** + * 是否开启多选,默认单选 + */ + showCheckbox: { + type: Boolean, + default: false, + }, + /** + * 默认选中的节点,注意单选时为单个key,多选时为key的数组 + */ + defaultCheckedKeys: { + type: [Array, String, Number], + default: null, + }, + /** + * 选择框的位置,可选 left/right + */ + checkboxPlacement: { + type: String, + default: 'left', + }, + /** + * 是否默认展开全部 + */ + defaultExpandAll: { + type: Boolean, + default: false, + }, + /** + * 默认展开的节点 + */ + defaultExpandedKeys: { + type: Array, + default: null, + }, + /** + * 是否自动展开到选中的节点,默认不展开 + */ + expandChecked: { + type: Boolean, + default: false, + }, + /** + * 子项缩进距离,默认40,单位rpx + */ + indent: { + type: Number, + default: 40, + }, + /** + * (旧)字段对应内容,默认为 {label: 'label',key: 'key', children: 'children', disabled: 'disabled', append: 'append'} + * 注意:1.5.0版本后不再兼容 + */ + field: { + type: Object, + default: null, + }, + /** + * 标签字段(新,拆分了) + */ + labelField: { + type: String, + default: 'label', + }, + /** + * 值字段(新,拆分了) + */ + valueField: { + type: String, + default: 'value', + }, + /** + * 下级字段(新,拆分了) + */ + childrenField: { + type: String, + default: 'children', + }, + /** + * 禁用字段(新,拆分了) + */ + disabledField: { + type: String, + default: 'disabled', + }, + /** + * 末级节点字段(新,拆分了) + */ + leafField: { + type: String, + default: 'leaf', + }, + /** + * 副标签字段(新,拆分了) + */ + appendField: { + type: String, + default: 'append', + }, + /** + * 排序字段(新,拆分了) + */ + sortField: { + type: String, + default: 'sort', + }, + isLeafFn: { + type: Function, + default: null, + }, + /** + * 是否显示单选图标,默认显示 + */ + showRadioIcon: { + type: Boolean, + default: true, + }, + /** + * 单选时只允许选中末级,默认可随意选中 + */ + onlyRadioLeaf: { + type: Boolean, + default: false, + }, + /** + * 多选时,是否执行父子不关联的任意勾选,默认父子关联 + */ + checkStrictly: { + type: Boolean, + default: false, + }, + /** + * 为 true 时,空的 children 数组会显示展开图标 + */ + loadMode: { + type: Boolean, + default: false, + }, + /** + * 异步加载接口 + */ + loadApi: { + type: Function, + default: null, + }, + /** + * 是否总在首次的时候加载一下内容,来比对是否一致 + */ + alwaysFirstLoad: { + type: Boolean, + default: false, + }, + /** + * 是否渲染(操作)禁用值 + */ + checkedDisabled: { + type: Boolean, + default: false, + }, + /** + * 是否返回已禁用的但已选中的key + */ + packDisabledkey: { + type: Boolean, + default: true, + }, +} diff --git a/src/components/da-tree-vue2/readme.md b/src/components/da-tree-vue2/readme.md new file mode 100644 index 0000000..d4c4459 --- /dev/null +++ b/src/components/da-tree-vue2/readme.md @@ -0,0 +1,303 @@ +# da-tree-vue2 + +一个基于 Vue2 的 tree(树)组件,同时支持主题换色,可能是最适合你的 tree(树)组件 + +`内容同步于 Vue3 版本,在此查看 ===>` **[Vue3 版](https://ext.dcloud.net.cn/plugin?id=12384)** + +_与 Vue3 版本版本不同的是,此版本兼容更全面,比如 360 小程序、快应用等均支持_ + +### 关于使用 + +可在右侧的`使用 HBuilderX 导入插件`或`下载示例项目ZIP`,方便快速上手。 + +可通过下方的示例及文档说明,进一步了解使用组件相关细节参数。 + +插件地址:https://ext.dcloud.net.cn/plugin?id=12692 + +### 组件示例 + +```jsx + +``` + +```js +/** + * 模拟创建一个接口数据 + */ +function GetApiData(currentNode) { + const { key } = currentNode + + return new Promise((resolve) => { + setTimeout(() => { + // 模拟返回空数据 + if (key.indexOf('-') > -1) { + return resolve(null) + // return resolve([]) + } + + return resolve([ + { + id: `${key}-1`, + name: `行政部X${key}-1`, + }, + { + id: `${key}-2`, + name: `财务部X${key}-2`, + append: '定义了末项数据', + leaf: true, + }, + { + id: `${key}-3`, + name: `资源部X${key}-3`, + }, + { + id: `${key}-4`, + name: `资源部X${key}-3`, + append: '被禁用,无展开图标', + disabled: true, + }, + ]) + }, 2000) + }) +} + +import DaTreeVue2 from '@/components/da-tree-vue2/index.vue' +export default { + components: { DaTreeVue2 }, + data() { + return { + GetApiData, + // key的类型必须对应树数据key的类型 + defaultCheckedKeysValue: ['211', '222'], + defaultCheckedKeysValue2: '222', + defaultExpandKeysValue3: ['212', '231'], + roomTreeData: [ + { + id: '2', + name: '行政中心', + children: [ + { + id: '21', + name: '行政部', + children: [ + { + id: '211', + name: '行政一部', + children: null, + }, + { + id: '212', + name: '行政二部', + children: [], + disabled: true, + }, + ], + }, + { + id: '22', + name: '财务部', + children: [ + { + id: '221', + name: '财务一部', + children: [], + disabled: true, + }, + { + id: '222', + name: '财务二部', + children: [], + }, + ], + }, + { + id: '23', + name: '人力资源部', + children: [ + { + id: '231', + name: '人力一部', + children: [], + }, + { + id: '232', + name: '人力二部', + append: '更多示例,请下载示例项目查看', + }, + ], + }, + ], + }, + ], + } + }, + methods: { + doExpandTree(keys, expand) { + this.$refs.DaTreeRef?.setExpandedKeys(keys, expand) + + const gek = this.$refs.DaTreeRef?.getExpandedKeys() + console.log('当前已展开的KEY ==>', gek) + }, + doCheckedTree(keys, checked) { + this.$refs.DaTreeRef?.setCheckedKeys(keys, checked) + + const gek = this.$refs.DaTreeRef?.getCheckedKeys() + console.log('当前已选中的KEY ==>', gek) + }, + handleTreeChange(allSelectedKeys, currentItem) { + console.log('handleTreeChange ==>', allSelectedKeys, currentItem) + }, + handleExpandChange(expand, currentItem) { + console.log('handleExpandChange ==>', expand, currentItem) + }, + }, +} +``` + +** 更多示例请下载/导入示例项目 ZIP 查看 ** + +### 组件参数 + +| 属性 | 类型 | 默认值 | 必填 | 说明 | +| :------------------ | :------------------------------ | :--------- | :--- | :--------------------------------------------------------------------------- | +| data | `Array` | - | 是 | 树的数据 | +| themeColor | `String` | `#007aff` | 否 | 主题色,十六进制 | +| defaultCheckedKeys | `Array` \| `Number` \| `String` | - | 否 | 默认选中的节点,单选为单个 key,多选为 key 的数组 | +| showCheckbox | `Boolean` | `false` | 否 | 是否开启多选,默认单选 | +| checkStrictly | `Boolean` | `false` | 否 | 多选时,是否执行父子不关联的任意勾选,默认父子关联 | +| showRadioIcon | `Boolean` | `true` | 否 | 是否显示单选图标,默认显示 | +| onlyRadioLeaf | `Boolean` | `true` | 否 | 单选时只允许选中末级,默认可随意选中 | +| defaultExpandAll | `Boolean` | `false` | 否 | 是否默认展开全部 | +| defaultExpandedKeys | `Array` | - | 否 | 默认展开的节点 | +| indent | `Number` | `40` | 否 | 子项缩进距离,单位 rpx | +| checkboxPlacement | `String` | `left` | 否 | 选择框的位置,可选 left/right | +| loadMode | `Boolean` | `false` | 否 | 为 true 时,空的 children 数组会显示展开图标 | +| loadApi | `Function` | - | 否 | 选择框的位置,可选 left/right | +| checkedDisabled | `Boolean` | `false` | 否 | 是否渲染禁用值,默认不渲染 | +| packDisabledkey | `Boolean` | `true` | 否 | 是否返回已禁用的但已选中的 key,默认返回禁用已选值 | +| expandChecked | `Boolean` | `false` | 否 | 是否自动展开到选中的节点,默认不展开 | +| alwaysFirstLoad | `Boolean` | `false` | 否 | 是否总在首次的时候加载一下内容,默认不加载,否则只有展开末级节点才会加载数据 | +| isLeafFn | `Function` | - | 否 | 自定义函数返回来控制数据项的末项 | +| field | `Object` | - | 否 | 字段对应内容,格式参考下方(1.5.0 后移除,请用单独的字段匹配) | +| labelField | `String` | `label` | 否 | 指定节点对象中某个属性为标签字段,默认`label` | +| valueField | `String` | `value` | 否 | 指定节点对象中某个属性为值字段,默认`value` | +| childrenField | `String` | `children` | 否 | 指定节点对象中某个属性为子树节点字段,默认`children` | +| disabledField | `String` | `disabled` | 否 | 指定节点对象中某个属性为禁用字段,默认`disabled` | +| appendField | `String` | `append` | 否 | 指定节点对象中某个属性为副标签字段,默认`append` | +| leafField | `String` | `leaf` | 否 | 指定节点对象中某个属性为末级节点字段,默认`leaf` | +| sortField | `String` | `sort` | 否 | 指定节点对象中某个属性为排序字段,默认`sort` | + +**field 格式(1.5.0 后移除,请用单独的字段匹配)** + +```js +{ + label: 'label', + key: 'key', + children: 'children', + disabled: 'disabled', + append: 'append' +} +``` + +### 组件事件 + +| 事件名称 | 回调参数 | 说明 | +| :------- | :-------------------------------------- | :-------------- | +| change | `(allCheckedKeys, currentItem) => void` | 选中时回调 | +| expand | `(expandState, currentItem) => void` | 展开/收起时回调 | + +### 组件方法 + +| 方法名称 | 参数 | 说明 | +| :------------------ | :--------------- | :------------------------------------------------------------------------------------------------ | +| setCheckedKeys | `(keys,checked)` | 设置指定 key 的节点选中/取消选中的状态。注: keys 单选时为 key,多选时为 key 的数组 | +| setExpandedKeys | `(keys,expand)` | 设置指定 key 的节点展开/收起的状态,当 keys 为 all 时即代表展开/收起全部。注:keys 为数组或 `all` | +| getCheckedKeys | - | 返回已选的 key | +| getHalfCheckedKeys | - | 返回半选的 key | +| getUncheckedKeys | - | 返回未选的 key | +| getCheckedNodes | - | 返回已选的节点 | +| getUncheckedNodes | - | 返回未选的节点 | +| getHalfCheckedNodes | - | 返回半选的节点 | +| getExpandedKeys | - | 返回已展开的 key | +| getUnexpandedKeys | - | 返回未展开的 key | +| getExpandedNodes | - | 返回已展开的节点 | +| getUnexpandedNodes | - | 返回未展开的节点 | + +### 组件版本 + +v1.4.1 + +### 差异化 + +已通过测试 + +> - H5 页面 +> - 微信小程序 +> - 支付宝、钉钉小程序 +> - 字节跳动、抖音、今日头条小程序 +> - 百度小程序 +> - 飞书小程序 +> - QQ 小程序 +> - 京东小程序 +> - 快应用 +> - 360 小程序 + +未测试 + +> - 快手小程序由于非企业用户暂无演示 + +### 开发组 + +[@CRLANG](https://crlang.com) diff --git a/src/components/da-tree-vue2/utils.js b/src/components/da-tree-vue2/utils.js new file mode 100644 index 0000000..979b331 --- /dev/null +++ b/src/components/da-tree-vue2/utils.js @@ -0,0 +1,151 @@ +// @ts-nocheck +/** 未选 */ +export const unCheckedStatus = 0 +/** 半选 */ +export const halfCheckedStatus = 1 +/** 选中 */ +export const isCheckedStatus = 2 + +/** + * 深拷贝内容 + * @param originData 拷贝对象 + * @author crlang(https://crlang.com) + */ +export function deepClone(originData) { + const type = Object.prototype.toString.call(originData) + let data + if (type === '[object Array]') { + data = [] + for (let i = 0; i < originData.length; i++) { + data.push(deepClone(originData[i])) + } + } else if (type === '[object Object]') { + data = {} + for (const prop in originData) { + // eslint-disable-next-line no-prototype-builtins + if (originData.hasOwnProperty(prop)) { // 非继承属性 + data[prop] = deepClone(originData[prop]) + } + } + } else { + data = originData + } + return data +} + +/** + * 获取所有指定的节点 + * @param type + * @param value + * @author crlang(https://crlang.com) + */ +export function getAllNodes(list, type, value, packDisabledkey = true) { + if (!list || list.length === 0) { + return [] + } + + const res = [] + for (let i = 0; i < list.length; i++) { + const item = list[i] + if (item[type] === value) { + if ((packDisabledkey && item.disabled) || !item.disabled) { + res.push(item) + } + } + } + + return res +} + +/** + * 获取所有指定的key值 + * @param type + * @param value + * @author crlang(https://crlang.com) + */ +export function getAllNodeKeys(list, type, value, packDisabledkey = true) { + if (!list || list.length === 0) { + return null + } + + const res = [] + for (let i = 0; i < list.length; i++) { + const item = list[i] + if (item[type] === value) { + if ((packDisabledkey && item.disabled) || !item.disabled) { + res.push(item.key) + } + } + } + + return res.length ? res : null +} + +/** + * 错误输出 + * + * @param msg + */ +export function logError(msg, ...args) { + console.error(`DaTree: ${msg}`, ...args) +} + +const toString = Object.prototype.toString + +export function is(val, type) { + return toString.call(val) === `[object ${type}]` +} + +/** + * 是否对象(Object) + * @param val + + */ +export function isObject(val) { + return val !== null && is(val, 'Object') +} + +/** + * 是否数字(Number) + * @param val + + */ +export function isNumber(val) { + return is(val, 'Number') +} + +/** + * 是否字符串(String) + * @param val + + */ +export function isString(val) { + return is(val, 'String') +} + +/** + * 是否函数方法(Function) + * @param val + + */ +export function isFunction(val) { + return typeof val === 'function' +} + +/** + * 是否布尔(Boolean) + * @param val + + */ +export function isBoolean(val) { + return is(val, 'Boolean') +} + +/** + * 是否数组(Array) + * @param val + + */ +export function isArray(val) { + return val && Array.isArray(val) +} diff --git a/src/package.json b/src/package.json new file mode 100644 index 0000000..c1e9355 --- /dev/null +++ b/src/package.json @@ -0,0 +1,19 @@ +{ + "id": "da-tree-vue2", + "name": "da-tree 树组件(支持单选、多选、无限级、主题色,Vue2版)", + "displayName": "da-tree 树组件(支持单选、多选、无限级、主题色,Vue2版)", + "version": "1.4.1", + "description": "一个基于 Vue2 的tree(树)组件,同时支持主题换色,可能是最适合你的tree(树)组件", + "keywords": [ + "tree", + "树", + "树组件", + "da系列" + ], + "dcloudext": { + "category": [ + "前端组件", + "通用组件" + ] + } +} \ No newline at end of file diff --git a/src/pages.json b/src/pages.json index 3fb5810..69abbbc 100644 --- a/src/pages.json +++ b/src/pages.json @@ -37,6 +37,15 @@ } } + ,{ + "path" : "pages/system/role", + "style" : + { + "navigationBarTitleText": "角色管理", + "enablePullDownRefresh": false + } + + } ], "globalStyle": { "navigationBarTextStyle": "white", diff --git a/src/pages/system/role.vue b/src/pages/system/role.vue new file mode 100644 index 0000000..7cbef98 --- /dev/null +++ b/src/pages/system/role.vue @@ -0,0 +1,351 @@ + + + + + diff --git a/src/pages/user/user.vue b/src/pages/user/user.vue index 88b743b..b68126d 100644 --- a/src/pages/user/user.vue +++ b/src/pages/user/user.vue @@ -40,7 +40,7 @@ - +