v1.1.9
This commit is contained in:
parent
308e0b64e1
commit
1ae32b8ed1
17
CHANGELOG.md
17
CHANGELOG.md
@ -1,5 +1,22 @@
|
|||||||
## 更新日志
|
## 更新日志
|
||||||
|
|
||||||
|
### 1.1.9
|
||||||
|
|
||||||
|
*2020-05-04*
|
||||||
|
|
||||||
|
#### 新增
|
||||||
|
|
||||||
|
- tree新增配置`simple`, 代表极简模式, 子级全部被选中后只会显示父级
|
||||||
|
|
||||||
|
#### Bug fixes
|
||||||
|
|
||||||
|
- 设置远程模式`totalSize`默认为1
|
||||||
|
- 修复普通多选模式下设置`max`配置后, 工具条的全选和反选 选中数据错误
|
||||||
|
- 修复`getValue`方法获取到的部分数据中携带`__node`参数无法进行序列化
|
||||||
|
- 修复同时开启远程搜索和远程分页的时候会出发两次`remoteMethod`
|
||||||
|
- 优化`remoteMethod`的内部回调机制
|
||||||
|
|
||||||
|
|
||||||
### 1.1.8
|
### 1.1.8
|
||||||
|
|
||||||
*2020-02-10*
|
*2020-02-10*
|
||||||
|
4
dist/static/2.js
vendored
4
dist/static/2.js
vendored
File diff suppressed because one or more lines are too long
4
dist/static/3.js
vendored
4
dist/static/3.js
vendored
File diff suppressed because one or more lines are too long
4
dist/static/docs.js
vendored
4
dist/static/docs.js
vendored
File diff suppressed because one or more lines are too long
4
dist/xm-select.js
vendored
4
dist/xm-select.js
vendored
File diff suppressed because one or more lines are too long
@ -18,6 +18,8 @@ tree: {
|
|||||||
expandedKeys: [],
|
expandedKeys: [],
|
||||||
//是否严格遵守父子模式
|
//是否严格遵守父子模式
|
||||||
strict: true,
|
strict: true,
|
||||||
|
//是否开启极简模式
|
||||||
|
simple: false,
|
||||||
},
|
},
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -32,6 +34,7 @@ tree: {
|
|||||||
<input type="checkbox" name="showFolderIcon" lay-filter="showFolderIcon" lay-skin="primary" title="是否展示三角图标" checked>
|
<input type="checkbox" name="showFolderIcon" lay-filter="showFolderIcon" lay-skin="primary" title="是否展示三角图标" checked>
|
||||||
<input type="checkbox" name="showLine" lay-filter="showLine" lay-skin="primary" title="是否显示虚线" checked>
|
<input type="checkbox" name="showLine" lay-filter="showLine" lay-skin="primary" title="是否显示虚线" checked>
|
||||||
<input type="checkbox" name="strict" lay-filter="strict" lay-skin="primary" title="严格父子结构" checked>
|
<input type="checkbox" name="strict" lay-filter="strict" lay-skin="primary" title="严格父子结构" checked>
|
||||||
|
<input type="checkbox" name="simple" lay-filter="simple" lay-skin="primary" title="极简模式">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div style="margin-top: 20px">间距</div>
|
<div style="margin-top: 20px">间距</div>
|
||||||
@ -41,7 +44,7 @@ tree: {
|
|||||||
<script>
|
<script>
|
||||||
layui.form.render();
|
layui.form.render();
|
||||||
|
|
||||||
['showFolderIcon', 'showLine', 'strict'].forEach(function(key){
|
['showFolderIcon', 'showLine', 'strict', 'simple'].forEach(function(key){
|
||||||
layui.form.on('checkbox('+key+')', function(data){
|
layui.form.on('checkbox('+key+')', function(data){
|
||||||
var treeConfig = {};
|
var treeConfig = {};
|
||||||
treeConfig[key] = data.elem.checked;
|
treeConfig[key] = data.elem.checked;
|
||||||
|
@ -8,35 +8,29 @@
|
|||||||
var demo1 = xmSelect.render({
|
var demo1 = xmSelect.render({
|
||||||
el: '#demo1',
|
el: '#demo1',
|
||||||
autoRow: true,
|
autoRow: true,
|
||||||
filterable: true,
|
height: '300px',
|
||||||
cascader: {
|
tree: {
|
||||||
show: true,
|
show: false,
|
||||||
indent: 100,
|
simple: true,
|
||||||
|
expandedKeys: [-1],
|
||||||
},
|
},
|
||||||
height: '100px',
|
|
||||||
toolbar: {
|
toolbar: {
|
||||||
show: true,
|
show: true,
|
||||||
list: ['ALL', 'REVERSE', 'CLEAR']
|
list: ['ALL', 'REVERSE', 'CLEAR']
|
||||||
},
|
},
|
||||||
filterable: true,
|
filterable: true,
|
||||||
data(){
|
paging: true,
|
||||||
return [
|
pageRemote: true,
|
||||||
{name: '销售员', value: -1, disabled: true, children: [
|
remoteSearch: true,
|
||||||
|
remoteMethod(val, cb, show, pageIndex){
|
||||||
|
cb([
|
||||||
{name: '张三11111111111', value: 1, selected: true, children: []},
|
{name: '张三11111111111', value: 1, selected: true, children: []},
|
||||||
{name: '李四1', value: 2, selected: true},
|
{name: '李四1', value: 2, selected: true},
|
||||||
{name: '王五1', value: 3, disabled: true},
|
{name: '王五1', value: 3, disabled: false},
|
||||||
]},
|
])
|
||||||
{name: '奖品', value: -2, children: [
|
},
|
||||||
{name: '奖品3333333333', value: -3, children: [
|
data(){
|
||||||
{name: '苹果3', value: 14, selected: true},
|
return []
|
||||||
{name: '香蕉3', value: 15},
|
|
||||||
{name: '葡萄3', value: 16},
|
|
||||||
]},
|
|
||||||
{name: '苹果2', value: 4, selected: true, disabled: true},
|
|
||||||
{name: '香蕉2', value: 5},
|
|
||||||
{name: '葡萄2', value: 6},
|
|
||||||
]},
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -174,6 +174,7 @@ list: [ "ALL", "CLEAR",
|
|||||||
| indent | 间距 | int | - | 20 |
|
| indent | 间距 | int | - | 20 |
|
||||||
| expandedKeys | 默认展开的节点数组, 为true时展开所有节点 | array / boolean | - | [ ] |
|
| expandedKeys | 默认展开的节点数组, 为true时展开所有节点 | array / boolean | - | [ ] |
|
||||||
| strict | 是否遵循严格父子结构 | boolean | true / false | true |
|
| strict | 是否遵循严格父子结构 | boolean | true / false | true |
|
||||||
|
| simple | 是否开启极简模式 | boolean | true / false | false |
|
||||||
|
|
||||||
|
|
||||||
### cascader
|
### cascader
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "xm-select",
|
"name": "xm-select",
|
||||||
"version": "1.1.8",
|
"version": "1.1.9",
|
||||||
"description": "始于Layui的select多选解决方案",
|
"description": "始于Layui的select多选解决方案",
|
||||||
"main": "index.js",
|
"main": "index.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
@ -164,3 +164,30 @@ export function exchangeOptionsData(arr, { prop }){
|
|||||||
}
|
}
|
||||||
return newArr;
|
return newArr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function toSimple(data, sels, list, prop){
|
||||||
|
if(!data || !isArray(data)){
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let { children, selected, value } = prop;
|
||||||
|
data.forEach(item => {
|
||||||
|
if(item.__node[selected] || sels.find(i => i[value] === item[value])){
|
||||||
|
list.push(item);
|
||||||
|
}else{
|
||||||
|
toSimple(item[children], sels, list, prop);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
export function delProp(data, children, props){
|
||||||
|
if(!data || !isArray(data)){
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
return data.map(item => {
|
||||||
|
item = { ...item };
|
||||||
|
props.forEach(prop => delete item[prop]);
|
||||||
|
item[children] = delProp(item[children], children, props);
|
||||||
|
return item;
|
||||||
|
})
|
||||||
|
}
|
||||||
|
@ -283,7 +283,6 @@ class Framework extends Component{
|
|||||||
if(type === 'data'){
|
if(type === 'data'){
|
||||||
let changeData = data.filter(item => item[this.props.prop.selected] === true);
|
let changeData = data.filter(item => item[this.props.prop.selected] === true);
|
||||||
this.resetSelectValue(mergeArr(changeData, this.state.sels, this.props.prop), changeData, true);
|
this.resetSelectValue(mergeArr(changeData, this.state.sels, this.props.prop), changeData, true);
|
||||||
|
|
||||||
let dataObj = {}, flatData = [];
|
let dataObj = {}, flatData = [];
|
||||||
this.load(data, dataObj, flatData);
|
this.load(data, dataObj, flatData);
|
||||||
this.setState({ data, flatData });
|
this.setState({ data, flatData });
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { h, Component, render } from 'preact'
|
import { h, Component, render } from 'preact'
|
||||||
import { isFunction } from '@/common/util'
|
import { isFunction, toSimple } from '@/common/util'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 标签的渲染
|
* 标签的渲染
|
||||||
@ -43,7 +43,7 @@ class Label extends Component{
|
|||||||
}
|
}
|
||||||
|
|
||||||
render(config) {
|
render(config) {
|
||||||
const { data, prop, theme, model, sels, autoRow } = config;
|
const { data, prop, theme, model, sels, autoRow, tree } = config;
|
||||||
const { name, disabled } = prop;
|
const { name, disabled } = prop;
|
||||||
|
|
||||||
//获取配置项
|
//获取配置项
|
||||||
@ -51,17 +51,24 @@ class Label extends Component{
|
|||||||
const type = label.type;
|
const type = label.type;
|
||||||
const conf = label[type];
|
const conf = label[type];
|
||||||
|
|
||||||
|
let list = sels;
|
||||||
|
//树结构开启极简显示
|
||||||
|
if(tree.show && tree.strict && tree.simple){
|
||||||
|
list = []
|
||||||
|
toSimple(data, sels, list, prop);
|
||||||
|
}
|
||||||
|
|
||||||
//渲染结果
|
//渲染结果
|
||||||
let html = '', innerHTML = true;
|
let html = '', innerHTML = true;
|
||||||
//悬浮显示已选择
|
//悬浮显示已选择
|
||||||
let title = sels.map(item => item[name]).join(',')
|
let title = list.map(item => item[name]).join(',')
|
||||||
|
|
||||||
if(type === 'text'){
|
if(type === 'text'){
|
||||||
html = sels.map(sel => `${conf.left}${sel[name]}${conf.right}`).join(conf.separator)
|
html = list.map(sel => `${conf.left}${sel[name]}${conf.right}`).join(conf.separator)
|
||||||
}else if(type === 'block'){
|
}else if(type === 'block'){
|
||||||
innerHTML = false;
|
innerHTML = false;
|
||||||
//已选择的数据
|
//已选择的数据
|
||||||
let arr = [...sels];
|
let arr = [...list];
|
||||||
|
|
||||||
const style = { backgroundColor: theme.color }
|
const style = { backgroundColor: theme.color }
|
||||||
//显示的个数
|
//显示的个数
|
||||||
@ -91,10 +98,10 @@ class Label extends Component{
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
}else{
|
}else{
|
||||||
if(sels.length && conf && conf.template){
|
if(list.length && conf && conf.template){
|
||||||
html = conf.template(data, sels);
|
html = conf.template(data, list);
|
||||||
}else{
|
}else{
|
||||||
html = sels.map(sel => sel[name]).join(',')
|
html = list.map(sel => sel[name]).join(',')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -125,13 +125,15 @@ class General extends Component{
|
|||||||
this.setState({ loading: true, remote: false });
|
this.setState({ loading: true, remote: false });
|
||||||
//让输入框失去焦点
|
//让输入框失去焦点
|
||||||
this.blur();
|
this.blur();
|
||||||
this.props.remoteMethod(this.state.filterValue, (result, totalSize) => {
|
this.props.remoteMethod(this.state.filterValue, (result, totalSize = 1) => {
|
||||||
|
//这里同步修改为异步
|
||||||
|
setTimeout(() => {
|
||||||
//回调后可以重新聚焦
|
//回调后可以重新聚焦
|
||||||
this.focus();
|
this.focus();
|
||||||
|
|
||||||
this.callback = true;
|
this.callback = true;
|
||||||
this.setState({ loading: false, totalSize });
|
this.setState({ loading: false, totalSize });
|
||||||
this.props.onReset(result, 'data');
|
this.props.onReset(result, 'data');
|
||||||
|
}, 10);
|
||||||
}, this.props.show, pageIndex);
|
}, this.props.show, pageIndex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -215,17 +217,19 @@ class General extends Component{
|
|||||||
}
|
}
|
||||||
|
|
||||||
render(config) {
|
render(config) {
|
||||||
let { data, flatData, prop, template, theme, radio, sels, empty, filterable, filterMethod, remoteSearch, remoteMethod, delay, searchTips, create, pageRemote } = config
|
let { data, flatData, prop, template, theme, radio, sels, empty, filterable, filterMethod, remoteSearch, remoteMethod, delay, searchTips, create, pageRemote, max } = config
|
||||||
|
|
||||||
const { name, value, disabled, children, optgroup } = prop;
|
const { name, value, disabled, children, optgroup } = prop;
|
||||||
|
|
||||||
let arr = deepMerge([], flatData), creator;
|
let arr = deepMerge([], flatData), creator;
|
||||||
|
|
||||||
//是否开启了搜索
|
//远程分页 或者 远程搜索
|
||||||
if(filterable){
|
if(pageRemote || filterable && remoteSearch){
|
||||||
if(remoteSearch){//是否进行远程搜索
|
|
||||||
this.postData();
|
this.postData();
|
||||||
}else{
|
}
|
||||||
|
|
||||||
|
//本地搜索
|
||||||
|
if(filterable && !remoteSearch){
|
||||||
const filterData = (item, index) => {
|
const filterData = (item, index) => {
|
||||||
const isGroup = item[optgroup];
|
const isGroup = item[optgroup];
|
||||||
if(isGroup){
|
if(isGroup){
|
||||||
@ -250,12 +254,6 @@ class General extends Component{
|
|||||||
//创建条目
|
//创建条目
|
||||||
creator = this.state.filterValue && isFunction(create);
|
creator = this.state.filterValue && isFunction(create);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
//远程分页
|
|
||||||
if(pageRemote){
|
|
||||||
this.postData();
|
|
||||||
}
|
|
||||||
|
|
||||||
const search = (
|
const search = (
|
||||||
<div class={ filterable ? 'xm-search' : 'xm-search dis' }>
|
<div class={ filterable ? 'xm-search' : 'xm-search dis' }>
|
||||||
@ -355,7 +353,19 @@ class General extends Component{
|
|||||||
info = { icon: 'xm-iconfont xm-icon-quanxuan', name, method: (pageData) => {
|
info = { icon: 'xm-iconfont xm-icon-quanxuan', name, method: (pageData) => {
|
||||||
const { optgroup, disabled } = prop;
|
const { optgroup, disabled } = prop;
|
||||||
const list = pageData.filter(item => !item[optgroup]).filter(item => !item[disabled])
|
const list = pageData.filter(item => !item[optgroup]).filter(item => !item[disabled])
|
||||||
this.props.onReset(radio ? list.slice(0, 1) : mergeArr(list, sels, prop), 'sels');
|
|
||||||
|
const disSels = sels.filter(item => item[prop.disabled]);
|
||||||
|
let result = [];
|
||||||
|
//单选的处理
|
||||||
|
if(radio){
|
||||||
|
result = disSels.length ? disSels : list.slice(0, 1)
|
||||||
|
}else if(max > 0){
|
||||||
|
result = disSels.length >= max ? disSels : mergeArr(list.slice(0, max - disSels.length), disSels, prop)
|
||||||
|
}else{
|
||||||
|
result = mergeArr(list, sels, prop)
|
||||||
|
}
|
||||||
|
|
||||||
|
this.props.onReset(result, 'sels');
|
||||||
} };
|
} };
|
||||||
}else if(tool === 'CLEAR'){
|
}else if(tool === 'CLEAR'){
|
||||||
info = { icon: 'xm-iconfont xm-icon-qingkong', name, method: (pageData) => {
|
info = { icon: 'xm-iconfont xm-icon-qingkong', name, method: (pageData) => {
|
||||||
@ -375,7 +385,19 @@ class General extends Component{
|
|||||||
list.splice(index, 1);
|
list.splice(index, 1);
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
this.props.onReset(radio ? selectedList.slice(0, 1) : mergeArr(list, selectedList, prop), 'sels');
|
|
||||||
|
const disSels = selectedList.filter(item => item[prop.disabled]);
|
||||||
|
let result = [];
|
||||||
|
//单选的处理
|
||||||
|
if(radio){
|
||||||
|
result = disSels.length ? disSels : list.slice(0, 1)
|
||||||
|
}else if(max > 0){
|
||||||
|
result = disSels.length >= max ? disSels : mergeArr(list.slice(0, max - disSels.length), disSels, prop)
|
||||||
|
}else{
|
||||||
|
result = mergeArr(list, selectedList, prop)
|
||||||
|
}
|
||||||
|
|
||||||
|
this.props.onReset(result, 'sels');
|
||||||
} };
|
} };
|
||||||
}else {
|
}else {
|
||||||
info = tool
|
info = tool
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import { h, Component, render } from 'preact'
|
import { h, Component, render } from 'preact'
|
||||||
import { datas, optionData, childData } from '@/index.js';
|
import { datas, optionData, childData } from '@/index.js';
|
||||||
import { warn, listenerClose, isArray, deepMerge, exchangeOptionsData } from '@/common/util'
|
import { warn, listenerClose, isArray, deepMerge, exchangeOptionsData, toSimple, delProp } from '@/common/util'
|
||||||
import Framework from '@/components/framework'
|
import Framework from '@/components/framework'
|
||||||
import defaultOptions from '@/config/options'
|
import defaultOptions from '@/config/options'
|
||||||
|
|
||||||
@ -84,11 +84,17 @@ class xmOptions {
|
|||||||
* 获取多选选中的数据
|
* 获取多选选中的数据
|
||||||
*/
|
*/
|
||||||
getValue(type){
|
getValue(type){
|
||||||
let arr = childData[this.options.el].state.sels.map(item => {
|
const { tree, prop, data } = this.options;
|
||||||
item = { ...item };
|
let sels = childData[this.options.el].state.sels;
|
||||||
delete item.__node;
|
let list = sels;
|
||||||
return item;
|
|
||||||
});
|
//树结构开启极简显示
|
||||||
|
if(tree.show && tree.strict && tree.simple){
|
||||||
|
list = []
|
||||||
|
toSimple(data, sels, list, prop);
|
||||||
|
}
|
||||||
|
|
||||||
|
let arr = delProp(list, prop.children, [ '__node' ]);;
|
||||||
|
|
||||||
if(type === 'name'){
|
if(type === 'name'){
|
||||||
return arr.map(item => item[this.options.prop.name]);
|
return arr.map(item => item[this.options.prop.name]);
|
||||||
|
@ -101,6 +101,8 @@ export default function (lan = 'zn') {
|
|||||||
lazy: false,
|
lazy: false,
|
||||||
//懒加载回调
|
//懒加载回调
|
||||||
load: null,
|
load: null,
|
||||||
|
//是否开启极简模式
|
||||||
|
simple: false,
|
||||||
},
|
},
|
||||||
//级联结构
|
//级联结构
|
||||||
cascader: {
|
cascader: {
|
||||||
|
Loading…
Reference in New Issue
Block a user