new
parent
ecd9eca8d0
commit
c0710442ed
13
src/App.vue
13
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;
|
||||
}
|
||||
</style>
|
||||
|
|
|
|||
|
|
@ -38,7 +38,7 @@ http.interceptors.response.use((response) => { /* 请求之后拦截器*/
|
|||
if(code ==4024){
|
||||
toast(response.data.msg)
|
||||
}else if(code ==401){
|
||||
toast('请关闭小程序,重新进入')
|
||||
toast('请关闭,重新进入')
|
||||
} else{
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 进行开发,支持单选、多选,全平台兼容。
|
||||
File diff suppressed because it is too large
Load Diff
|
|
@ -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,
|
||||
},
|
||||
}
|
||||
|
|
@ -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
|
||||
<template>
|
||||
<view>
|
||||
<view>多选</view>
|
||||
<view><button @click="doCheckedTree(['2'],true)">全选</button></view>
|
||||
<view><button @click="doCheckedTree(['2'],false)">取消全选</button></view>
|
||||
<view><button @click="doCheckedTree(['211','222'],true)">选中指定节点</button></view>
|
||||
<view><button @click="doCheckedTree(['211','222'],false)">取消选中指定节点</button></view>
|
||||
<view><button @click="doExpandTree('all',true)">展开全部节点</button></view>
|
||||
<view><button @click="doExpandTree('all',false)">收起全部节点</button></view>
|
||||
<view><button @click="doExpandTree(['22','23'],true)">展开节点</button></view>
|
||||
<view><button @click="doExpandTree(['22','23'],false)">收起节点</button></view>
|
||||
<DaTreeVue2
|
||||
ref="DaTreeRef"
|
||||
:data="roomTreeData"
|
||||
labelField="name"
|
||||
valueField="id"
|
||||
defaultExpandAll
|
||||
showCheckbox
|
||||
:defaultCheckedKeys="defaultCheckedKeysValue"
|
||||
@change="handleTreeChange"
|
||||
@expand="handleExpandChange" />
|
||||
|
||||
<view>单选</view>
|
||||
<DaTreeVue2
|
||||
:data="roomTreeData"
|
||||
labelField="name"
|
||||
valueField="id"
|
||||
defaultExpandAll
|
||||
:defaultCheckedKeys="defaultCheckedKeysValue2"
|
||||
@change="handleTreeChange"
|
||||
@expand="handleExpandChange" />
|
||||
<view>默认展开指定节点</view>
|
||||
<DaTreeVue2
|
||||
:data="roomTreeData"
|
||||
labelField="name"
|
||||
valueField="id"
|
||||
showCheckbox
|
||||
:defaultExpandedKeys="defaultExpandKeysValue3"
|
||||
@change="handleTreeChange"
|
||||
@expand="handleExpandChange" />
|
||||
<view>异步加载数据</view>
|
||||
<DaTreeVue2
|
||||
:data="roomTreeData"
|
||||
labelField="name"
|
||||
valueField="id"
|
||||
showCheckbox
|
||||
loadMode
|
||||
:loadApi="GetApiData"
|
||||
defaultExpandAll
|
||||
@change="handleTreeChange"
|
||||
@expand="handleExpandChange" />
|
||||
</view>
|
||||
</template>
|
||||
```
|
||||
|
||||
```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)
|
||||
|
|
@ -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)
|
||||
}
|
||||
|
|
@ -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": [
|
||||
"前端组件",
|
||||
"通用组件"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
|
@ -37,6 +37,15 @@
|
|||
}
|
||||
|
||||
}
|
||||
,{
|
||||
"path" : "pages/system/role",
|
||||
"style" :
|
||||
{
|
||||
"navigationBarTitleText": "角色管理",
|
||||
"enablePullDownRefresh": false
|
||||
}
|
||||
|
||||
}
|
||||
],
|
||||
"globalStyle": {
|
||||
"navigationBarTextStyle": "white",
|
||||
|
|
|
|||
|
|
@ -0,0 +1,351 @@
|
|||
<template>
|
||||
<view class="role-page bg-page">
|
||||
<view class="content-box">
|
||||
<u-swipe-action class="tb_list"
|
||||
v-for="(item, index) in rolelist"
|
||||
:show="item.show" :index="index" :key="item.id"
|
||||
@click="click"
|
||||
@open="open"
|
||||
:options="options"
|
||||
>
|
||||
<view class="tb_body" @click="showInfo(index)">
|
||||
<!-- <view class="row_box">
|
||||
<view class="text">序号:{{ index+1 }}</view>
|
||||
</view> -->
|
||||
<view class="row_box">
|
||||
<view class="text">角色名称:{{ item.name }}</view>
|
||||
</view>
|
||||
<view class="row_box">
|
||||
<view class="text">角色编码:{{ item.slug }}</view>
|
||||
</view>
|
||||
</view>
|
||||
</u-swipe-action>
|
||||
</view>
|
||||
<!-- 编辑 -->
|
||||
<u-popup v-model="editShow" border-radius="28" width="92%" height="70%"
|
||||
mode="center" :closeable="true" :mask-close-able="false" z-index="910">
|
||||
<view class="popup-section">
|
||||
<view class="top_box">
|
||||
<view class="title">编辑角色</view>
|
||||
</view>
|
||||
<scroll-view class="scroll-y" scroll-y="true">
|
||||
<view class="form_edit">
|
||||
<u-form :model="formInfo">
|
||||
<u-form-item label="角色ID" label-width="140">
|
||||
<view class="input_box bg_colorf8">
|
||||
<u-input v-model="formInfo.id" :disabled="true" />
|
||||
</view>
|
||||
</u-form-item>
|
||||
<u-form-item label="角色名称" label-width="140">
|
||||
<view class="input_box">
|
||||
<u-input v-model="formInfo.name" />
|
||||
</view>
|
||||
</u-form-item>
|
||||
<u-form-item label="角色编码" label-width="140">
|
||||
<view class="input_box">
|
||||
<u-input v-model="formInfo.slug" />
|
||||
</view>
|
||||
</u-form-item>
|
||||
<view class="label_tit">菜单分配</view>
|
||||
<DaTreeVue2
|
||||
ref="DaTreeRef"
|
||||
:data="permissionsList"
|
||||
labelField="label"
|
||||
valueField="id"
|
||||
showCheckbox
|
||||
:defaultCheckedKeys="defaultCheckedKeysValue"
|
||||
@change="handleTreeChange"
|
||||
@expand="handleExpandChange" />
|
||||
|
||||
</u-form>
|
||||
|
||||
</view>
|
||||
</scroll-view>
|
||||
<view class="buttom_section">
|
||||
<u-button class="btn" type="default">取消</u-button>
|
||||
<u-button class="btn" type="primary">确定</u-button>
|
||||
</view>
|
||||
</view>
|
||||
</u-popup>
|
||||
<u-popup v-model="popupShow" mode="bottom" border-radius="28" z-index="900">
|
||||
<view class="popup-box">
|
||||
<view class="top_box">
|
||||
<view class="handle-btns">
|
||||
<view class="btn_del" @click="deleteRoleId(info.id)">删除</view>
|
||||
<view class="btn_edit">编辑</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="section_c">
|
||||
|
||||
<view class="plist u-border-bottom">
|
||||
<view class="label_t">角色名称</view>
|
||||
<view class="flex-1">{{info.name}}</view>
|
||||
</view>
|
||||
<view class="plist u-border-bottom">
|
||||
<view class="label_t">角色编码</view>
|
||||
<view class="flex-1">{{info.slug}}</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</u-popup>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import DaTreeVue2 from '@/components/da-tree-vue2/index.vue'
|
||||
export default {
|
||||
components: { DaTreeVue2 },
|
||||
data() {
|
||||
return {
|
||||
per_page:10,
|
||||
page:0,
|
||||
rolelist:[],
|
||||
loading:'loadmore',
|
||||
options: [
|
||||
{
|
||||
text: '编辑',
|
||||
style: {
|
||||
backgroundColor: '#007aff'
|
||||
}
|
||||
},
|
||||
{
|
||||
text: '删除',
|
||||
style: {
|
||||
backgroundColor: '#dd524d'
|
||||
}
|
||||
}
|
||||
],
|
||||
popupShow:false,
|
||||
info:{},//详情
|
||||
cindex:-1,//操作的索引
|
||||
editShow:false,
|
||||
formInfo:{
|
||||
id:'',
|
||||
name:'',
|
||||
slug:'',
|
||||
permissions:''
|
||||
},
|
||||
permissionsList:[],
|
||||
defaultCheckedKeysValue: [],
|
||||
};
|
||||
},
|
||||
onLoad() {
|
||||
this.queryAdminRoleList();
|
||||
this.queryPermissions();
|
||||
},
|
||||
methods: {
|
||||
handleTreeChange(allSelectedKeys, currentItem) {
|
||||
console.log('handleTreeChange ==>', allSelectedKeys, currentItem)
|
||||
},
|
||||
handleExpandChange(expand, currentItem) {
|
||||
console.log('handleExpandChange ==>', expand, currentItem)
|
||||
},
|
||||
showInfo(index){
|
||||
this.cindex = index;
|
||||
this.info = this.rolelist[index];
|
||||
this.popupShow = true;
|
||||
},
|
||||
open(index){
|
||||
this.rolelist[index].show = true;
|
||||
},
|
||||
click(index, index1) {
|
||||
console.log(index,index1,this.rolelist[index])
|
||||
if(index1 == 1) {
|
||||
this.cindex = index;
|
||||
let _id = this.rolelist[index].id;
|
||||
this.deleteRoleId(_id);
|
||||
} else {
|
||||
let _id = this.rolelist[index].id;
|
||||
this.queryRoleInfo(_id);
|
||||
this.formInfo = this.rolelist[index];
|
||||
this.editShow = true;
|
||||
this.rolelist[index].show = false;
|
||||
|
||||
}
|
||||
|
||||
},
|
||||
queryAdminRoleList(refresh){
|
||||
if(refresh){
|
||||
this.loading = 'loadmore';
|
||||
this.rolelist = [];
|
||||
this.page = 0;
|
||||
}
|
||||
if(this.loading=='nomore'){//超出最大页
|
||||
return false;
|
||||
}
|
||||
let params = {
|
||||
per_page:this.per_page,
|
||||
page:this.page ++
|
||||
}
|
||||
this.loading = 'loading';
|
||||
this.$http.get('/api/admin-roles',params).then(({data})=>{
|
||||
console.log(data)
|
||||
this.loading = 'loadmore';
|
||||
if(data.code==200){
|
||||
let _list = data.data|| [];
|
||||
for(let item of _list){
|
||||
item.show = false;
|
||||
}
|
||||
this.rolelist = this.rolelist.concat(_list);
|
||||
console.log(this.rolelist);
|
||||
if(this.rolelist.length>= data.meta.total){
|
||||
this.loading=='nomore';
|
||||
}
|
||||
}
|
||||
}).catch(()=>{
|
||||
this.loading = 'loadmore';
|
||||
})
|
||||
},
|
||||
//删除角色
|
||||
deleteRoleId(id){
|
||||
uni.showModal({
|
||||
title: '提示',
|
||||
content: '是否确定删除?',
|
||||
success: (res)=> {
|
||||
if (res.confirm) {
|
||||
console.log('用户点击确定');
|
||||
this.$http.delete(`/api/admin-roles/${id}`).then(({data})=>{
|
||||
if(data.code==200){
|
||||
this.info = {};//重置删除
|
||||
this.popupShow = false;
|
||||
this.rolelist.splice(this.cindex,1);
|
||||
uni.showToast({ title: data.message, icon: 'none' });
|
||||
}
|
||||
}).catch(()=>{
|
||||
|
||||
})
|
||||
} else if (res.cancel) {
|
||||
console.log('用户点击取消');
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
},
|
||||
//权限数据
|
||||
queryPermissions(){
|
||||
this.$http.get('/api/permissions').then(({data})=>{
|
||||
if(data.code==200){
|
||||
this.permissionsList = data.data;
|
||||
}
|
||||
}).catch((err)=>{
|
||||
|
||||
})
|
||||
},
|
||||
queryRoleInfo(id){
|
||||
this.$http.get(`/api/admin-roles/${id}`).then(({data})=>{
|
||||
if(data.code==200){
|
||||
|
||||
}
|
||||
}).catch((err)=>{
|
||||
|
||||
})
|
||||
},
|
||||
},
|
||||
//触底加载
|
||||
onReachBottom() {
|
||||
if(this.loading=='loadmore'){
|
||||
this.queryAdminRoleList();
|
||||
}
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.role-page{
|
||||
.content-box{
|
||||
padding: 30rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.tb_list{
|
||||
margin-bottom: 24rpx;
|
||||
border-radius: 6rpx;
|
||||
.tb_body{
|
||||
padding: 16rpx;
|
||||
background-color: #fff;
|
||||
.row_box{
|
||||
font-size: 28rpx;
|
||||
line-height: 40rpx;
|
||||
color: #333;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
.popup-box{
|
||||
min-height: 450rpx;
|
||||
.top_box{
|
||||
height: 96rpx;
|
||||
padding: 0 40rpx;
|
||||
|
||||
|
||||
.handle-btns{
|
||||
height: 100%;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
font-size: 30rpx;
|
||||
.btn_del{
|
||||
color:#fa3534;
|
||||
|
||||
}
|
||||
.btn_edit{
|
||||
color:#2979ff;
|
||||
}
|
||||
}
|
||||
}
|
||||
.form_edit{
|
||||
padding: 0 30rpx;
|
||||
|
||||
}
|
||||
.plist{
|
||||
display: flex;
|
||||
padding: 20rpx 40rpx;
|
||||
.label_t{
|
||||
width: 100px;
|
||||
}
|
||||
}
|
||||
}
|
||||
.input_box{
|
||||
width: 100%;
|
||||
padding: 0 12rpx;
|
||||
}
|
||||
.popup-section{
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
.top_box{
|
||||
height: 96rpx;
|
||||
padding: 0 40rpx;
|
||||
.title{
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 32rpx;
|
||||
font-weight: bold;
|
||||
}
|
||||
}
|
||||
.form_edit{
|
||||
padding: 0 30rpx;
|
||||
.label_tit{
|
||||
padding-top: 28rpx;
|
||||
}
|
||||
}
|
||||
.label_tit{
|
||||
padding: 18rpx 0;
|
||||
}
|
||||
.scroll-y{
|
||||
flex: 1;
|
||||
flex-shrink: 0;
|
||||
min-height: 1px;
|
||||
}
|
||||
.buttom_section{
|
||||
display: flex;
|
||||
padding: 40rpx 24rpx 40rpx 24rpx;
|
||||
.btn{
|
||||
width: 220rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
@ -40,7 +40,7 @@
|
|||
<view class="arrow_R"></view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="nav-list" @click="linnavF('/pages/user/password-edit')">
|
||||
<view class="nav-list" @click="linnavF('/pages/system/role')">
|
||||
<view class="icon_img">
|
||||
<u-icon name="man-add" size="46"></u-icon>
|
||||
</view>
|
||||
|
|
|
|||
Loading…
Reference in New Issue