-
@@ -32,21 +37,19 @@ export default {
props: {
placeholder: String,
- type: {
+ value: String,
+ showAction: {
+ type: Boolean,
+ default: false
+ },
+ background: {
type: String,
- default: 'normal'
- }
- },
-
- watch: {
- value(val) {
- this.$emit('change', val);
+ default: '#f2f2f2'
}
},
data() {
return {
- value: '',
focusStatus: false,
isFocus: false
};
@@ -71,29 +74,38 @@ export default {
this.isFocus = true;
},
+ handleInput(event) {
+ this.$emit('input', event.target.value);
+ },
+
/**
- * 点击close后清空vlaue后,再聚焦input框
+ * 点击close后清空value后,再聚焦input框
*/
handleClean() {
- this.value = '';
+ this.$emit('input', '');
this.focusStatus = true;
+
+ // 保证多次点击 clean 后,仍能触发 refocus
+ this.$nextTick(() => {
+ this.focusStatus = false;
+ });
},
/**
* 点击取消后,清空所有回复最初状态
*/
handleBack() {
- this.value = '';
- this.focusStatus = false;
- this.isFocus = false;
+ this.$emit('input', '');
this.$emit('cancel');
},
/**
* input输入回车后,发送回调
*/
- handleSearch() {
- this.$emit('search', this.value);
+ handleSearch(e) {
+ e.preventDefault();
+ this.$emit('search');
+ return false;
},
handleClickoutside() {
diff --git a/packages/vant-css/src/search.css b/packages/vant-css/src/search.css
index 08df57948..d4238ed38 100644
--- a/packages/vant-css/src/search.css
+++ b/packages/vant-css/src/search.css
@@ -1,26 +1,19 @@
@import './common/var.css';
.van-search {
- position: relative;
+ display: flex;
+ align-items: center;
box-sizing: border-box;
padding: 4px 15px;
- background-color: #F2F2F2;
- &--focus {
- padding-right: 50px;
- }
-
- &--showcase {
- padding: 10px;
- background-color: $background-color;
-
- .van-search__input-wrap {
- border-color: $gray-light;
- }
+ &--show-action {
+ padding-right: 0;
}
&__input-wrap {
position: relative;
+ flex: 1;
+ height: 16px;
padding: 8px 24px 8px 35px;
border: 1px solid $gray-light;
border-radius: 4px;
@@ -49,13 +42,14 @@
}
}
- &__cancel {
- position: absolute;
+ &__action {
line-height: 34px;
- padding: 4px 0;
- top: 0;
- right: 10px;
font-size: 14px;
+ letter-spacing: 1px;
+ }
+
+ &__action-text {
+ padding: 0 10px;
color: $green;
}
@@ -73,9 +67,11 @@
font-size: 14px;
line-height: 16px;
position: absolute;
- right: 5px;
+ right: 0;
top: 50%;
transform: translateY(-50%);
+ /* 增加 clear 点击区域 */
+ padding: 5px;
color: #888;
}
}
diff --git a/test/unit/specs/search.spec.js b/test/unit/specs/search.spec.js
index 4a63a0389..b066b6bc7 100644
--- a/test/unit/specs/search.spec.js
+++ b/test/unit/specs/search.spec.js
@@ -8,7 +8,7 @@ describe('Search', () => {
wrapper && wrapper.destroy();
});
- it('create a stepper', () => {
+ it('create a search', () => {
wrapper = mount(Search);
expect(wrapper.hasClass('van-search')).to.be.true;
@@ -25,54 +25,65 @@ describe('Search', () => {
expect(wrapper.data().isFocus).to.be.true;
});
- it('emit change event', (done) => {
- wrapper = mount(Search);
+ it('create a search with searchText', (done) => {
+ wrapper = mount(Search, {
+ propsData: {
+ value: 'search text'
+ }
+ });
- const eventStub = sinon.stub(wrapper.vm, '$emit');
- wrapper.setData({ value: 'test' });
- wrapper.update();
wrapper.vm.$nextTick(() => {
- expect(wrapper.data().value).to.be.equal('test');
- expect(eventStub.calledOnce).to.be.true;
- expect(eventStub.calledWith('change'));
+ const input = wrapper.find('.van-search__input')[0];
+ expect(input.element.value === 'search text').to.be.true;
done();
});
});
- it('handle clean click', () => {
+ it('emit input event', () => {
wrapper = mount(Search);
- wrapper.setData({ value: 'test' });
- expect(wrapper.data().value).to.be.equal('test');
+ const input = wrapper.find('.van-search__input')[0];
+ const eventStub = sinon.stub(wrapper.vm, '$emit');
+ input.trigger('input', { target: { value: 'search' }});
+
+ expect(eventStub.calledOnce).to.be.true;
+ expect(eventStub.calledWith('input')).to.be.true;
+ });
+
+ it('handle clean click and refocus', (done) => {
+ wrapper = mount(Search);
+ wrapper.setProps({ value: 'test' });
+ const eventStub = sinon.stub(wrapper.vm, '$emit');
const input = wrapper.find('.van-search__input')[0];
input.trigger('focus');
const cleanBtn = wrapper.find('.van-icon-clear')[0];
cleanBtn.trigger('click');
- expect(wrapper.data().value).to.equal('');
- expect(wrapper.data().focusStatus).to.be.true;
+
+ wrapper.vm.$nextTick(() => {
+ expect(eventStub.calledOnce).to.be.true;
+ expect(eventStub.calledWith('input')).to.be.true;
+ done();
+ });
});
it('handle cancel click', (done) => {
wrapper = mount(Search);
- wrapper.setData({ value: 'test' });
- expect(wrapper.data().value).to.be.equal('test');
+ wrapper.setProps({ value: 'test', showAction: true });
+ expect(wrapper.vm.value).to.be.equal('test');
const eventStub = sinon.stub(wrapper.vm, '$emit');
- const input = wrapper.find('.van-search__input')[0];
- input.trigger('focus');
-
- const cancelBtn = wrapper.find('.van-search__cancel')[0];
+ const cancelBtn = wrapper.find('.van-search__action-text')[0];
cancelBtn.trigger('click');
wrapper.vm.$nextTick(() => {
- expect(wrapper.data().value).to.be.equal('');
- expect(wrapper.data().focusStatus).to.be.false;
- expect(wrapper.data().isFocus).to.be.false;
- expect(eventStub.calledOnce).to.be.true;
+ expect(wrapper.vm.focusStatus).to.be.false;
+ expect(wrapper.vm.isFocus).to.be.false;
+ expect(eventStub.calledTwice).to.be.true;
+ expect(eventStub.calledWith('input'));
expect(eventStub.calledWith('change'));
done();
});
@@ -84,7 +95,7 @@ describe('Search', () => {
const eventStub = sinon.stub(wrapper.vm, '$emit');
const input = wrapper.find('.van-search__input')[0];
- input.trigger('keyup.enter');
+ input.trigger('keypress.enter');
wrapper.vm.$nextTick(() => {
expect(eventStub.calledOnce).to.be.true;
@@ -93,24 +104,17 @@ describe('Search', () => {
});
});
- it('create a showcase type search', () => {
- wrapper = mount(Search, {
- propsData: {
- type: 'showcase'
- }
- });
-
- expect(wrapper.hasClass('van-search')).to.be.true;
- expect(wrapper.hasClass('van-search--showcase')).to.be.true;
+ it('blur after click outside', () => {
+ wrapper = mount(Search);
const input = wrapper.find('.van-search__input')[0];
input.trigger('focus');
- expect(wrapper.data().isFocus).to.be.true;
+ expect(wrapper.vm.isFocus).to.be.true;
const body = document.body;
body.click();
- expect(wrapper.data().isFocus).to.be.false;
- expect(wrapper.data().focusStatus).to.be.false;
+ expect(wrapper.vm.isFocus).to.be.false;
+ expect(wrapper.vm.focusStatus).to.be.false;
});
});