mirror of
https://gitee.com/vant-contrib/vant.git
synced 2025-05-22 06:31:45 +08:00
feat: migrate Search component
This commit is contained in:
parent
322db54c77
commit
735acabcec
@ -54,4 +54,5 @@ module.exports = [
|
|||||||
'datetime-picker',
|
'datetime-picker',
|
||||||
'number-keyboard',
|
'number-keyboard',
|
||||||
'password-input',
|
'password-input',
|
||||||
|
'search',
|
||||||
];
|
];
|
||||||
|
115
src/search/index.js
Normal file
115
src/search/index.js
Normal file
@ -0,0 +1,115 @@
|
|||||||
|
// Utils
|
||||||
|
import { createNamespace } from '../utils';
|
||||||
|
import { preventDefault } from '../utils/dom/event';
|
||||||
|
|
||||||
|
// Components
|
||||||
|
import Field from '../field';
|
||||||
|
|
||||||
|
const [createComponent, bem, t] = createNamespace('search');
|
||||||
|
|
||||||
|
export default createComponent({
|
||||||
|
inheritAttrs: false,
|
||||||
|
|
||||||
|
props: {
|
||||||
|
label: String,
|
||||||
|
rightIcon: String,
|
||||||
|
modelValue: String,
|
||||||
|
actionText: String,
|
||||||
|
background: String,
|
||||||
|
showAction: Boolean,
|
||||||
|
clearTrigger: String,
|
||||||
|
shape: {
|
||||||
|
type: String,
|
||||||
|
default: 'square',
|
||||||
|
},
|
||||||
|
clearable: {
|
||||||
|
type: Boolean,
|
||||||
|
default: true,
|
||||||
|
},
|
||||||
|
leftIcon: {
|
||||||
|
type: String,
|
||||||
|
default: 'search',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
emits: ['search', 'cancel', 'keypress'],
|
||||||
|
|
||||||
|
setup(props, { emit, slots }) {
|
||||||
|
return function () {
|
||||||
|
function Label() {
|
||||||
|
if (slots.label || props.label) {
|
||||||
|
return (
|
||||||
|
<div class={bem('label')}>
|
||||||
|
{slots.label ? slots.label() : props.label}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function Action() {
|
||||||
|
if (!props.showAction) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
function onCancel() {
|
||||||
|
if (slots.action) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
emit('update:modelValue', '');
|
||||||
|
emit('cancel');
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
class={bem('action')}
|
||||||
|
role="button"
|
||||||
|
tabindex="0"
|
||||||
|
onClick={onCancel}
|
||||||
|
>
|
||||||
|
{slots.action ? slots.action() : props.actionText || t('cancel')}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const fieldData = {
|
||||||
|
...this.$attrs,
|
||||||
|
onKeypress(event) {
|
||||||
|
// press enter
|
||||||
|
if (event.keyCode === 13) {
|
||||||
|
preventDefault(event);
|
||||||
|
emit('search', props.modelValue);
|
||||||
|
}
|
||||||
|
emit('keypress', event);
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
class={bem({ 'show-action': props.showAction })}
|
||||||
|
style={{ background: props.background }}
|
||||||
|
>
|
||||||
|
{slots.left?.()}
|
||||||
|
<div class={bem('content', props.shape)}>
|
||||||
|
{Label()}
|
||||||
|
<Field
|
||||||
|
type="search"
|
||||||
|
border={false}
|
||||||
|
leftIcon={props.leftIcon}
|
||||||
|
rightIcon={props.rightIcon}
|
||||||
|
clearable={props.clearable}
|
||||||
|
modelValue={props.modelValue}
|
||||||
|
clearTrigger={props.clearTrigger}
|
||||||
|
scopedSlots={{
|
||||||
|
'left-icon': slots['left-icon'],
|
||||||
|
'right-icon': slots['right-icon'],
|
||||||
|
}}
|
||||||
|
{...fieldData}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
{Action()}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
},
|
||||||
|
});
|
@ -1,149 +0,0 @@
|
|||||||
// Utils
|
|
||||||
import { createNamespace } from '../utils';
|
|
||||||
import { inherit, emit } from '../utils/functional';
|
|
||||||
import { preventDefault } from '../utils/dom/event';
|
|
||||||
|
|
||||||
// Components
|
|
||||||
import Field from '../field';
|
|
||||||
|
|
||||||
// Types
|
|
||||||
import { CreateElement, RenderContext } from 'vue/types';
|
|
||||||
import { DefaultSlots, ScopedSlot } from '../utils/types';
|
|
||||||
|
|
||||||
const [createComponent, bem, t] = createNamespace('search');
|
|
||||||
|
|
||||||
export type SearchProps = {
|
|
||||||
shape: 'sqaure' | 'round';
|
|
||||||
value?: string;
|
|
||||||
label?: string;
|
|
||||||
leftIcon: string;
|
|
||||||
rightIcon?: string;
|
|
||||||
clearable: boolean;
|
|
||||||
background: string;
|
|
||||||
actionText?: string;
|
|
||||||
showAction?: boolean;
|
|
||||||
clearTrigger?: string;
|
|
||||||
};
|
|
||||||
|
|
||||||
export type SearchSlots = DefaultSlots & {
|
|
||||||
left?: ScopedSlot;
|
|
||||||
label?: ScopedSlot;
|
|
||||||
action?: ScopedSlot;
|
|
||||||
'left-icon'?: ScopedSlot;
|
|
||||||
'right-icon'?: ScopedSlot;
|
|
||||||
};
|
|
||||||
|
|
||||||
export type SearchEvents = {
|
|
||||||
onCancel?(): void;
|
|
||||||
onInput?(value: string): void;
|
|
||||||
onSearch?(value: string): void;
|
|
||||||
onKeypress?(event: KeyboardEvent): void;
|
|
||||||
};
|
|
||||||
|
|
||||||
function Search(
|
|
||||||
h: CreateElement,
|
|
||||||
props: SearchProps,
|
|
||||||
slots: SearchSlots,
|
|
||||||
ctx: RenderContext<SearchProps>
|
|
||||||
) {
|
|
||||||
function Label() {
|
|
||||||
if (slots.label || props.label) {
|
|
||||||
return (
|
|
||||||
<div class={bem('label')}>
|
|
||||||
{slots.label ? slots.label() : props.label}
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function Action() {
|
|
||||||
if (!props.showAction) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
function onCancel() {
|
|
||||||
if (slots.action) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
emit(ctx, 'input', '');
|
|
||||||
emit(ctx, 'cancel');
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div class={bem('action')} role="button" tabindex="0" onClick={onCancel}>
|
|
||||||
{slots.action ? slots.action() : props.actionText || t('cancel')}
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
const fieldData = {
|
|
||||||
attrs: ctx.data.attrs,
|
|
||||||
on: {
|
|
||||||
...ctx.listeners,
|
|
||||||
keypress(event: KeyboardEvent) {
|
|
||||||
// press enter
|
|
||||||
if (event.keyCode === 13) {
|
|
||||||
preventDefault(event);
|
|
||||||
emit(ctx, 'search', props.value);
|
|
||||||
}
|
|
||||||
emit(ctx, 'keypress', event);
|
|
||||||
},
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
const inheritData = inherit(ctx);
|
|
||||||
inheritData.attrs = undefined;
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div
|
|
||||||
class={bem({ 'show-action': props.showAction })}
|
|
||||||
style={{ background: props.background }}
|
|
||||||
{...inheritData}
|
|
||||||
>
|
|
||||||
{slots.left?.()}
|
|
||||||
<div class={bem('content', props.shape)}>
|
|
||||||
{Label()}
|
|
||||||
<Field
|
|
||||||
type="search"
|
|
||||||
border={false}
|
|
||||||
value={props.value}
|
|
||||||
leftIcon={props.leftIcon}
|
|
||||||
rightIcon={props.rightIcon}
|
|
||||||
clearable={props.clearable}
|
|
||||||
clearTrigger={props.clearTrigger}
|
|
||||||
scopedSlots={{
|
|
||||||
'left-icon': slots['left-icon'],
|
|
||||||
'right-icon': slots['right-icon'],
|
|
||||||
}}
|
|
||||||
{...fieldData}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
{Action()}
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
Search.props = {
|
|
||||||
value: String,
|
|
||||||
label: String,
|
|
||||||
rightIcon: String,
|
|
||||||
actionText: String,
|
|
||||||
background: String,
|
|
||||||
showAction: Boolean,
|
|
||||||
clearTrigger: String,
|
|
||||||
shape: {
|
|
||||||
type: String,
|
|
||||||
default: 'square',
|
|
||||||
},
|
|
||||||
clearable: {
|
|
||||||
type: Boolean,
|
|
||||||
default: true,
|
|
||||||
},
|
|
||||||
leftIcon: {
|
|
||||||
type: String,
|
|
||||||
default: 'search',
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
export default createComponent<SearchProps, SearchEvents, SearchSlots>(Search);
|
|
@ -155,10 +155,10 @@ module.exports = {
|
|||||||
path: 'rate',
|
path: 'rate',
|
||||||
title: 'Rate 评分',
|
title: 'Rate 评分',
|
||||||
},
|
},
|
||||||
// {
|
{
|
||||||
// path: 'search',
|
path: 'search',
|
||||||
// title: 'Search 搜索',
|
title: 'Search 搜索',
|
||||||
// },
|
},
|
||||||
{
|
{
|
||||||
path: 'slider',
|
path: 'slider',
|
||||||
title: 'Slider 滑块',
|
title: 'Slider 滑块',
|
||||||
@ -489,10 +489,10 @@ module.exports = {
|
|||||||
path: 'rate',
|
path: 'rate',
|
||||||
title: 'Rate',
|
title: 'Rate',
|
||||||
},
|
},
|
||||||
// {
|
{
|
||||||
// path: 'search',
|
path: 'search',
|
||||||
// title: 'Search',
|
title: 'Search',
|
||||||
// },
|
},
|
||||||
{
|
{
|
||||||
path: 'slider',
|
path: 'slider',
|
||||||
title: 'Slider',
|
title: 'Slider',
|
||||||
|
Loading…
x
Reference in New Issue
Block a user