v1.0.6
#### 新增 - 新增`showCount`配置, 可以控制选项的数量, 提高渲染性能 - 新增分组模式, 可以在选项中使用`optgroup`或`children`来开启, 分组时不建议开启分页模式 - 远程搜索中新增`show`参数, 可以查看当前下拉框是否显示 #### Bug fixes - 修复工具条中`全选`和`清空`还可以操作禁用选项的问题 - 修复远程搜索中`selected`不回显的问题
This commit is contained in:
@@ -118,9 +118,9 @@ export function checkUserAgent() {
|
||||
}
|
||||
|
||||
export function IEVersion() {
|
||||
var userAgent = navigator.userAgent; //取得浏览器的userAgent字符串
|
||||
var isIE = userAgent.indexOf("compatible") > -1 && userAgent.indexOf("MSIE") > -1; //判断是否IE<11浏览器
|
||||
var isEdge = userAgent.indexOf("Edge") > -1 && !isIE; //判断是否IE的Edge浏览器
|
||||
var userAgent = navigator.userAgent; //取得浏览器的userAgent字符串
|
||||
var isIE = userAgent.indexOf("compatible") > -1 && userAgent.indexOf("MSIE") > -1; //判断是否IE<11浏览器
|
||||
var isEdge = userAgent.indexOf("Edge") > -1 && !isIE; //判断是否IE的Edge浏览器
|
||||
var isIE11 = userAgent.indexOf('Trident') > -1 && userAgent.indexOf("rv:11.0") > -1;
|
||||
if (isIE) {
|
||||
var reIE = new RegExp("MSIE (\\d+\\.\\d+);");
|
||||
@@ -140,8 +140,32 @@ export function IEVersion() {
|
||||
} else if (isEdge) {
|
||||
return 'edge'; //edge
|
||||
} else if (isIE11) {
|
||||
return 11; //IE11
|
||||
return 11; //IE11
|
||||
} else {
|
||||
return -1; //不是ie浏览器
|
||||
}
|
||||
}
|
||||
|
||||
export function filterGroupOption(arr, data, prop){
|
||||
const { children, optgroup } = prop;
|
||||
data.filter(item => !item[optgroup]).forEach(item => {
|
||||
let child = item[children];
|
||||
if(isArray(child)){
|
||||
filterGroupOption(arr, child, children, optgroup);
|
||||
}else{
|
||||
arr.push(item);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
export function findSelected(arr, data, prop){
|
||||
const { selected, children, optgroup } = prop;
|
||||
data.filter(item => !item[optgroup]).forEach(item => {
|
||||
let child = item[children];
|
||||
if(isArray(child)){
|
||||
findSelected(arr, child, prop);
|
||||
}else{
|
||||
item[selected] && (arr.push(item));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -53,6 +53,8 @@ export default function (lan = 'zn') {
|
||||
//多选上限
|
||||
max: 0,
|
||||
maxMethod: function(sels, item){},
|
||||
//选项显示数量
|
||||
showCount: 0,
|
||||
//工具条
|
||||
toolbar: {
|
||||
show: false,
|
||||
@@ -65,6 +67,8 @@ export default function (lan = 'zn') {
|
||||
value: 'value',
|
||||
selected: 'selected',
|
||||
disabled: 'disabled',
|
||||
children: 'children',
|
||||
optgroup: 'optgroup',
|
||||
},
|
||||
//主题配置
|
||||
theme: {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { h, Component, render } from '@/components/preact'
|
||||
import { checkUserAgent, isFunction, toNum } from '@/components/common/util'
|
||||
import { checkUserAgent, isFunction, toNum, filterGroupOption, findSelected, mergeArr } from '@/components/common/util'
|
||||
|
||||
//渲染类
|
||||
import Tips from './tips';
|
||||
@@ -24,10 +24,15 @@ class Framework extends Component{
|
||||
//用于多选上限的边框颜色变化
|
||||
this.updateBorderColor('');
|
||||
this.resetDate(props.data);
|
||||
let selected = props.prop.selected;
|
||||
this.value(props.initValue ? props.initValue : this.state.data.filter(item => item[selected]), false);
|
||||
this.value(props.initValue ? props.initValue : this.findValue(this.state.data), false);
|
||||
}
|
||||
|
||||
findValue(data){
|
||||
let list = [];
|
||||
findSelected(list, data, this.props.prop);
|
||||
return list;
|
||||
}
|
||||
|
||||
resetDate(data = []){
|
||||
this.setState({ data });
|
||||
}
|
||||
@@ -36,8 +41,11 @@ class Framework extends Component{
|
||||
let data = this.state.data;
|
||||
let value = this.props.prop.value;
|
||||
let direction = this.props.direction;
|
||||
|
||||
let list = [];
|
||||
filterGroupOption(list, data, this.props.prop);
|
||||
this.setState({
|
||||
sels: sels.map(sel => typeof sel === 'object' ? sel[value] : sel).map(val => data.find(item => item[value] == val)).filter(a => a),
|
||||
sels: sels.map(sel => typeof sel === 'object' ? sel[value] : sel).map(val => list.find(item => item[value] == val)).filter(a => a),
|
||||
//下拉框是否展开
|
||||
show,
|
||||
//下拉方向
|
||||
@@ -53,7 +61,7 @@ class Framework extends Component{
|
||||
onReset(data, type){
|
||||
//重置数据
|
||||
if(type === 'data'){
|
||||
this.resetDate(data);
|
||||
this.setState({ sels: mergeArr(this.findValue(data), this.state.sels, this.props.prop), data });
|
||||
}else
|
||||
//重置选中数据
|
||||
if(type === 'sels'){
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { h, Component, render } from '@/components/preact'
|
||||
import { isFunction, safety, mergeArr, IEVersion } from '@/components/common/util'
|
||||
import { isFunction, isArray, safety, mergeArr, IEVersion, filterGroupOption } from '@/components/common/util'
|
||||
|
||||
/**
|
||||
* 普通的多选渲染
|
||||
@@ -111,9 +111,9 @@ class General extends Component{
|
||||
|
||||
let { data, prop, template, theme, radio, sels, empty, filterable, filterMethod, remoteSearch, remoteMethod, delay, searchTips } = config
|
||||
|
||||
const { name, value, disabled } = prop;
|
||||
const { name, value, disabled, children, optgroup } = prop;
|
||||
|
||||
let arr = data;
|
||||
let arr = safety(data);
|
||||
//是否开启了搜索
|
||||
if(filterable){
|
||||
if(remoteSearch){//是否进行远程搜索
|
||||
@@ -127,10 +127,34 @@ class General extends Component{
|
||||
|
||||
this.setState({ loading: false });
|
||||
this.props.onReset(result, 'data');
|
||||
});
|
||||
}, this.props.show);
|
||||
}
|
||||
}else{
|
||||
arr = data.filter((item, index) => filterMethod(this.state.filterValue, item, index, prop));
|
||||
const filterData = (item, index) => {
|
||||
const isGroup = item[optgroup];
|
||||
if(isGroup){
|
||||
return true;
|
||||
}
|
||||
const child = item[children];
|
||||
if(isArray(child) && child.length > 0){//分组模式
|
||||
item[children] = child.filter(filterData);
|
||||
return item[children].length != 0;
|
||||
}
|
||||
return filterMethod(this.state.filterValue, item, index, prop);
|
||||
}
|
||||
arr = arr.filter(filterData);
|
||||
|
||||
for(let i = 0; i < arr.length - 1; i++){
|
||||
let a = arr[i];
|
||||
let b = arr[i + 1];
|
||||
if(a[optgroup] && (b[optgroup] || isArray(b[children]))){
|
||||
arr[i].__del = true;
|
||||
}
|
||||
}
|
||||
if(arr.length && arr[arr.length - 1][optgroup]){
|
||||
arr[arr.length - 1].__del = true;
|
||||
}
|
||||
arr = arr.filter(item => !item.__del);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -177,10 +201,10 @@ class General extends Component{
|
||||
this.state.pageIndex <= 1 && (prevStyle = disabledStyle);
|
||||
this.state.pageIndex == size && (nextStyle = disabledStyle);
|
||||
|
||||
const defaultCurrClass = {
|
||||
position: 'relative',
|
||||
borderRadius: '1px',
|
||||
}
|
||||
// const defaultCurrClass = {
|
||||
// position: 'relative',
|
||||
// borderRadius: '1px',
|
||||
// }
|
||||
// {
|
||||
// ''.padEnd(size, ' ').split('').map((s, i) => (
|
||||
// <span style={
|
||||
@@ -201,7 +225,12 @@ class General extends Component{
|
||||
</div>
|
||||
)
|
||||
|
||||
}
|
||||
}else{
|
||||
//检查是否设置了显示数量上限
|
||||
if(config.showCount > 0){
|
||||
arr = arr.slice(0, config.showCount);
|
||||
}
|
||||
}
|
||||
|
||||
let safetyArr = safety(arr);
|
||||
//工具条操作
|
||||
@@ -212,12 +241,14 @@ class General extends Component{
|
||||
|
||||
let info;
|
||||
if(tool === 'ALL'){
|
||||
info = { icon: 'xm-iconfont xm-icon-quanxuan', name: '全选', method: (data) => {
|
||||
this.props.onReset(mergeArr(data, sels, prop), 'sels');
|
||||
info = { icon: 'xm-iconfont xm-icon-quanxuan', name: '全选', method: (pageData) => {
|
||||
const list = [];
|
||||
filterGroupOption(list, pageData, prop);
|
||||
this.props.onReset(mergeArr(list.filter(item => !item[prop.disabled]), sels, prop), 'sels');
|
||||
} };
|
||||
}else if(tool === 'CLEAR'){
|
||||
info = { icon: 'xm-iconfont xm-icon-qingkong', name: '清空', method: (data) => {
|
||||
this.props.onReset([], 'sels');
|
||||
info = { icon: 'xm-iconfont xm-icon-qingkong', name: '清空', method: (pageData) => {
|
||||
this.props.onReset(sels.filter(item => item[prop.disabled]), 'sels');
|
||||
} };
|
||||
}else {
|
||||
info = tool
|
||||
@@ -238,27 +269,47 @@ class General extends Component{
|
||||
</div>
|
||||
)
|
||||
|
||||
const renderItem = item => {
|
||||
const selected = !!sels.find(sel => sel[value] == item[value])
|
||||
const iconStyle = selected ? {
|
||||
color: theme.color,
|
||||
border: 'none',
|
||||
fontSize: '18px'
|
||||
} : {
|
||||
borderColor: theme.color,
|
||||
};
|
||||
const className = ['xm-option', (item[disabled] ? ' disabled' : ''), (selected ? ' selected' : '')].join(' ');
|
||||
const iconClass = ['xm-option-icon xm-iconfont', radio ? 'xm-icon-danx' : 'xm-icon-duox'].join(' ');
|
||||
|
||||
arr = arr.map(item => {
|
||||
return (
|
||||
<div class={ className } value={ item[value] } onClick={ this.optionClick.bind(this, item, selected, item[disabled]) }>
|
||||
<i class={ iconClass } style={ iconStyle }></i>
|
||||
<div class='xm-option-content' dangerouslySetInnerHTML={{ __html: template({ data, item, arr: sels, name: item[name], value: item[value] }) }}></div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
const renderGroup = item => {
|
||||
const isGroup = item[optgroup];
|
||||
if(isGroup){//分组模式
|
||||
return (
|
||||
<div class="xm-group">
|
||||
<div class="xm-group-item">{ item[name] }</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
const selected = !!sels.find(sel => sel[value] == item[value])
|
||||
const iconStyle = selected ? {
|
||||
color: theme.color,
|
||||
border: 'none',
|
||||
fontSize: '18px'
|
||||
} : {
|
||||
borderColor: theme.color,
|
||||
};
|
||||
const className = ['xm-option', (item[disabled] ? ' disabled' : ''), (selected ? ' selected' : '')].join(' ');
|
||||
const iconClass = ['xm-option-icon xm-iconfont', radio ? 'xm-icon-danx' : 'xm-icon-duox'].join(' ');
|
||||
|
||||
return (
|
||||
<div class={className} value={ item[value] } onClick={ this.optionClick.bind(this, item, selected, item[disabled]) }>
|
||||
<i class={ iconClass } style={ iconStyle }></i>
|
||||
<div class='xm-option-content' dangerouslySetInnerHTML={{ __html: template({ data, item, arr: sels, name: item[name], value: item[value] }) }}></div>
|
||||
</div>
|
||||
)
|
||||
})
|
||||
const child = item[children];
|
||||
if(isArray(child) && child.length > 0){//分组模式
|
||||
return (
|
||||
<div class="xm-group">
|
||||
<div class="xm-group-item">{ item[name] }</div>
|
||||
{ child.map(renderItem) }
|
||||
</div>
|
||||
)
|
||||
}
|
||||
return renderItem(item);
|
||||
}
|
||||
arr = arr.map(renderGroup);
|
||||
|
||||
if(!arr.length){
|
||||
arr.push(
|
||||
|
||||
@@ -189,6 +189,15 @@ xm-select{
|
||||
bottom: 42px;
|
||||
}
|
||||
|
||||
.xm-group{
|
||||
&-item{
|
||||
cursor: default;
|
||||
padding: 0 10px;
|
||||
color: #999;
|
||||
font-size: 12px;
|
||||
}
|
||||
}
|
||||
|
||||
.xm-option{
|
||||
display: flex;
|
||||
align-items: center;
|
||||
@@ -375,7 +384,7 @@ xm-select{
|
||||
pointer-events: none;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
.xm-select-default{
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user