修复tree模式的节点显示异常
This commit is contained in:
parent
1175612369
commit
ca9453469e
1
.gitignore
vendored
1
.gitignore
vendored
@ -2,3 +2,4 @@
|
||||
.DS_Store
|
||||
node_modules/*
|
||||
yarn.lock
|
||||
*.zip
|
15
CHANGELOG.md
15
CHANGELOG.md
@ -1,5 +1,20 @@
|
||||
## 更新日志
|
||||
|
||||
### 1.2.1
|
||||
|
||||
*2020-11-27*
|
||||
|
||||
#### 新增
|
||||
|
||||
- 新增配置`enableKeyboard`, 用于控制是否使用键盘操作, 用于取消因为键盘事件带来的性能影响
|
||||
- tree模式新增配置`clickExpand`, 是否点击节点即展开节点
|
||||
- tree模式新增配置`clickCheck`, 是否点击节点即选中节点
|
||||
|
||||
#### Bug fixes
|
||||
|
||||
- [紧急修复]tree模式下节点超过2层, 父节点半选状态异常
|
||||
|
||||
|
||||
### 1.2.0
|
||||
|
||||
*2020-11-26*
|
||||
|
2
dist/static/2.js
vendored
2
dist/static/2.js
vendored
File diff suppressed because one or more lines are too long
2
dist/static/3.js
vendored
2
dist/static/3.js
vendored
File diff suppressed because one or more lines are too long
2
dist/xm-select.js
vendored
2
dist/xm-select.js
vendored
File diff suppressed because one or more lines are too long
@ -20,6 +20,10 @@ tree: {
|
||||
strict: true,
|
||||
//是否开启极简模式
|
||||
simple: false,
|
||||
//点击节点是否展开
|
||||
clickExpand: true,
|
||||
//点击节点是否选中
|
||||
clickCheck: true,
|
||||
},
|
||||
```
|
||||
|
||||
@ -42,6 +46,11 @@ tree: {
|
||||
<input type="checkbox" name="all" lay-filter="all" lay-skin="primary" title="展开所有节点">
|
||||
<input type="checkbox" name="close" lay-filter="close" lay-skin="primary" title="闭合所有节点">
|
||||
<input type="checkbox" name="key3" lay-filter="key3" lay-skin="primary" title="展开指定节点">
|
||||
|
||||
<br/><br/>
|
||||
<input type="checkbox" name="clickExpand" lay-filter="clickExpand" lay-skin="primary" title="clickExpand" checked>
|
||||
<input type="checkbox" name="clickCheck" lay-filter="clickCheck" lay-skin="primary" title="clickExpand" checked>
|
||||
|
||||
</div>
|
||||
|
||||
<div style="margin-top: 20px">间距</div>
|
||||
@ -110,6 +119,22 @@ layui.form.on('checkbox(key3)', function(data){
|
||||
}
|
||||
});
|
||||
|
||||
layui.form.on('checkbox(clickExpand)', function(data){
|
||||
demo1.update({
|
||||
tree: {
|
||||
clickExpand: data.elem.checked
|
||||
}
|
||||
})
|
||||
});
|
||||
|
||||
layui.form.on('checkbox(clickCheck)', function(data){
|
||||
demo1.update({
|
||||
tree: {
|
||||
clickCheck: data.elem.checked
|
||||
}
|
||||
})
|
||||
});
|
||||
|
||||
layui.slider.render({
|
||||
elem: '#slideTest1',
|
||||
min: 10,
|
||||
|
@ -16,6 +16,8 @@ var demo1 = xmSelect.render({
|
||||
indent: 20,
|
||||
expandedKeys: [ -3 ],
|
||||
simple: true,
|
||||
clickExpand: false,
|
||||
clickCheck: false,
|
||||
},
|
||||
toolbar: {
|
||||
show: true,
|
||||
|
@ -45,6 +45,7 @@
|
||||
| layReqText | 表单验证, 同layui的lay-reqText | string | - | '' |
|
||||
| toolbar | 工具条, 具体看下表 | object | - | - |
|
||||
| showCount | 展示在下拉框中的最多选项数量 | int | - | 0 |
|
||||
| enableKeyboard | 是否启用键盘操作选项 | boolean | true / false | true |
|
||||
| autoRow | 是否开启自动换行(选项过多时) | boolean | true / false | false |
|
||||
| size | 尺寸 | string | large / medium / small / mini | medium |
|
||||
| disabled | 是否禁用多选 | boolean | true / false | false |
|
||||
@ -189,6 +190,8 @@ list: [ "ALL", "CLEAR",
|
||||
| strict | 是否遵循严格父子结构 | boolean | true / false | true |
|
||||
| simple | 是否开启极简模式 | boolean | true / false | false |
|
||||
| nodeType | 标注节点类型的key | string | leaf: 叶子节点, parent: 父节点, half: 半选节点 | __node_type |
|
||||
| clickExpand | 点击节点是否展开, false时点击三角箭头进行展开操作| boolean | true / false | true |
|
||||
| clickCheck | 点击节点是否选中, false时点击复选框进行选中操作 | boolean | true / false | true |
|
||||
|
||||
|
||||
### cascader
|
||||
|
@ -193,7 +193,7 @@ class Framework extends Component{
|
||||
let child = parent[children];
|
||||
child.filter(item => !(item[disabled] || item.__node.disabled)).forEach(item => {
|
||||
if(item[optgroup]){
|
||||
this.treeHandler(sels, item, change, type);
|
||||
this.treeHandler(sels, item, change, type, changeStatus);
|
||||
}else{
|
||||
let index = sels.findIndex(sel => sel[value] == item[value])
|
||||
if(type === 'del'){
|
||||
@ -255,9 +255,11 @@ class Framework extends Component{
|
||||
}else{
|
||||
handlerType = 'add';
|
||||
}
|
||||
|
||||
if(handlerType != 'half'){
|
||||
this.treeHandler(sels, item, change, handlerType);
|
||||
}
|
||||
|
||||
if(this.checkMax(change, change)){
|
||||
return ;
|
||||
}
|
||||
|
@ -117,6 +117,8 @@ class Label extends Component{
|
||||
this.props.onReset(e, 'labelSearch')
|
||||
}} compositionend={ e => {
|
||||
this.props.onReset(e, 'labelSearch')
|
||||
}} onClick={ e => {
|
||||
e.stopPropagation();
|
||||
}}></input>
|
||||
)
|
||||
}else{
|
||||
|
@ -165,45 +165,47 @@ class General extends Component{
|
||||
}
|
||||
}
|
||||
|
||||
const { value, optgroup, disabled } = this.props.prop;
|
||||
let data = this.tempData.filter(item => !item[optgroup] && !item[disabled]);
|
||||
let len = data.length - 1;
|
||||
if(len === -1){
|
||||
return ;
|
||||
}
|
||||
if(this.props.enableKeyboard){
|
||||
const { value, optgroup, disabled } = this.props.prop;
|
||||
let data = this.tempData.filter(item => !item[optgroup] && !item[disabled]);
|
||||
let len = data.length - 1;
|
||||
if(len === -1){
|
||||
return ;
|
||||
}
|
||||
|
||||
let index = data.findIndex(item => item[value] === this.state.val);
|
||||
//Up 键
|
||||
if(keyCode === 38){
|
||||
if(index <= 0){
|
||||
index = len
|
||||
}else if(index > 0){
|
||||
index -= 1;
|
||||
}
|
||||
let val = data[index][value];
|
||||
this.setState({ val })
|
||||
//键盘选中时滚动到可视范围内
|
||||
let opt = this.base.querySelector(`.xm-option[value="${ val }"]`);
|
||||
opt && opt.scrollIntoView(false)
|
||||
}else
|
||||
//Down 键
|
||||
if(keyCode === 40){
|
||||
if(index === -1 || index === len){
|
||||
index = 0
|
||||
}else if(index < len){
|
||||
index += 1;
|
||||
}
|
||||
let val = data[index][value];
|
||||
this.setState({ val })
|
||||
//键盘选中时滚动到可视范围内
|
||||
let opt = this.base.querySelector(`.xm-option[value="${ val }"]`);
|
||||
opt && opt.scrollIntoView(false)
|
||||
}else
|
||||
//Enter 键
|
||||
if(keyCode === 13){
|
||||
if(this.state.val != emptyVal){
|
||||
let option = data[index];
|
||||
this.optionClick(option, this.props.sels.findIndex(item => item[value] === this.state.val) != -1, option[disabled], e)
|
||||
let index = data.findIndex(item => item[value] === this.state.val);
|
||||
//Up 键
|
||||
if(keyCode === 38){
|
||||
if(index <= 0){
|
||||
index = len
|
||||
}else if(index > 0){
|
||||
index -= 1;
|
||||
}
|
||||
let val = data[index][value];
|
||||
this.setState({ val })
|
||||
//键盘选中时滚动到可视范围内
|
||||
let opt = this.base.querySelector(`.xm-option[value="${ val }"]`);
|
||||
opt && opt.scrollIntoView(false)
|
||||
}else
|
||||
//Down 键
|
||||
if(keyCode === 40){
|
||||
if(index === -1 || index === len){
|
||||
index = 0
|
||||
}else if(index < len){
|
||||
index += 1;
|
||||
}
|
||||
let val = data[index][value];
|
||||
this.setState({ val })
|
||||
//键盘选中时滚动到可视范围内
|
||||
let opt = this.base.querySelector(`.xm-option[value="${ val }"]`);
|
||||
opt && opt.scrollIntoView(false)
|
||||
}else
|
||||
//Enter 键
|
||||
if(keyCode === 13){
|
||||
if(this.state.val != emptyVal){
|
||||
let option = data[index];
|
||||
this.optionClick(option, this.props.sels.findIndex(item => item[value] === this.state.val) != -1, option[disabled], e)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -237,7 +239,7 @@ class General extends Component{
|
||||
}
|
||||
|
||||
render(config) {
|
||||
let { data, flatData, prop, template, theme, radio, sels, empty, filterable, filterMethod, remoteSearch, remoteMethod, delay, searchTips, create, pageRemote, max } = config
|
||||
let { data, flatData, prop, template, theme, radio, sels, empty, filterable, filterMethod, remoteSearch, remoteMethod, delay, searchTips, create, pageRemote, max, enableKeyboard } = config
|
||||
|
||||
const { name, value, disabled, children, optgroup } = prop;
|
||||
|
||||
@ -451,7 +453,7 @@ class General extends Component{
|
||||
const itemStyle = {}
|
||||
|
||||
//处理键盘的选择背景色
|
||||
if(item[value] === this.state.val){
|
||||
if(enableKeyboard && item[value] === this.state.val){
|
||||
itemStyle.backgroundColor = theme.hover
|
||||
}
|
||||
//不显示图标时候的背景色处理
|
||||
@ -473,7 +475,19 @@ class General extends Component{
|
||||
const hoverChange = e => {
|
||||
if(e.type === 'mouseenter'){
|
||||
if(!item[disabled]){
|
||||
this.setState({ val: item[value] })
|
||||
if(enableKeyboard){
|
||||
this.setState({ val: item[value] })
|
||||
}else{
|
||||
e.target.style.backgroundColor = theme.hover;
|
||||
}
|
||||
}
|
||||
}else if(e.type === 'mouseleave'){
|
||||
if(!item[disabled]){
|
||||
if(enableKeyboard){
|
||||
|
||||
}else{
|
||||
e.target.style.backgroundColor = '';
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -58,31 +58,43 @@ class Tree extends Component{
|
||||
}
|
||||
|
||||
const { tree, prop, sels } = this.props;
|
||||
const { clickExpand, clickCheck } = tree;
|
||||
|
||||
//不是父节点的不需要处理
|
||||
if(!tree.lazy && !item[prop.optgroup]){
|
||||
this.props.ck(item, selected, disabled);
|
||||
return
|
||||
//检测点击的是不是三角箭头
|
||||
let isExpand = e.target && isFunction(e.target.getAttribute) && e.target.getAttribute('type') === 'expand'
|
||||
//如果点击即展开
|
||||
if(clickExpand || isExpand){
|
||||
//不是父节点的不需要处理
|
||||
if(!tree.lazy && !item[prop.optgroup]){
|
||||
this.props.ck(item, selected, disabled);
|
||||
return
|
||||
}
|
||||
|
||||
let val = item[this.props.prop.value];
|
||||
let expandedKeys = this.state.expandedKeys;
|
||||
let index = expandedKeys.findIndex(v => v === val);
|
||||
index === -1 ? expandedKeys.push(val) : expandedKeys.splice(index, 1);
|
||||
this.setState({ expandedKeys });
|
||||
|
||||
//是否需要懒加载
|
||||
let child = item[prop.children];
|
||||
if(tree.lazy && child && child.length === 0 && item.__node.loading !== false){
|
||||
item.__node.loading = true;
|
||||
tree.load(item, (result) => {
|
||||
item.__node.loading = false;
|
||||
item[prop.children] = this.handlerData(result, prop.children);
|
||||
item[prop.selected] = sels.findIndex(i => i[prop.value] === item[prop.value]) != -1
|
||||
this.props.onReset(sels, 'treeData');
|
||||
});
|
||||
}
|
||||
}else{
|
||||
if(clickCheck){
|
||||
type = 'checkbox'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let val = item[this.props.prop.value];
|
||||
let expandedKeys = this.state.expandedKeys;
|
||||
let index = expandedKeys.findIndex(v => v === val);
|
||||
index === -1 ? expandedKeys.push(val) : expandedKeys.splice(index, 1);
|
||||
this.setState({ expandedKeys });
|
||||
|
||||
//是否需要懒加载
|
||||
let child = item[prop.children];
|
||||
if(tree.lazy && child && child.length === 0 && item.__node.loading !== false){
|
||||
item.__node.loading = true;
|
||||
tree.load(item, (result) => {
|
||||
item.__node.loading = false;
|
||||
item[prop.children] = this.handlerData(result, prop.children);
|
||||
item[prop.selected] = sels.findIndex(i => i[prop.value] === item[prop.value]) != -1
|
||||
this.props.onReset(sels, 'treeData');
|
||||
});
|
||||
}
|
||||
}else if(type === 'checkbox'){
|
||||
if(type === 'checkbox'){
|
||||
this.props.ck(item, selected, disabled);
|
||||
}
|
||||
//阻止父组件上的事件冒泡
|
||||
@ -218,7 +230,7 @@ class Tree extends Component{
|
||||
}
|
||||
|
||||
render(config, { expandedKeys }) {
|
||||
let { prop, empty, sels, theme, radio, template, data, tree, filterable, remoteSearch, searchTips, iconfont } = config;
|
||||
let { prop, empty, sels, theme, radio, template, data, tree, filterable, remoteSearch, searchTips, iconfont, enableKeyboard } = config;
|
||||
let { name, value, disabled, children, optgroup } = prop;
|
||||
|
||||
let showIcon = config.model.icon != 'hidden';
|
||||
@ -246,7 +258,7 @@ class Tree extends Component{
|
||||
const itemStyle = { paddingLeft: indent + 'px' }
|
||||
|
||||
//处理键盘的选择背景色
|
||||
if(item[value] === this.state.val){
|
||||
if(enableKeyboard && item[value] === this.state.val){
|
||||
itemStyle.backgroundColor = theme.hover
|
||||
}
|
||||
|
||||
@ -279,7 +291,7 @@ class Tree extends Component{
|
||||
|
||||
const iconArray = [];
|
||||
if(tree.showFolderIcon){
|
||||
iconArray.push(<i class={ treeIconClass }></i>);
|
||||
iconArray.push(<i class={ treeIconClass } type="expand"></i>);
|
||||
if(tree.showLine){
|
||||
if(expand){
|
||||
iconArray.push(<i class='left-line' style={ {left: indent - tree.indent + 3 + 'px'} }></i>)
|
||||
@ -293,7 +305,19 @@ class Tree extends Component{
|
||||
const hoverChange = e => {
|
||||
if(e.type === 'mouseenter'){
|
||||
if(!item[disabled]){
|
||||
this.setState({ val: item[value] })
|
||||
if(enableKeyboard){
|
||||
this.setState({ val: item[value] })
|
||||
}else{
|
||||
e.target.style.backgroundColor = theme.hover;
|
||||
}
|
||||
}
|
||||
}else if(e.type === 'mouseleave'){
|
||||
if(!item[disabled]){
|
||||
if(enableKeyboard){
|
||||
|
||||
}else{
|
||||
e.target.style.backgroundColor = '';
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -349,7 +373,6 @@ class Tree extends Component{
|
||||
|
||||
//工具条操作
|
||||
function flat(list, array){
|
||||
//array.forEach(item => item[optgroup] ? (!tree.strict && list.push(item), flat(list, item[children])) : list.push(item))
|
||||
array.forEach(item => {
|
||||
if(item[optgroup]){
|
||||
//非严格模式, 如果隐藏父节点, 证明不可选
|
||||
|
@ -79,6 +79,8 @@ export default function (lan = 'zn') {
|
||||
maxMethod: function(sels, item){},
|
||||
//选项显示数量
|
||||
showCount: 0,
|
||||
//是否开启键盘操作
|
||||
enableKeyboard: true,
|
||||
//工具条
|
||||
toolbar: {
|
||||
show: false,
|
||||
@ -107,6 +109,10 @@ export default function (lan = 'zn') {
|
||||
simple: false,
|
||||
//标注节点类型的key
|
||||
nodeType: '__node_type',
|
||||
//点击节点是否展开
|
||||
clickExpand: true,
|
||||
//点击节点是否选中
|
||||
clickCheck: true,
|
||||
},
|
||||
//级联结构
|
||||
cascader: {
|
||||
|
Loading…
Reference in New Issue
Block a user