[refactor] Field & Stepper 自定义组件改造 (#168)

* [refactor] Field & Stepper 自定义组件改造

* Field & Stepper remove componentId
This commit is contained in:
张敏 2018-03-28 15:10:35 +08:00 committed by Yao
parent 9d2ad7e092
commit a0dcec4dc5
17 changed files with 437 additions and 338 deletions

View File

@ -54,6 +54,7 @@ module.exports = {
// Form 中使用输入框 // Form 中使用输入框
form: { form: {
name: { name: {
name: 'name',
placeholder: '请输入收货人姓名', placeholder: '请输入收货人姓名',
componentId: 'form:test:name' componentId: 'form:test:name'
}, },

View File

@ -1,7 +1,6 @@
const Zan = require('../../dist/index');
const config = require('./config'); const config = require('./config');
Page(Object.assign({}, Zan.Field, { Page(Object.assign({}, {
data: { data: {
config, config,
value: 'test', value: 'test',
@ -24,21 +23,21 @@ Page(Object.assign({}, Zan.Field, {
}, },
handleZanFieldChange(e) { handleZanFieldChange(e) {
const { componentId, detail } = e; const { detail } = e;
console.log('[zan:field:change]', componentId, detail); console.log('[zan:field:change]', detail);
}, },
handleZanFieldFocus(e) { handleZanFieldFocus(e) {
const { componentId, detail } = e; const { detail } = e;
console.log('[zan:field:focus]', componentId, detail); console.log('[zan:field:focus]', detail);
}, },
handleZanFieldBlur(e) { handleZanFieldBlur(e) {
const { componentId, detail } = e; const { detail } = e;
console.log('[zan:field:blur]', componentId, detail); console.log('[zan:field:blur]', detail);
}, },
clearInput() { clearInput() {

View File

@ -1,3 +1,6 @@
{ {
"navigationBarTitleText": "Field 输入框" "navigationBarTitleText": "Field 输入框",
"usingComponents": {
"zan-field": "../../dist/field/index"
}
} }

View File

@ -1,67 +1,106 @@
<import src="/dist/field/index.wxml" /> <import src="/dist/field/index.wxml" />
<view class="container"> <doc-page title="Field">
<view class="doc-title zan-hairline--bottom">Field</view>
<!-- Field 基础用法 --> <!-- Field 基础用法 -->
<view class="zan-panel-title">基础用法</view> <view class="zan-panel-title">基础用法</view>
<view class="zan-panel"> <view class="zan-panel">
<template <zan-field
is="zan-field" title="{{ config.base.name.title }}"
data="{{ ...config.base.name, value }}"></template> placeholder="{{ config.base.name.placeholder }}"
<template focus="{{ config.base.name.focus }}"
is="zan-field" value="{{ value }}"
data="{{ ...config.base.tel }}"></template> >
<template </zan-field>
is="zan-field" <zan-field
data="{{ ...config.base.address }}"></template> title="{{ config.base.tel.title }}"
<template placeholder="{{ config.base.tel.placeholder }}"
is="zan-field" error="{{ config.base.tel.error }}"
data="{{ ...config.base.disabled }}"></template> input-type="{{ config.base.tel.inputType }}"
>
</zan-field>
<zan-field
title="{{ config.base.address.title }}"
type="{{ config.base.address.type }}"
placeholder="{{ config.base.address.placeholder }}"
>
</zan-field>
<zan-field
title="{{ config.base.disabled.title }}"
value="{{ config.base.disabled.value }}"
disabled="{{ config.base.disabled.disabled }}"
>
</zan-field>
</view> </view>
<view class="zan-btns"> <view class="zan-btns">
<button <button
class="zan-btn zan-btn--primary" class="zan-btn zan-btn--primary"
bindtap="clearInput">清除输入</button> bindtap="clearInput"
>
清除输入
</button>
</view> </view>
<!-- 去除标题后的输入框样式 --> <!-- 去除标题后的输入框样式 -->
<view class="zan-panel-title">无标题输入框</view> <view class="zan-panel-title">无标题输入框</view>
<view class="zan-panel"> <view class="zan-panel">
<template <zan-field
is="zan-field" placeholder="{{ config.notitle.placeholder }}"
data="{{ ...config.notitle, value: textareaValue }}"></template> value="{{ textareaValue }}"
>
</zan-field>
</view> </view>
<view class="zan-btns"> <view class="zan-btns">
<button <button
class="zan-btn zan-btn--primary" class="zan-btn zan-btn--primary"
bindtap="clearTextarea">清除输入</button> bindtap="clearTextarea"
>
清除输入
</button>
</view> </view>
<!-- 使用 Field 圆角样式 --> <!-- 使用 Field 圆角样式 -->
<view class="zan-panel-title field__title--radius">圆角输入框</view> <view class="zan-panel-title field__title--radius">圆角输入框</view>
<template <zan-field
is="zan-field" title="{{ config.radius.totalPrice.title }}"
data="{{ ...config.radius.totalPrice }}"></template> type="{{ config.radius.totalPrice.type }}"
<template placeholder="{{ config.radius.totalPrice.placeholder }}"
is="zan-field" right="{{ config.radius.totalPrice.right }}"
data="{{ ...config.radius.excludePrice }}"></template> mode="{{ config.radius.totalPrice.mode }}"
<template >
is="zan-field" </zan-field>
data="{{ ...config.radius.notitle }}"></template> <zan-field
class="zan-field--radius"
title="{{ config.radius.excludePrice.title }}"
type="{{ config.radius.excludePrice.type }}"
placeholder="{{ config.radius.excludePrice.placeholder }}"
right="{{ config.radius.excludePrice.right }}"
mode="{{ config.radius.excludePrice.mode }}"
error="{{ config.radius.excludePrice.error }}"
>
</zan-field>
<zan-field
placeholder="{{ config.radius.notitle.placeholder }}"
mode="{{ config.radius.notitle.mode }}"
input-type="{{ config.radius.notitle.inputTitle }}"
>
</zan-field>
<!-- form 中使用 Field -->
<view class="zan-panel-title">Form 表单中的field应用</view> <view class="zan-panel-title">Form 表单中的field应用</view>
<form bindsubmit="formSubmit" bindreset="formReset"> <form bindsubmit="formSubmit" bindreset="formReset">
<view class="zan-panel"> <view class="zan-panel">
<template <zan-field
is="zan-field" name="{{ config.form.name.name }}"
data="{{ ...config.form.name }}"></template> placeholder="{{ config.form.name.placeholder }}"
<template >
is="zan-field" </zan-field>
data="{{ ...config.form.tel }}"></template> <zan-field
name="{{ config.form.tel.name }}"
placeholder="{{ config.form.tel.placeholder }}"
input-type="{{ config.form.tel.inputType }}"
>
</zan-field>
<view class="zan-btns"> <view class="zan-btns">
<button <button
class="zan-btn zan-btn--primary" class="zan-btn zan-btn--primary"
@ -75,45 +114,6 @@
<view class="zan-panel-title">自定义显示内容</view> <view class="zan-panel-title">自定义显示内容</view>
<view class="zan-panel"> <view class="zan-panel">
<!-- 配合 popup 使用 picker-view -->
<view class="zan-cell zan-field">
<view class="zan-cell__hd zan-field__title">人员信息</view>
<view
class="zan-field__input zan-cell__bd"
bindtap="handleDateFieldClick"
>
出生日期: {{ pickerViewConfig.year[pickerViewConfig.value[0]] }}
性别: {{ pickerViewConfig.sex[pickerViewConfig.value[1]] }}
</view>
</view>
<!-- 对应的 popup 层 -->
<view
class="zan-popup zan-popup--bottom {{ pickerViewConfig.show ? 'zan-popup--show' : ''}}"
>
<view class="zan-popup__mask" bindtap="hideDatePopup"></view>
<view class="zan-popup__container popup-field-example--bottom">
<picker-view
value="{{ pickerViewConfig.value }}"
indicator-style="height: 50px"
class="picker-view-example"
bindchange="handlePopupDateChange"
>
<picker-view-column>
<view
class="picker-view-column-example"
wx:for="{{ pickerViewConfig.year }}"
>{{item}}年</view>
</picker-view-column>
<picker-view-column>
<view
class="picker-view-column-example"
wx:for="{{ pickerViewConfig.sex }}"
>{{item}}</view>
</picker-view-column>
</picker-view>
</view>
</view>
<!-- 简单 picker 示例 --> <!-- 简单 picker 示例 -->
<view class="zan-cell zan-field"> <view class="zan-cell zan-field">
<view class="zan-cell__hd zan-field__title">选择区域</view> <view class="zan-cell__hd zan-field__title">选择区域</view>
@ -139,4 +139,4 @@
</view> </view>
</view> </view>
</view> </view>
</view> </doc-page>

View File

@ -1,5 +1,5 @@
<doc-page title="ICON"> <doc-page title="ICON">
<view wx:for="{{ icons }}" wx:for-item="icon" class="icon-wrap"> <view wx:for="{{ icons }}" wx:for-item="icon" wx:key="icon" class="icon-wrap">
<view class="example-icon"> <view class="example-icon">
<zan-icon type="{{ icon }}"></zan-icon> <zan-icon type="{{ icon }}"></zan-icon>
</view> </view>

View File

@ -1,6 +1,4 @@
var Zan = require('../../dist/index'); Page(Object.assign({}, {
Page(Object.assign({}, Zan.Stepper, {
data: { data: {
stepper1: { stepper1: {
stepper: 10, stepper: 10,
@ -8,20 +6,21 @@ Page(Object.assign({}, Zan.Stepper, {
max: 20 max: 20
}, },
stepper2: { stepper2: {
stepper: 1, stepper: 10,
min: 1, min: 1,
max: 1 max: 20
}, },
stepper3: { stepper3: {
stepper: 10, stepper: 10,
min: 1, min: 1,
max: 20 max: 20,
step: 2
} }
}, },
handleZanStepperChange(e) { handleZanStepperChange(e) {
var componentId = e.componentId; const componentId = e.target.dataset.componentId;
var stepper = e.stepper; const stepper = e.detail;
this.setData({ this.setData({
[`${componentId}.stepper`]: stepper [`${componentId}.stepper`]: stepper

View File

@ -1,3 +1,6 @@
{ {
"navigationBarTitleText": "Stepper 计数器" "navigationBarTitleText": "Stepper 计数器",
"usingComponents": {
"zan-stepper": "../../dist/stepper/index"
}
} }

View File

@ -1,20 +1,40 @@
<import src="/dist/stepper/index.wxml" /> <doc-page title="Stepper">
<view class="zan-panel-title">基础用法</view>
<view class="container">
<view class="doc-title zan-hairline--bottom">Stepper</view>
<view style="padding: 40px 15px"> <view style="padding: 40px 15px">
<template is="zan-stepper" data="{{ ...stepper1, componentId: 'stepper1' }}" /> <zan-stepper
</view> stepper="{{ stepper1.stepper }}"
min="{{ stepper1.min }}"
<!-- 当最大值等于最小值时,组件不可用 --> max="{{ stepper1.max }}"
<view style="padding: 40px 15px "> data-component-id="stepper1"
<template is="zan-stepper" data="{{ ...stepper2, componentId: 'stepper2' }}" /> bind:change="handleZanStepperChange"
>
</zan-stepper>
</view> </view>
<!-- small size --> <!-- small size -->
<view style="padding: 40px 15px "> <view class="zan-panel-title">不同尺寸</view>
<template is="zan-stepper" data="{{ ...stepper3, componentId: 'stepper3', size: 'small' }}" /> <view style="padding: 40px 15px">
<zan-stepper
stepper="{{ stepper2.stepper }}"
min="{{ stepper2.min }}"
max="{{ stepper2.max }}"
size="small"
data-component-id="stepper2"
bind:change="handleZanStepperChange"
>
</zan-stepper>
</view> </view>
</view>
<view class="zan-panel-title">高级用法</view>
<view style="padding: 40px 15px">
<zan-stepper
stepper="{{ stepper3.stepper }}"
min="{{ stepper3.min }}"
max="{{ stepper3.max }}"
step="{{ stepper3.step }}"
data-component-id="stepper3"
bind:change="handleZanStepperChange"
>
</zan-stepper>
</view>
</doc-page>

View File

@ -1,55 +1,87 @@
## Field 输入框 ## Field 输入框
### 使用指南 ### 使用指南
在 app.wxss 中引入组件库所有样式 在 index.json 中引入组件
```css ```json
@import "path/to/zanui-weapp/dist/index.wxss"; {
``` "usingComponents": {
"zan-field": "path/to/zanui-weapp/dist/field/index"
在需要使用的页面里引入组件库模板和脚本 }
```html }
<import src="path/to/zanui-weapp/dist/field/index.wxml" />
<!-- 直接使用 zan-field 模板,并且直接传入设置值 -->
<template is="zan-field" data="{{ value }}"></template>
```
```js
const { Field, extend } = require('path/to/zanui-weapp/dist/index');
// 在 Page 中混入 Field 里面声明的方法
Page(extend({}, Field, {
// ...
}));
``` ```
### 代码演示 ### 代码演示
#### 基础用法
field 支持多种展示方式,在 `data` 中传入对应的设置即可。 field 支持多种展示方式,在 `data` 中传入对应的设置即可。
```html ```html
<template is="zan-field" data="{{ title: '收货人', type: 'input', placeholder: '名字', value }}"></template> <zan-field
title="{{ field.title }}"
placeholder="{{ field.placeholder }}"
focus="{{ field.focus }}"
value="{{ field.value }}"
>
</zan-field>
``` ```
当 field 触发输入事件时,可以在页面中注册 handleZanFieldChange 方法来监听
```js ```js
Page(extend({}, Field, { Page(extend({}, {
// 输入框内容更改时触发 data: {
handleZanFieldChange({ componentId, detail }) { field: {
/* focus: true,
* componentId 即为在模板中传入的 componentId title: '收货人',
* 用于在一个页面上使用多个 tab 时,进行区分 placeholder: '名字',
* detail 即输入框中的内容 value: 'test'
*/ }
/* }
* 处理函数可以直接 return 一个字符串,将替换输入框的内容。
*/
},
// 输入框聚焦时触发
handleZanFieldFocus({ componentId, detail }) {},
// 输入框失焦时触发
handleZanFieldBlur({ componentId, detail }) {},
})); }));
``` ```
`Field` 支持传入参数如下 #### 监听事件
field会触发一些事件当你需要监听这些事件时可以绑定对应的事件。
```html
<zan-field
title="{{ field.title }}"
placeholder="{{ field.placeholder }}"
focus="{{ field.focus }}"
value="{{ field.value }}"
bind:change="handleFieldChange"
bind:focus="handleFieldFocus"
bind:blur="handleFieldBlur"
>
</zan-field>
```
```js
Page(extend({}, {
data: {
field: {
focus: true,
title: '收货人',
placeholder: '名字',
value: 'test'
}
},
methods: {
handleFieldChange(event) {
console.log(event);
},
handleFieldFocus(event) {
console.log(event);
},
handleFieldBlur(event) {
console.log(event);
}
}
}));
```
### API
| 参数 | 说明 | 类型 | 默认值 | 必须 | | 参数 | 说明 | 类型 | 默认值 | 必须 |
|-----------|-----------|-----------|-------------|-------------| |-----------|-----------|-----------|-------------|-------------|
@ -65,3 +97,11 @@ Page(extend({}, Field, {
| right | 输入框内容是否居右显示 | Boolean | false | | | right | 输入框内容是否居右显示 | Boolean | false | |
| error | 是否显示为输入框错误情况下的样式 | Boolean | false | | | error | 是否显示为输入框错误情况下的样式 | Boolean | false | |
| componentId | 用于区分输入框之间的唯一名称 | String | - | | | componentId | 用于区分输入框之间的唯一名称 | String | - | |
### Event
| 事件名称 | 说明 | 回调参数 |
|-----------|-----------|-----------|
| change | 当绑定值变化时触发的事件 | event对象 |
| focus | 输入框focus | event对象 |
| blur | 输入框blur | event对象 |

View File

@ -1,38 +1,44 @@
const { extractComponentId } = require('../common/helper'); Component({
properties: {
module.exports = { title: String,
_handleZanFieldChange(event) { name: String,
const componentId = extractComponentId(event); type: {
event.componentId = componentId; type: String,
value: 'input'
console.info('[zan:field:change]', event); },
name: String,
if (this.handleZanFieldChange) { value: String,
return this.handleZanFieldChange(event); disabled: Boolean,
} inputType: {
type: String,
console.warn('页面缺少 handleZanFieldChange 回调函数'); value: 'text'
},
placeholder: String,
focus: Boolean,
mode: {
type: String,
value: 'normal'
},
right: Boolean,
error: Boolean
}, },
_handleZanFieldFocus(event) { methods: {
const componentId = extractComponentId(event); handleZanFieldChange(event) {
event.componentId = componentId; console.info('[zan:field:change]', event);
this.triggerEvent('change', event);
console.info('[zan:field:focus]', event); },
if (this.handleZanFieldFocus) { handleZanFieldFocus(event) {
return this.handleZanFieldFocus(event); console.info('[zan:field:focus]', event);
}
}, this.triggerEvent('focus', event);
},
_handleZanFieldBlur(event) {
const componentId = extractComponentId(event); handleZanFieldBlur(event) {
event.componentId = componentId; console.info('[zan:field:blur]', event);
console.info('[zan:field:blur]', event); this.triggerEvent('blur', event);
if (this.handleZanFieldBlur) {
return this.handleZanFieldBlur(event);
} }
} }
}; })

View File

@ -0,0 +1,3 @@
{
"component": true
}

View File

@ -6,7 +6,7 @@
} }
.zan-field--wrapped { .zan-field--wrapped {
margin: 0 15px; margin: 10px 15px;
background-color: #fff; background-color: #fff;
&::after { &::after {
@ -21,16 +21,12 @@
display: block; display: block;
} }
.zan-field--wrapped + .zan-field--wrapped {
margin-top: 10px;
}
.zan-field--error { .zan-field--error {
color: #f40; color: #f40;
} }
/* 圆角输入框出现错误时,将边框也置红 */ /* 圆角输入框出现错误时,将边框也置红 */
.zan-field--wrapped.zan-field--error::after { .zan-field--wrapped.zan-field--error::after {
border-color: #f40; border-color: #f40;
} }

View File

@ -1,35 +1,35 @@
<template name="zan-field"> <view class="zan-cell zan-field {{ error ? 'zan-field--error' : '' }} {{ mode === 'wrapped' ? 'zan-field--wrapped' : '' }}">
<view class="zan-cell zan-field {{ error ? 'zan-field--error' : '' }} {{ mode === 'wrapped' ? 'zan-field--wrapped' : '' }}"> <view
<view wx:if="{{ title }}"
wx:if="{{ title }}" class="zan-cell__hd zan-field__title">
class="zan-cell__hd zan-field__title">{{ title }}</view> {{ title }}
<textarea
wx:if="{{ type === 'textarea' }}"
auto-height
name="{{ name || componentId || '' }}"
disabled="{{ disabled }}"
focus="{{ focus }}"
value="{{ value }}"
placeholder="{{ placeholder }}"
class="zan-field__input zan-cell__bd {{ right ? 'zan-field__input--right' : '' }}"
placeholder-class="zan-field__placeholder"
bindinput="_handleZanFieldChange"
bindfocus="_handleZanFieldFocus"
bindblur="_handleZanFieldBlur"
data-component-id="{{ componentId || '' }}"></textarea>
<input
wx:else
type="{{ inputType || 'text' }}"
name="{{ name || componentId || '' }}"
disabled="{{ disabled }}"
focus="{{ focus }}"
value="{{ value }}"
placeholder="{{ placeholder }}"
class="zan-field__input zan-cell__bd {{ right ? 'zan-field__input--right' : '' }}"
placeholder-class="zan-field__placeholder"
bindinput="_handleZanFieldChange"
bindfocus="_handleZanFieldFocus"
bindblur="_handleZanFieldBlur"
data-component-id="{{ componentId || '' }}"/>
</view> </view>
</template> <textarea
wx:if="{{ type === 'textarea' }}"
auto-height
name="{{ name || '' }}"
disabled="{{ disabled }}"
focus="{{ focus }}"
value="{{ value }}"
placeholder="{{ placeholder }}"
class="zan-field__input zan-cell__bd {{ right ? 'zan-field__input--right' : '' }}"
placeholder-class="zan-field__placeholder"
bindinput="handleZanFieldChange"
bindfocus="handleZanFieldFocus"
bindblur="handleZanFieldBlur">
</textarea>
<input
wx:else
type="{{ inputType || 'text' }}"
name="{{ name || '' }}"
disabled="{{ disabled }}"
focus="{{ focus }}"
value="{{ value }}"
placeholder="{{ placeholder }}"
class="zan-field__input zan-cell__bd {{ right ? 'zan-field__input--right' : '' }}"
placeholder-class="zan-field__placeholder"
bindinput="handleZanFieldChange"
bindfocus="handleZanFieldFocus"
bindblur="handleZanFieldBlur"
/>
</view>

View File

@ -1,45 +1,32 @@
## Stepper 计数器 ## Stepper 计数器
### 使用指南 ### 使用指南
在 app.wxss 中引入组件库所有样式 在 index.json 中引入组件
```css ```json
@import "path/to/zanui-weapp/dist/index.wxss"; {
``` "usingComponents": {
"zan-stepper": "path/to/zanui-weapp/dist/stepper/index"
在需要使用的页面里引入组件库模板和脚本 }
```html }
<import src="path/to/zanui-weapp/dist/stepper/index.wxml" />
<template is="zan-stepper" data="{{ ...stepper, componentId: 'stepper' }}"></template>
```
```js
const { extend, Stepper } = require('path/to/zanui-weapp/dist/index');
// 在 Page 中混入 Stepper 里面声明的方法
Page(extend({}, Stepper, {
// ...
}));
``` ```
### 代码演示 ### 代码演示
#### 基础功能
#### 基础用法
`Stepper` 组件通过传入的 stepper 对象控制,内部数据格式如下: `Stepper` 组件通过传入的 stepper 对象控制,内部数据格式如下:
```js ```js
const stepper = { Page(extend({}, {
// 当前 stepper 数字 data: {
stepper: 1, stepper: {
// 最小可到的数字 // 当前 stepper 数字
min: 1, stepper: 1,
// 最大可到的数字 // 最小可到的数字
max: 1 min: 1,
}; // 最大可到的数字
``` max: 1
}
},
当一个 `Stepper`min 超过 max就会导致组件被置灰
当 stepper 被点击时,可以在页面中注册 handleZanStepperChange 方法来监听
```js
Page(extend({}, Stepper, {
handleZanStepperChange({ componentId, stepper }) { handleZanStepperChange({ componentId, stepper }) {
// componentId 即为在模板中传入的 componentId // componentId 即为在模板中传入的 componentId
// 用于在一个页面上使用多个 stepper 时,进行区分 // 用于在一个页面上使用多个 stepper 时,进行区分
@ -50,3 +37,37 @@ Page(extend({}, Stepper, {
} }
})); }));
``` ```
当一个 `Stepper`min 超过 max就会导致组件被置灰。
当 stepper 被点击时,需要监听`change`事件,处理计数器值的改变。
```js
<zan-stepper
stepper="{{ stepper.stepper }}"
min="{{ stepper.min }}"
max="{{ stepper.max }}"
component-id="stepper"
bind:change="handleZanStepperChange"
>
</zan-stepper>
```
### API
| 参数 | 说明 | 类型 | 默认值 | 必须 |
|-----------|-----------|-----------|-------------|-------------|
| size | 计数器尺寸 | String | - | |
| stepper | 计数器的值 | Number | `1` | 必须 |
| min | 计数器最小值 | Number | `1` | |
| max | 计数器最大值 | Number | 无穷大 | |
| step | 步数 | Number | `1` | |
| componentId | 用于区分输入框之间的唯一名称 | String | - | |
### Event
| 事件名称 | 说明 | 回调参数 |
|-----------|-----------|-----------|
| change | 当绑定值变化时触发的事件 | `{ index, stepper }` |
| minus | 点击减少按钮时触发 | - |
| plus | 点击增加按钮时触发 | - |

View File

@ -1,61 +1,71 @@
function handle(e, num) { Component({
var dataset = e.currentTarget.dataset; properties: {
var componentId = dataset.componentId; size: String,
var disabled = dataset.disabled; stepper: {
var stepper = +dataset.stepper; type: Number,
value: 1
if (disabled) return null; },
min: {
callback.call(this, componentId, stepper + num); type: Number,
} value: 1
},
function callback(componentId, stepper) { max: {
stepper = +stepper; type: Number,
var e = { componentId, stepper }; value: Infinity
console.info('[zan:stepper:change]', e); },
step: {
if (this.handleZanStepperChange) { type: Number,
this.handleZanStepperChange(e); value: 1
} else { }
console.warn('页面缺少 handleZanStepperChange 回调函数');
}
}
var Stepper = {
_handleZanStepperMinus(e) {
handle.call(this, e, -1);
}, },
_handleZanStepperPlus(e) { methods: {
handle.call(this, e, +1); handleZanStepperChange(e, type) {
}, const dataset = e.currentTarget.dataset;
const disabled = dataset.disabled;
const { step } = this.data;
let stepper = this.data.stepper;
_handleZanStepperBlur(e) { if (disabled) return null;
var dataset = e.currentTarget.dataset;
var componentId = dataset.componentId;
var max = +dataset.max;
var min = +dataset.min;
var value = e.detail.value;
if (!value) { if (type === 'minus') {
setTimeout(() => { stepper -= step;
callback.call(this, componentId, min); } else if (type === 'plus') {
}, 16); stepper += step;
callback.call(this, componentId, value); }
return '' + value;
this.triggerEvent('change', stepper);
this.triggerEvent(type);
},
handleZanStepperMinus(e) {
this.handleZanStepperChange(e, 'minus');
},
handleZanStepperPlus(e) {
this.handleZanStepperChange( e, 'plus');
},
handleZanStepperBlur(e) {
const dataset = e.currentTarget.dataset;
let value = e.detail.value;
const { min, max } = this.data;
if (!value) {
setTimeout(() => {
this.triggerEvent('change', min);
}, 16);
return;
}
value = +value;
if (value > max) {
value = max;
} else if (value < min) {
value = min;
}
this.triggerEvent('change', value);
} }
value = +value;
if (value > max) {
value = max;
} else if (value < min) {
value = min;
}
callback.call(this, componentId, value);
return '' + value;
} }
}; });
module.exports = Stepper;

View File

@ -0,0 +1,3 @@
{
"component": true
}

View File

@ -1,28 +1,23 @@
<template name="zan-stepper"> <view class="zan-stepper {{ size === 'small' ? 'zan-stepper--small' : '' }}">
<view class="zan-stepper {{ size === 'small' ? 'zan-stepper--small' : '' }}"> <view
<view class="zan-stepper__minus {{ stepper <= min ? 'zan-stepper--disabled' : '' }}"
class="zan-stepper__minus {{ stepper <= min ? 'zan-stepper--disabled' : '' }}" data-disabled="{{ stepper <= min }}"
data-component-id="{{ componentId }}" bindtap="handleZanStepperMinus"
data-stepper="{{ stepper }}" >
data-disabled="{{ stepper <= min }}" -
bindtap="_handleZanStepperMinus"
>-</view>
<input
class="zan-stepper__text {{ min >= max ? 'zan-stepper--disabled' : '' }}"
type="number"
data-component-id="{{ componentId }}"
data-min="{{ min }}"
data-max="{{ max }}"
value="{{ stepper }}"
disabled="{{ min >= max }}"
bindblur="_handleZanStepperBlur"
></input>
<view
class="zan-stepper__plus {{ stepper >= max ? 'zan-stepper--disabled' : '' }}"
data-component-id="{{ componentId }}"
data-stepper="{{ stepper }}"
data-disabled="{{ stepper >= max }}"
bindtap="_handleZanStepperPlus"
>+</view>
</view> </view>
</template> <input
class="zan-stepper__text {{ min >= max ? 'zan-stepper--disabled' : '' }}"
type="number"
value="{{ stepper }}"
disabled="{{ min >= max }}"
bindblur="handleZanStepperBlur"
/>
<view
class="zan-stepper__plus {{ stepper >= max ? 'zan-stepper--disabled' : '' }}"
data-disabled="{{ stepper >= max }}"
bindtap="handleZanStepperPlus"
>
+
</view>
</view>