[breaking change] Search: rewrite

This commit is contained in:
陈嘉涵 2018-08-07 15:01:09 +08:00
parent f76c438f1d
commit 8ecff7904c
9 changed files with 195 additions and 262 deletions

View File

@ -1,20 +1,27 @@
Page({ Page({
data: { data: {
inputValue: '', value: ''
focus: true
}, },
searchChange(e) { onChange(e) {
this.setData({ this.setData({
inputValue: e.detail.value value: e.detail
}); });
}, },
searchDone(e) { onSearch(event) {
console.error('search', e.detail.value) if (event.detail) {
wx.showToast({
title: '搜索:' + event.detail,
icon: 'none'
});
}
}, },
handleCancel() { onCancel() {
console.error('cancel') wx.showToast({
title: '取消',
icon: 'none'
});
} }
}); });

View File

@ -1,8 +1,7 @@
{ {
"navigationBarTitleText": "Search 搜索", "navigationBarTitleText": "Search 搜索",
"usingComponents": { "usingComponents": {
"van-icon": "../icon/index", "demo-block": "../../components/demo-block/index",
"van-search": "../../dist/search/index", "van-search": "../../dist/search/index"
"van-panel": "../../dist/panel/index"
} }
} }

View File

@ -1,48 +1,31 @@
<van-panel title='基本用法'> <demo-block title="基本用法">
<van-search <van-search
alignLeft="{{ true }}" value="{{ value }}"
placeholder="搜索..." placeholder="请输入搜索关键词"
keyword="{{ inputValue }}" bind:change="onChange"
placeholder="搜索商品" bind:search="onSearch"
focus="{{ focus }}"
bindchange="searchChange"
bindsearch="searchDone"
/> />
</van-panel> </demo-block>
<van-panel title='不可用'> <demo-block title="监听对应事件">
<van-search <van-search
alignLeft="{{ true }}" value="{{ value }}"
placeholder="搜索..." show-action
disabled="{{ true }}" placeholder="请输入搜索关键词"
placeholder="搜索商品" bind:change="onChange"
bind:search="onSearch"
bind:cancel="onCancel"
/> />
</van-panel> </demo-block>
<van-panel title='自定义样式'> <demo-block title="自定义行动按钮">
<van-search <van-search
alignLeft="{{ true }}" value="{{ value }}"
placeholder="搜索..." placeholder="请输入搜索关键词"
searchStyle="height: 88rpx; padding: 0 30rpx; background: {{ searchbg || '#F2F2F2' }};" use-action-slot
inputStyle="height: 56rpx; border-radius: 8rpx;" bind:change="onChange"
keyword="{{ inputValue }}" bind:search="onSearch"
placeholder="搜索商品" >
focus="{{ focus }}" <view slot="action" bind:tap="onSearch">搜索</view>
bindchange="searchChange" </van-search>
bindsearch="searchDone" </demo-block>
/>
</van-panel>
<van-panel title='取消按钮'>
<van-search
alignLeft="{{ true }}"
placeholder="搜索..."
keyword="{{ inputValue }}"
placeholder="搜索商品"
focus="{{ focus }}"
useCancel="{{ true }}"
bindchange="searchChange"
bindsearch="searchDone"
bindcancel="handleCancel"
/>
</van-panel>

View File

@ -1,6 +1,6 @@
{ {
"name": "vant-weapp", "name": "vant-weapp",
"version": "3.0.10", "version": "0.0.1-beta",
"description": "高颜值、好用、易扩展的小程序 UI 库Powered by 有赞", "description": "高颜值、好用、易扩展的小程序 UI 库Powered by 有赞",
"main": "app.js", "main": "app.js",
"directories": { "directories": {

View File

@ -3,63 +3,73 @@
### 使用指南 ### 使用指南
在 index.json 中引入组件 在 index.json 中引入组件
```json ```json
{
"usingComponents": { "usingComponents": {
"van-search": "/packages/search/index" "van-search": "/packages/search/index"
} }
}
``` ```
### 代码演示 #### 基础用法
value 用于控制搜索框中的文字
```wxml ```html
<van-search value="{{ value }}" placeholder="请输入搜索关键词" />
```
#### 监听对应事件
Search 提供了 search 和 cancel 事件。search 事件在用户点击键盘上的搜索按钮触发。cancel 事件在用户点击搜索框右侧取消按钮时触发
```html
<van-search <van-search
placeholder="搜索..." v-model="value"
keyword="{{ inputValue }}" placeholder="请输入搜索关键词"
placeholder="搜索商品" show-action
focus="{{ focus }}" @search="onSearch"
bindchange="searchChange" @cancel="onCancel"
bindsearch="searchDone"
/> />
``` ```
```js #### 自定义行动按钮
data: {
inputValue: '',
focus: true
},
searchChange(e) {
this.setData({
inputValue: e.detail.value
});
},
searchDone(e) { Search 支持自定义右侧取消按钮,使用名字为 action 的 slot 即可。
console.log('search', e.detail.value)
} ```html
<van-search
v-model="value"
placeholder="请输入搜索关键词"
use-action-slot
@search="onSearch"
>
<view slot="action" @click="onSearch">搜索</view>
</van-search>
``` ```
### API ### API
Search 默认支持 Input 标签所有的原生属性,比如 `maxlength``placeholder``readony``autofocus`
#### 参数 | 参数 | 说明 | 类型 | 默认值 |
| 名称 | 类型 | 是否必须 | 默认 | 描述 | |-----------|-----------|-----------|-------------|
| ---------------- | ----------- | -------- | ----- | --------------------------------------------------- | | value | 当前输入的值 | `String | Number` | - |
| keyword | String | 否 | 无 | 默认搜索关键字 | | background | 搜索框背景色 | `String` | `#f2f2f2` |
| disabled | Boolean | 否 | false | 是否禁用 | | show-action | 是否在搜索框右侧显示取消按钮 | `Boolean` | `false` |
| focus | Boolean | 否 | false | 是否获取焦点 | | use-action-slot | 是否使用 action slot | `Boolean` | `false` |
| useCancel | Boolean | 否 | false | 是否显示取消按钮 | | disabled | 是否禁用输入框 | `Boolean` | `false` |
| cancelText | String | 否 | 取消 | 取消按钮文字 | | | readonly | 是否只读 | `Boolean` | `false` |
| placeholder | String | 否 | 无 | 输入框占位字符串 | | maxlength | 最大输入长度,设置为 -1 的时候不限制最大长度 | `Number` | `-1` |
| cancelStyle | String | 否 | 无 | “取消”的样式 | | focus | 获取焦点 | `Boolean` | `false` |
| inputStyle | String | 否 | 无 | “输入框”的样式
| searchStyle | String | 否 | 无 | “整个搜索”的样式
#### 事件 ### Event
Search 默认支持 Input 标签所有的原生事件,如 `focus``blur``keypress`
| 名称 | 类型 | 是否必须 | 默认 | 描述 | 事件名 | 说明 | 参数 |
| ---------------- | ----------- | -------- | ----- | ------| |-----------|-----------|-----------|
| bindcancel | EventHandle | 否 | 无 | 取消按钮点击时触发 | search | 确定搜索时触发 | event.detail: 当前输入值 |
| bindsearch | EventHandle | 否 | 无 | 键盘点击确认时触发 | change | 输入内容变化时触发 | event.detail: 当前输入值 |
| bindchange | EventHandle | 否 | 无 | 内容改变时触发 | cancel | 取消搜索搜索时触发 | - |
| bindblur | EventHandle | 否 | 无 | 焦点丢失时触发 | focus | 输入框聚焦时触发 | - |
| bindfocus | EventHandle | 否 | 无 | 焦点聚焦时触发 | blur | 输入框失焦时触发 | - |
### Slot
| 名称 | 说明 |
|-----------|-----------|
| action | 自定义搜索框右侧按钮,需要在`showAction`为 true 时才会显示 |

View File

@ -1,67 +1,57 @@
Component({ Component({
externalClasses: ['search-class', 'input-class', 'cancel-class'], externalClasses: ['custom-class', 'cancel-class'],
options: {
multipleSlots: true
},
properties: { properties: {
cancelText: { disabled: Boolean,
readonly: Boolean,
showAction: Boolean,
useActionSlot: Boolean,
placeholder: String,
value: {
type: String, type: String,
value: '取消' observer(currentValue) {
}, this.setData({ currentValue });
disabled: {
type: Boolean,
value: false
},
focus: {
type: Boolean,
value: false
},
keyword: {
type: String,
value: ''
},
show: {
type: Array,
value: ['icon', 'cancel']
},
placeholder: {
type: String,
value: '请输入查询关键字',
observer(newVal) {
this.setData({
inputWidth: `${(newVal.length * 14) + 45}px`
});
} }
}, },
useCancel: { background: {
type: Boolean type: String,
value: '#f2f2f2'
}, },
searchStyle: String, maxlength: {
cancelStyle: String, type: Number,
inputStyle: String, value: -1
}
}, },
data: {
inputWidth: 'auto' attached() {
this.setData({ currentValue: this.data.value });
}, },
methods: { methods: {
blur() { onChange(event) {
this.triggerEvent('blur'); this.triggerEvent('change', event.detail);
}, },
clearInput() {
this.setData({ onCancel() {
focus: true this.setData({ currentValue: '' });
});
this.triggerEvent('change', { value: '' });
},
cancelSearch() {
this.triggerEvent('cancel'); this.triggerEvent('cancel');
this.triggerEvent('change', '');
}, },
focus() {
onSearch() {
this.triggerEvent('search', this.data.currentValue);
},
onFocus() {
this.triggerEvent('focus'); this.triggerEvent('focus');
}, },
inputChange(e) {
this._inputvalue = e.detail.value; onBlur() {
this.triggerEvent('change', { value: e.detail.value }); this.triggerEvent('blur');
},
search(e) {
this.triggerEvent('search', { value: e.detail.value });
} }
} }
}); });

View File

@ -1,3 +1,7 @@
{ {
"component": true "component": true,
"usingComponents": {
"van-icon": "../icon/index",
"van-field": "../field/index"
}
} }

View File

@ -1,89 +1,41 @@
@import '../common/index.pcss';
.van-search { .van-search {
box-sizing: border-box;
display: flex; display: flex;
justify-content: space-between; padding: 7px 15px;
align-items: center; align-items: center;
background: transparent; box-sizing: border-box;
padding:5px 10px;
&__field {
flex: 1;
border-radius: 4px;
&__left-icon {
color: $gray-dark;
}
} }
.van-search.center-placeholder { &--show-action {
background: #ffffff; padding-right: 0;
} }
.van-search.center-placeholder .van-search__form { input {
margin-left: 50%; &::-webkit-search-decoration,
transform: translateX(-50%); &::-webkit-search-cancel-button,
border: none; &::-webkit-search-results-button,
} &::-webkit-search-results-decoration {
.van-search.van-cell::after {
display: none; display: none;
} }
.van-search__form {
display: flex;
flex: 1;
background:#ffffff;
border-radius: 4rpx;
height: 64rpx;
line-height: 56rpx;
justify-content: space-between;
align-items: center;
} }
.van-search picker { &__action {
display: flex; padding: 0 10px;
align-items: center; font-size: 14px;
height: 100%; line-height: 30px;
padding-right: 20rpx; color: $gray-darker;
}
.van-search__form .picker { &:active {
position: relative; background-color: $active-color;
width: 110rpx;
height: 100%;
color: #666;
font-size: 28rpx;
margin-left: 20rpx;
} }
.van-search__form .picker::after {
content: '';
width: 0;
height: 0;
position: absolute;
right: 0;
top: 50%;
margin-top: -6rpx;
border-top: 12rpx solid #333;
border-right: 8rpx solid transparent;
border-left: 8rpx solid transparent;
} }
.van-search__form input {
height: 100%;
flex: 1;
padding: 0 20rpx;
font-size: 28rpx;
color: #333;
}
.van-search__form icon {
margin-left: 20rpx;
line-height: 1;
}
.van-search__clear {
padding: 12rpx 20rpx;
}
.van-search__placeholder {
font-size: 28rpx;
color: #cacaca;
}
.van-search__cancel {
align-self: stretch;
display: inline-flex;
align-items: center;
padding-left: 30rpx;
font-size: 28rpx;
color: #3388FF;
} }

View File

@ -1,40 +1,28 @@
<view <view
class="van-search {{ searchClass }}" class="van-search custom-class {{ showAction || useActionSlot ? 'van-search--show-action' : '' }}"
style="{{ searchStyle }}" style="background: {{ background }}"
> >
<view <view class="van-search__field">
class="van-search__form {{ useCancel ? 'van-search__form--cancel' : '' }} input-class" <van-field
style="{{ inputStyle }}" clearable
> type="search"
<icon type="search" size="15" color="#a9a9a9" /> left-icon="search"
<input border="{{ false }}"
class="van-search__input"
placeholder="{{ placeholder }}"
placeholder-class="van-search__placeholder"
confirm-type="search" confirm-type="search"
bindfocus="focus" value="{{ currentValue }}"
bindblur="blur"
value="{{ keyword }}"
bindconfirm="search"
bindinput="inputChange"
focus="{{ focus }}"
disabled="{{ disabled }}" disabled="{{ disabled }}"
/> readonly="{{ readony }}"
<icon maxlength="{{ maxlength }}"
wx:if="{{keyword}}" placeholder="{{ placeholder }}"
class="van-search__clear" custom-style="padding: 3px 10px"
type="clear" bind:blur="onBlur"
size="14" bind:focus="onFocus"
color="#bbb" bind:change="onChange"
bindtap="clearInput" bind:confirm="onSearch"
/> />
</view> </view>
<view <view wx:if="{{ showAction || useActionSlot }}" class="van-search__action">
class="van-search__cancel cancel-class" <slot wx:if="{{ useActionSlot }}" name="action" />
wx:if="{{ useCancel }}" <view wx:else bind:tap="onCancel" class="cancel-class">取消</view>
bindtap="cancelSearch"
style="{{ cancelStyle }}"
>
{{cancelText || '取消'}}
</view> </view>
</view> </view>