[improvement] Field: 优化在列表中输入框表现 (#296)

* 优化 field 实现

* field 使用cell来架构

* field 列表
This commit is contained in:
Yao 2018-06-04 21:52:32 +08:00 committed by GitHub
parent d3eee374dd
commit 876c75a388
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 122 additions and 51 deletions

View File

@ -3,6 +3,7 @@
"usingComponents": { "usingComponents": {
"zan-button": "../../dist/btn/index", "zan-button": "../../dist/btn/index",
"zan-button-group": "../../dist/btn-group/index", "zan-button-group": "../../dist/btn-group/index",
"zan-cell-group": "../../dist/cell-group/index",
"zan-field": "../../dist/field/index", "zan-field": "../../dist/field/index",
"zan-panel": "../../dist/panel/index", "zan-panel": "../../dist/panel/index",
"doc-page": "../../components/doc-page/index" "doc-page": "../../components/doc-page/index"

View File

@ -1,33 +1,35 @@
<doc-page title="Field" without-padding> <doc-page title="Field" without-padding>
<!-- Field 基础用法 --> <!-- Field 基础用法 -->
<zan-panel title="基础用法"> <zan-panel title="基础用法">
<zan-field <zan-cell-group>
title="{{ config.base.name.title }}" <zan-field
placeholder="{{ config.base.name.placeholder }}" title="{{ config.base.name.title }}"
focus="{{ config.base.name.focus }}" placeholder="{{ config.base.name.placeholder }}"
value="{{ value }}" focus="{{ config.base.name.focus }}"
> value="{{ value }}"
</zan-field> >
<zan-field </zan-field>
title="{{ config.base.tel.title }}" <zan-field
placeholder="{{ config.base.tel.placeholder }}" title="{{ config.base.tel.title }}"
error="{{ config.base.tel.error }}" placeholder="{{ config.base.tel.placeholder }}"
input-type="{{ config.base.tel.inputType }}" error="{{ config.base.tel.error }}"
> input-type="{{ config.base.tel.inputType }}"
</zan-field> >
<zan-field </zan-field>
title="{{ config.base.address.title }}" <zan-field
type="{{ config.base.address.type }}" title="{{ config.base.address.title }}"
placeholder="{{ config.base.address.placeholder }}" type="{{ config.base.address.type }}"
maxlength="50" placeholder="{{ config.base.address.placeholder }}"
> maxlength="50"
</zan-field> >
<zan-field </zan-field>
title="{{ config.base.disabled.title }}" <zan-field
value="{{ config.base.disabled.value }}" title="{{ config.base.disabled.title }}"
disabled="{{ config.base.disabled.disabled }}" value="{{ config.base.disabled.value }}"
> disabled="{{ config.base.disabled.disabled }}"
</zan-field> >
</zan-field>
</zan-cell-group>
</zan-panel> </zan-panel>
<zan-button-group> <zan-button-group>

View File

@ -1,44 +1,58 @@
const CELL_PATH = '../cell/index';
const FIELD_PATH = '../field/index'
Component({ Component({
relations: { relations: {
'../cell/index': { [CELL_PATH]: {
type: 'child', type: 'child',
linked() { linked() {
this._updateIsLastCell(); this._updateIsLastElement(CELL_PATH);
}, },
linkChanged() { linkChanged() {
this._updateIsLastCell(); this._updateIsLastElement(CELL_PATH);
}, },
unlinked() { unlinked() {
this._updateIsLastCell(); this._updateIsLastElement(CELL_PATH);
}
},
[FIELD_PATH]: {
type: 'child',
linked() {
this._updateIsLastElement(FIELD_PATH);
},
linkChanged() {
this._updateIsLastElement(FIELD_PATH);
},
unlinked() {
this._updateIsLastElement(FIELD_PATH);
} }
} }
}, },
data: { data: {
cellUpdateTimeout: 0 elementUpdateTimeout: 0
}, },
methods: { methods: {
_updateIsLastCell() { _updateIsLastElement(childPath) {
// 用 setTimeout 减少计算次数 // 用 setTimeout 减少计算次数
if (this.data.cellUpdateTimeout > 0) { if (this.data.elementUpdateTimeout > 0) {
return; return;
} }
const cellUpdateTimeout = setTimeout(() => { const elementUpdateTimeout = setTimeout(() => {
this.setData({ cellUpdateTimeout: 0 }); this.setData({ elementUpdateTimeout: 0 });
let cells = this.getRelationNodes('../cell/index'); let elements = this.getRelationNodes(childPath);
if (elements.length > 0) {
let lastIndex = elements.length - 1;
if (cells.length > 0) { elements.forEach((cell, index) => {
let lastIndex = cells.length - 1; cell.updateIsLastElement(index === lastIndex);
cells.forEach((cell, index) => {
cell.updateIsLastCell(index === lastIndex);
}); });
} }
}); });
this.setData({ cellUpdateTimeout }); this.setData({ elementUpdateTimeout });
} }
} }
}); });

View File

@ -70,7 +70,7 @@ Component({
}, },
// 用于被 cell-group 更新,标志是否是最后一个 cell // 用于被 cell-group 更新,标志是否是最后一个 cell
updateIsLastCell(isLastCell) { updateIsLastElement(isLastCell) {
this.setData({ isLastCell }); this.setData({ isLastCell });
} }
} }

View File

@ -38,6 +38,14 @@ Page({
}); });
``` ```
#### Field 列表
```html
<zan-cell-group>
<zan-field title="姓名"></zan-field>
<zan-field title="邮件"></zan-field>
</zan-cell-group>
```
#### 监听事件 #### 监听事件
field会触发一些事件当你需要监听这些事件时可以绑定对应的事件。 field会触发一些事件当你需要监听这些事件时可以绑定对应的事件。

View File

@ -1,6 +1,14 @@
Component({ Component({
behaviors: ['wx://form-field'], behaviors: ['wx://form-field'],
externalClasses: ['field-class'],
relations: {
'../cell-group/index': {
type: 'parent'
}
},
properties: { properties: {
title: String, title: String,
type: { type: {
@ -8,12 +16,12 @@ Component({
value: 'input' value: 'input'
}, },
disabled: Boolean, disabled: Boolean,
focus: Boolean,
inputType: { inputType: {
type: String, type: String,
value: 'text' value: 'text'
}, },
placeholder: String, placeholder: String,
focus: Boolean,
mode: { mode: {
type: String, type: String,
value: 'normal' value: 'normal'
@ -26,6 +34,10 @@ Component({
} }
}, },
data: {
showBorder: true
},
methods: { methods: {
handleFieldChange(event) { handleFieldChange(event) {
const { detail = {} } = event; const { detail = {} } = event;
@ -41,6 +53,17 @@ Component({
handleFieldBlur(event) { handleFieldBlur(event) {
this.triggerEvent('blur', event); this.triggerEvent('blur', event);
},
updateIsLastElement(isLastField) {
let showBorder = true;
if (isLastField && this.data.mode === 'normal') {
showBorder = false;
}
this.setData({
showBorder
});
} }
} }
}); });

View File

@ -1,3 +1,6 @@
{ {
"component": true "component": true,
"usingComponents": {
"zan-cell": "../cell/index"
}
} }

View File

@ -1,10 +1,26 @@
@import '../cell/index'; @import "../common/_mixins";
.zan-field { .zan-field {
padding: 7px 15px; display: block;
position: relative;
color: #333; color: #333;
} }
.zan-field::after {
@mixin hairline;
border-bottom-width: 1px;
left: 15px;
right: 0;
}
.zan-field--no-border::after {
border-bottom-width: 0;
}
.zan-cell--field {
padding: 7px 15px;
}
.zan-field--wrapped { .zan-field--wrapped {
margin: 10px 15px; margin: 10px 15px;
background-color: #fff; background-color: #fff;
@ -17,7 +33,7 @@
} }
/* 圆角输入框,强制展示边框 */ /* 圆角输入框,强制展示边框 */
.zan-field.zan-field--wrapped::after { .zan-field--wrapped::after {
display: block; display: block;
} }

View File

@ -1,5 +1,9 @@
<view class="zan-cell zan-field {{ error ? 'zan-field--error' : '' }} {{ mode === 'wrapped' ? 'zan-field--wrapped' : '' }}"> <zan-cell
class="field-class zan-field {{ error ? 'zan-field--error' : '' }} {{ mode === 'wrapped' ? 'zan-field--wrapped' : '' }} {{ !showBorder ? 'zan-field--no-border' : '' }}"
cell-class="zan-cell--field"
>
<view <view
slot="icon"
wx:if="{{ title }}" wx:if="{{ title }}"
class="zan-cell__hd zan-field__title"> class="zan-cell__hd zan-field__title">
{{ title }} {{ title }}
@ -32,4 +36,4 @@
bindfocus="handleFieldFocus" bindfocus="handleFieldFocus"
bindblur="handleFieldBlur" bindblur="handleFieldBlur"
/> />
</view> </zan-cell>