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* *2019-11-21*
#### 新增
- label也可以自定义渲染
#### Bug fixes #### Bug fixes
- 树形组件
- [新增]`strict`严格父子结构
- [修改]树状结构使用`setValue`数据错误
- [修改]树状结构中`children`属性为空数组时无法操作节点的问题
- [修改]半选状态下如无可选子项则变更操作为取消
- 修改`initValue`失效的问题 - 修改`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* *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 :::demo
```html ```html
@ -10,10 +10,16 @@
<script> <script>
var demo1 = xmSelect.render({ var demo1 = xmSelect.render({
el: '#demo1', el: '#demo1',
data: [ template({ item, sels, name, value }){
{name: '张三', value: 'zhangsan', selected: true}, return item.name + '<span style="position: absolute; right: 10px; color: #8799a3">'+value+'</span>'
{name: '李四', value: 'lisi', selected: true}, },
{name: '王五', value: 'wangwu'}, prop: {
name: 'showname',
},
data: [
{name: '张三', value: 'zhangsan', showname: '组织部-张三', selected: true},
{name: '李四', value: 'lisi', showname: '策划部-李四', selected: true},
{name: '王五', value: 'wangwu', showname: '运营部-王五' },
] ]
}) })
</script> </script>
@ -21,24 +27,35 @@ var demo1 = xmSelect.render({
::: :::
### 自定义渲染 ### 自定义渲染 - label
:::demo :::demo
```html ```html
<div id="demo2" class="xm-select-demo"></div> <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({ var demo2 = xmSelect.render({
el: '#demo2', el: '#demo2',
template({ item, sels, name, value }){ model: {
return name + '<span style="position: absolute; right: 10px; color: #8799a3">'+value+'</span>' label: {
}, block: {
data: [ template: function(item, sels){
{name: '张三', value: 'zhangsan', selected: true}, return '<i class="'+icons[item.group]+'"></i>' + item.name;
{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>'
},
data: [
{group: 1, name: '张三', value: 'zhangsan', selected: true},
{group: 0, name: '李四', value: 'lisi', selected: true},
{group: 1, name: '王五', value: 'wangwu' },
] ]
}) })
</script> </script>
``` ```
::: :::

View File

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

View File

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

View File

@ -61,7 +61,7 @@ class Framework extends Component{
const { prop, tree } = this.props; const { prop, tree } = this.props;
let changeData = this.exchangeValue(sels, !tree.show); let changeData = this.exchangeValue(sels, !tree.show);
if(tree.show){ if(tree.show && tree.strict){
let data = this.state.data; let data = this.state.data;
this.clearAndReset(data, changeData); this.clearAndReset(data, changeData);
changeData = this.init({ data, prop }, true); changeData = this.init({ data, prop }, true);
@ -81,7 +81,8 @@ class Framework extends Component{
} }
load(data, dataObj, flatData, parent){ 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 => { data.forEach(item => {
//数据提取/处理 //数据提取/处理
item.__node = { parent } item.__node = { parent }
@ -94,15 +95,18 @@ class Framework extends Component{
if(len > 0){ if(len > 0){
this.load(child, dataObj, flatData, item); this.load(child, dataObj, flatData, item);
//严格的父子结构 //是否包含子节点
item[optgroup] = true; item[optgroup] = true;
if(item[selected] === true){ //严格的父子结构
delete item[selected] if(tree.strict){
child.forEach(c => c[selected] = true) if(item[selected] === true){
} delete item[selected]
if(item[disabled] === true){ child.forEach(c => c[selected] = true)
delete item[disabled] }
child.forEach(c => c[disabled] = true) if(item[disabled] === true){
delete item[disabled]
child.forEach(c => c[disabled] = true)
}
} }
//检查子节点的数据是否都被选中 //检查子节点的数据是否都被选中
@ -158,20 +162,25 @@ class Framework extends Component{
//选项, 选中状态, 禁用状态, 是否强制删除:在label上点击删除 //选项, 选中状态, 禁用状态, 是否强制删除:在label上点击删除
itemClick(item, itemSelected, itemDisabled, mandatoryDelete){ 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 let { sels } = this.state
const { value, selected, disabled, children, optgroup } = prop const { value, selected, disabled, children, optgroup } = prop
//如果是禁用状态, 不能进行操作 //如果是禁用状态, 不能进行操作
if(itemDisabled) return; if(itemDisabled) return;
if(item[optgroup]){ if(item[optgroup] && tree.strict){
let child = item[children], change = [], isAdd = true; let child = item[children], change = [], isAdd = true;
if(item.__node.selected){ if(item.__node.selected){
this.treeHandler(sels, item, change, 'del'); this.treeHandler(sels, item, change, 'del');
isAdd = false; isAdd = false;
}else if(item.__node.half){ }else if(item.__node.half){
this.treeHandler(sels, item, change, 'half'); this.treeHandler(sels, item, change, 'half');
//无法操作禁用状态, 变成取消操作
if(change.length === 0){
this.treeHandler(sels, item, change, 'del');
isAdd = false;
}
}else{ }else{
this.treeHandler(sels, item, change, 'add'); 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 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 => { html = arr.splice(0, count).map(sel => {
const styleProps = { width: conf.showIcon ? 'calc(100% - 20px)' : '100%', } const styleProps = { width: conf.showIcon ? 'calc(100% - 20px)' : '100%', }
const className = ['xm-label-block', sel[disabled] ? 'disabled':''].join(' '); const className = ['xm-label-block', sel[disabled] ? 'disabled':''].join(' ');
return ( return (
<div class={className} style={ style }> <div class={className} style={ style }>
<span style={ styleProps }>{ sel[name] }</span> { 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> } { conf.showIcon && <i class="xm-iconfont xm-icon-close" onClick={ this.iconClick.bind(this, sel, true, sel[disabled]) }></i> }
</div> </div>
) )

View File

@ -62,10 +62,20 @@ class Tree extends Component{
const showIcon = config.model.icon != 'hidden'; const showIcon = config.model.icon != 'hidden';
const renderItem = (item, indent, expand) => { const renderItem = (item, indent, expand) => {
const half = item.__node.half === true; //是否被选中
const selected = !!sels.find(sel => sel[value] == item[value]) || half || item.__node.selected let selected = !!sels.find(sel => sel[value] == item[value]);
const dis = item[disabled] || item.__node.disabled; //是否禁用
const iconStyle = selected || half ? { 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, color: theme.color,
border: 'none' border: 'none'
} : { } : {
@ -77,7 +87,7 @@ class Tree extends Component{
dis && (itemStyle.backgroundColor = '#C2C2C2'); dis && (itemStyle.backgroundColor = '#C2C2C2');
} }
const className = ['xm-option', (dis ? ' disabled' : ''), (selected ? ' selected' : ''), (showIcon ? 'show-icon' : 'hide-icon') ].join(' '); 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(' '); const treeIconClass = ['xm-tree-icon', expand ? 'expand':'', item[children] && item[children].length > 0 ? 'visible':'hidden'].join(' ');
return ( return (

View File

@ -84,7 +84,11 @@ class xmOptions {
* 获取多选选中的数据 * 获取多选选中的数据
*/ */
getValue(type){ 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'){ if(type === 'name'){
return arr.map(item => item[this.options.prop.name]); return arr.map(item => item[this.options.prop.name]);

View File

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