v1.1.0.Beta+

This commit is contained in:
maplemei 2019-11-21 20:06:27 +08:00
parent 926e1d47f9
commit db6fdae5cd
12 changed files with 133 additions and 77 deletions

View File

@ -1,26 +1,26 @@
## 更新日志
### 1.1.0.Beta-3
### 1.1.0.Beta+
*2019-11-21*
#### 新增
- label也可以自定义渲染
#### Bug fixes
- 树形组件
- [新增]`strict`严格父子结构
- [修改]树状结构使用`setValue`数据错误
- [修改]树状结构中`children`属性为空数组时无法操作节点的问题
- [修改]半选状态下如无可选子项则变更操作为取消
- 修改`initValue`失效的问题
- 修改`getValue()`方法无法序列化的问题
- 调整拓展中心下拉日期多选的样式
### 1.1.0.Beta-2
*2019-11-20*
#### Bug fixes
- 修改树状结构使用`setValue`数据错误
- 修改树状结构中`children`属性为空数组时无法操作节点的问题
### 1.1.0.Beta-1
### 1.1.0.Beta
*2019-11-19*

2
dist/static/2.js vendored

File diff suppressed because one or more lines are too long

2
dist/static/3.js vendored

File diff suppressed because one or more lines are too long

2
dist/xm-select.js vendored

File diff suppressed because one or more lines are too long

View File

@ -1,7 +1,7 @@
## 构建选项
### 默认渲染
### 自定义渲染
:::demo
```html
@ -10,10 +10,16 @@
<script>
var demo1 = xmSelect.render({
el: '#demo1',
data: [
{name: '张三', value: 'zhangsan', selected: true},
{name: '李四', value: 'lisi', selected: true},
{name: '王五', value: 'wangwu'},
template({ item, sels, name, value }){
return item.name + '<span style="position: absolute; right: 10px; color: #8799a3">'+value+'</span>'
},
prop: {
name: 'showname',
},
data: [
{name: '张三', value: 'zhangsan', showname: '组织部-张三', selected: true},
{name: '李四', value: 'lisi', showname: '策划部-李四', selected: true},
{name: '王五', value: 'wangwu', showname: '运营部-王五' },
]
})
</script>
@ -21,24 +27,35 @@ var demo1 = xmSelect.render({
:::
### 自定义渲染
### 自定义渲染 - label
:::demo
```html
<div id="demo2" class="xm-select-demo"></div>
<script>
<script>
var icons = ['layui-icon layui-icon-face-smile', 'layui-icon layui-icon-cellphone']
var demo2 = xmSelect.render({
el: '#demo2',
template({ item, sels, name, value }){
return name + '<span style="position: absolute; right: 10px; color: #8799a3">'+value+'</span>'
},
data: [
{name: '张三', value: 'zhangsan', selected: true},
{name: '李四', value: 'lisi', selected: true},
{name: '王五', value: 'wangwu'},
model: {
label: {
block: {
template: function(item, sels){
return '<i class="'+icons[item.group]+'"></i>' + item.name;
},
},
}
},
template({ item, sels, name, value }){
return item.name + '<span style="position: absolute; right: 10px; color: #8799a3">'+value+'</span>'
},
data: [
{group: 1, name: '张三', value: 'zhangsan', selected: true},
{group: 0, name: '李四', value: 'lisi', selected: true},
{group: 1, name: '王五', value: 'wangwu' },
]
})
</script>
```
:::
:::

View File

@ -16,6 +16,8 @@ tree: {
indent: 20,
//默认展开节点的数组
expandedKeys: [],
//是否严格遵守父子模式
strict: true,
},
```
@ -29,6 +31,7 @@ tree: {
<div class="layui-form">
<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="strict" lay-filter="strict" lay-skin="primary" title="严格父子结构" checked>
</div>
<div style="margin-top: 20px">间距</div>
@ -38,20 +41,16 @@ tree: {
<script>
layui.form.render();
layui.form.on('checkbox(showFolderIcon)', function(data){
demo1.update({
tree: {
showFolderIcon: data.elem.checked
}
})
});
layui.form.on('checkbox(showLine)', function(data){
demo1.update({
tree: {
showLine: data.elem.checked
}
})
});
['showFolderIcon', 'showLine', 'strict'].forEach(function(key){
layui.form.on('checkbox('+key+')', function(data){
var treeConfig = {};
treeConfig[key] = data.elem.checked;
demo1.update({
tree: treeConfig
})
});
})
layui.slider.render({
elem: '#slideTest1',
min: 10,

View File

@ -115,7 +115,9 @@ model: {
//最大显示数量, 0:不限制
showCount: 0,
//是否显示删除图标
showIcon: true,
showIcon: true,
//自定义渲染label, 默认渲染name, 回调参数(item, sels)
template: null,
},
//自定义文字
count: {
@ -170,6 +172,7 @@ list: [ "ALL", "CLEAR",
| showLine | 是否显示虚线 | boolean | true / false | true |
| indent | 间距 | int | - | 20 |
| expandedKeys | 默认展开的节点数组 | array | - | [ ] |
| strict | 是否遵循严格父子结构 | boolean | true / false | true |
### 全局方法

View File

@ -61,7 +61,7 @@ class Framework extends Component{
const { prop, tree } = this.props;
let changeData = this.exchangeValue(sels, !tree.show);
if(tree.show){
if(tree.show && tree.strict){
let data = this.state.data;
this.clearAndReset(data, changeData);
changeData = this.init({ data, prop }, true);
@ -81,7 +81,8 @@ class Framework extends Component{
}
load(data, dataObj, flatData, parent){
const { children, optgroup, value, selected, disabled } = this.props.prop;
const { prop, tree } = this.props;
const { children, optgroup, value, selected, disabled } = prop;
data.forEach(item => {
//数据提取/处理
item.__node = { parent }
@ -94,15 +95,18 @@ class Framework extends Component{
if(len > 0){
this.load(child, dataObj, flatData, item);
//严格的父子结构
//是否包含子节点
item[optgroup] = true;
if(item[selected] === true){
delete item[selected]
child.forEach(c => c[selected] = true)
}
if(item[disabled] === true){
delete item[disabled]
child.forEach(c => c[disabled] = true)
//严格的父子结构
if(tree.strict){
if(item[selected] === true){
delete item[selected]
child.forEach(c => c[selected] = true)
}
if(item[disabled] === true){
delete item[disabled]
child.forEach(c => c[disabled] = true)
}
}
//检查子节点的数据是否都被选中
@ -158,20 +162,25 @@ class Framework extends Component{
//选项, 选中状态, 禁用状态, 是否强制删除:在label上点击删除
itemClick(item, itemSelected, itemDisabled, mandatoryDelete){
const { theme, prop, radio, repeat, clickClose, max, maxMethod } = this.props
const { theme, prop, radio, repeat, clickClose, max, maxMethod, tree } = this.props
let { sels } = this.state
const { value, selected, disabled, children, optgroup } = prop
//如果是禁用状态, 不能进行操作
if(itemDisabled) return;
if(item[optgroup]){
if(item[optgroup] && tree.strict){
let child = item[children], change = [], isAdd = true;
if(item.__node.selected){
this.treeHandler(sels, item, change, 'del');
isAdd = false;
}else if(item.__node.half){
this.treeHandler(sels, item, change, 'half');
//无法操作禁用状态, 变成取消操作
if(change.length === 0){
this.treeHandler(sels, item, change, 'del');
isAdd = false;
}
}else{
this.treeHandler(sels, item, change, 'add');
}

View File

@ -1,4 +1,5 @@
import { h, Component, render } from 'preact'
import { h, Component, render } from 'preact'
import { isFunction } from '@/common/util'
/**
* 标签的渲染
@ -63,14 +64,18 @@ class Label extends Component{
const style = { backgroundColor: theme.color }
//显示的个数
const count = conf.showCount <= 0 ? arr.length : conf.showCount;
const count = conf.showCount <= 0 ? arr.length : conf.showCount;
html = arr.splice(0, count).map(sel => {
const styleProps = { width: conf.showIcon ? 'calc(100% - 20px)' : '100%', }
const className = ['xm-label-block', sel[disabled] ? 'disabled':''].join(' ');
return (
<div class={className} style={ style }>
<span style={ styleProps }>{ sel[name] }</span>
<div class={className} style={ style }>
{ conf.template && isFunction(conf.template) ? (
<span style={ styleProps } dangerouslySetInnerHTML={{ __html: conf.template(sel, arr) }}></span>
) : (
<span style={ styleProps }>{ sel[name] }</span>
) }
{ conf.showIcon && <i class="xm-iconfont xm-icon-close" onClick={ this.iconClick.bind(this, sel, true, sel[disabled]) }></i> }
</div>
)

View File

@ -62,10 +62,20 @@ class Tree extends Component{
const showIcon = config.model.icon != 'hidden';
const renderItem = (item, indent, expand) => {
const half = item.__node.half === true;
const selected = !!sels.find(sel => sel[value] == item[value]) || half || item.__node.selected
const dis = item[disabled] || item.__node.disabled;
const iconStyle = selected || half ? {
//是否被选中
let selected = !!sels.find(sel => sel[value] == item[value]);
//是否禁用
let dis = item[disabled]
// 是否半选
let half = item.__node.half === true;
//tree是否遵义严格父子结构
if(tree.strict){
selected = selected || half || item.__node.selected
dis = dis || item.__node.disabled;
}
const iconStyle = selected ? {
color: theme.color,
border: 'none'
} : {
@ -77,7 +87,7 @@ class Tree extends Component{
dis && (itemStyle.backgroundColor = '#C2C2C2');
}
const className = ['xm-option', (dis ? ' disabled' : ''), (selected ? ' selected' : ''), (showIcon ? 'show-icon' : 'hide-icon') ].join(' ');
const iconClass = ['xm-option-icon xm-iconfont', radio ? 'xm-icon-danx' : half ? 'xm-icon-banxuan' : 'xm-icon-duox'].join(' ');
const iconClass = ['xm-option-icon xm-iconfont', radio ? 'xm-icon-danx' : tree.strict && half ? 'xm-icon-banxuan' : 'xm-icon-duox'].join(' ');
const treeIconClass = ['xm-tree-icon', expand ? 'expand':'', item[children] && item[children].length > 0 ? 'visible':'hidden'].join(' ');
return (

View File

@ -84,7 +84,11 @@ class xmOptions {
* 获取多选选中的数据
*/
getValue(type){
let arr = deepMerge([], childData[this.options.el].state.sels);
let arr = childData[this.options.el].state.sels.map(item => {
item = { ...item };
delete item.__node;
return item;
});
if(type === 'name'){
return arr.map(item => item[this.options.prop.name]);

View File

@ -76,13 +76,21 @@ export default function (lan = 'zn') {
show: false,
showIcon: true,
list: [ 'ALL', 'CLEAR' ],
},
tree: {
show: false,
showFolderIcon: true,
showLine: true,
indent: 20,
expandedKeys: [],
},
//树状结构
tree: {
//是否展示树
show: false,
//是否展示三角图标
showFolderIcon: true,
//是否展示连接线
showLine: true,
//间距
indent: 20,
//默认展开的节点数组
expandedKeys: [],
//是否严格遵守父子模式
strict: true,
},
//自定义属性名称
prop: {
@ -110,7 +118,8 @@ export default function (lan = 'zn') {
},
block: {
showCount: 0,
showIcon: true,
showIcon: true,
template: null,
},
count: {
template(data, sels){