first commit
This commit is contained in:
285
uni_modules/tdesign-uniapp/components/search/search.vue
Normal file
285
uni_modules/tdesign-uniapp/components/search/search.vue
Normal file
@@ -0,0 +1,285 @@
|
||||
<template>
|
||||
<view>
|
||||
<view
|
||||
:style="tools._style([customStyle])"
|
||||
:class="classPrefix + ' ' + tClass"
|
||||
>
|
||||
<view
|
||||
:class="
|
||||
classPrefix +'__input-box ' +
|
||||
prefix + '-' +(focus ? 'is-focused' : 'not-focused') +
|
||||
' ' + classPrefix + '__input-box--' + (center ? 'center' : '') +
|
||||
' ' + classPrefix + '__input-box--' + shape +
|
||||
' ' + tClassInputContainer
|
||||
"
|
||||
>
|
||||
<t-icon
|
||||
v-if="leftIcon"
|
||||
:name="leftIcon"
|
||||
:t-class="prefix + '-icon ' + tClassLeft"
|
||||
:aria-hidden="true"
|
||||
/>
|
||||
<slot
|
||||
v-else
|
||||
name="left-icon"
|
||||
/>
|
||||
<input
|
||||
:type="type"
|
||||
name="input"
|
||||
:maxlength="maxlength"
|
||||
:disabled="disabled || readonly"
|
||||
:class="prefix + '-input__keyword ' + tClassInput + ' ' + (disabled ? prefix + '-input--disabled' : '')"
|
||||
:focus="focus"
|
||||
:value="dataValue"
|
||||
:confirm-type="confirmType"
|
||||
:confirm-hold="confirmHold"
|
||||
:cursor="cursor"
|
||||
:adjust-position="adjustPosition"
|
||||
:always-embed="alwaysEmbed"
|
||||
:selection-start="selectionStart"
|
||||
:selection-end="selectionEnd"
|
||||
:hold-keyboard="holdKeyboard"
|
||||
:cursor-spacing="cursorSpacing"
|
||||
:cursor-color="cursorColor"
|
||||
:placeholder="placeholder"
|
||||
:placeholder-style="placeholderStyle"
|
||||
:placeholder-class="placeholderClass + ' ' + classPrefix + '__placeholder ' + classPrefix + '__placeholder--' + (center ? 'center' : 'normal')"
|
||||
@input="onInput"
|
||||
@focus="onFocus"
|
||||
@blur="onBlur"
|
||||
@confirm="onConfirm"
|
||||
>
|
||||
<view
|
||||
v-if="dataValue !== '' && clearable && showClearIcon"
|
||||
:class="classPrefix + '__clear hotspot-expanded ' + tClassClear"
|
||||
aria-role="button"
|
||||
aria-label="清除"
|
||||
@touchstart.stop.prevent="handleClear"
|
||||
>
|
||||
<t-icon
|
||||
name="close-circle-filled"
|
||||
size="inherit"
|
||||
color="inherit"
|
||||
/>
|
||||
</view>
|
||||
</view>
|
||||
<view
|
||||
v-if="action"
|
||||
:class="classPrefix + '__search-action ' + tClassAction"
|
||||
aria-role="button"
|
||||
@click.stop.prevent="onActionClick"
|
||||
>
|
||||
{{ action }}
|
||||
</view>
|
||||
<slot
|
||||
v-else
|
||||
name="action"
|
||||
/>
|
||||
</view>
|
||||
<view
|
||||
v-if="isShowResultList && !isSelected"
|
||||
:class="classPrefix + '__result-list'"
|
||||
aria-role="listbox"
|
||||
>
|
||||
<t-cell
|
||||
v-for="(item, index) in resultList"
|
||||
:key="index"
|
||||
:data-index="index"
|
||||
:t-class="classPrefix + '__result-item'"
|
||||
hover
|
||||
aria-role="option"
|
||||
@click="onSelectResultItem($event, { index })"
|
||||
>
|
||||
<template
|
||||
#title
|
||||
>
|
||||
<rich-text
|
||||
:nodes="highLight(item, dataValue)"
|
||||
/>
|
||||
</template>
|
||||
</t-cell>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
<script>
|
||||
import TIcon from '../icon/icon';
|
||||
import TCell from '../cell/cell';
|
||||
import { uniComponent } from '../common/src/index';
|
||||
import { prefix } from '../common/config';
|
||||
import props from './props';
|
||||
import { getCharacterLength, nextTick } from '../common/utils';
|
||||
import tools from '../common/utils.wxs';
|
||||
import { highLight } from './computed.js';
|
||||
// import { getInnerMaxLen } from '../input/utils';
|
||||
|
||||
const name = `${prefix}-search`;
|
||||
|
||||
|
||||
export default uniComponent({
|
||||
name,
|
||||
options: {
|
||||
styleIsolation: 'shared',
|
||||
},
|
||||
externalClasses: [
|
||||
`${prefix}-class`,
|
||||
`${prefix}-class-input-container`,
|
||||
`${prefix}-class-input`,
|
||||
`${prefix}-class-action`,
|
||||
`${prefix}-class-left`,
|
||||
`${prefix}-class-clear`,
|
||||
],
|
||||
components: {
|
||||
TIcon,
|
||||
TCell,
|
||||
},
|
||||
props: {
|
||||
...props,
|
||||
},
|
||||
emits: [
|
||||
'selectresult',
|
||||
],
|
||||
data() {
|
||||
return {
|
||||
classPrefix: name,
|
||||
prefix,
|
||||
isShowResultList: false,
|
||||
isSelected: false,
|
||||
showClearIcon: false,
|
||||
tools,
|
||||
|
||||
dataValue: this.value,
|
||||
// innerMaxLen: -1,
|
||||
// rawValue: '',
|
||||
};
|
||||
},
|
||||
watch: {
|
||||
resultList: {
|
||||
handler(val) {
|
||||
const { isSelected } = this;
|
||||
if (val.length) {
|
||||
if (isSelected) {
|
||||
// 已选择
|
||||
this.isShowResultList = false;
|
||||
this.isSelected = false;
|
||||
} else {
|
||||
this.isShowResultList = true;
|
||||
}
|
||||
} else {
|
||||
this.isShowResultList = false;
|
||||
}
|
||||
},
|
||||
immediate: true,
|
||||
},
|
||||
|
||||
dataValue: {
|
||||
handler() {
|
||||
// this.updateInnerMaxLen();
|
||||
this.updateClearIconVisible();
|
||||
},
|
||||
},
|
||||
clearTrigger: 'updateClearIconVisible',
|
||||
clearable: 'updateClearIconVisible',
|
||||
disabled: 'updateClearIconVisible',
|
||||
readonly: 'updateClearIconVisible',
|
||||
|
||||
// maxcharacter: 'updateInnerMaxLen',
|
||||
// maxlength: 'updateInnerMaxLen',
|
||||
},
|
||||
mounted() {
|
||||
this.updateClearIconVisible();
|
||||
},
|
||||
methods: {
|
||||
updateClearIconVisible(value = false) {
|
||||
const { clearTrigger, disabled, readonly, dataValue } = this;
|
||||
if (disabled || readonly || !dataValue) {
|
||||
this.showClearIcon = false;
|
||||
return;
|
||||
}
|
||||
|
||||
this.showClearIcon = value || String(clearTrigger) === 'always';
|
||||
},
|
||||
|
||||
onInput(e) {
|
||||
let { value } = e.detail;
|
||||
// this.rawValue = value;
|
||||
this.dataValue = value;
|
||||
|
||||
const { maxcharacter } = this;
|
||||
if (maxcharacter && typeof maxcharacter === 'number' && maxcharacter > 0) {
|
||||
const { characters } = getCharacterLength('maxcharacter', value, maxcharacter);
|
||||
|
||||
value = characters;
|
||||
}
|
||||
|
||||
|
||||
nextTick().then(() => {
|
||||
this.dataValue = value;
|
||||
this.$emit('change', { value });
|
||||
});
|
||||
// this.updateInnerMaxLen();
|
||||
},
|
||||
|
||||
onFocus(e) {
|
||||
const { value } = e.detail;
|
||||
this.updateClearIconVisible(true);
|
||||
this.$emit('focus', { value });
|
||||
},
|
||||
|
||||
onBlur(e) {
|
||||
const { value } = e.detail;
|
||||
this.updateClearIconVisible();
|
||||
this.$emit('blur', { value });
|
||||
},
|
||||
|
||||
handleClear() {
|
||||
this.dataValue = '';
|
||||
this.$emit('clear', { value: '' });
|
||||
this.$emit('change', { value: '' });
|
||||
},
|
||||
|
||||
onConfirm(e) {
|
||||
const { value } = e.detail;
|
||||
this.$emit('submit', { value });
|
||||
},
|
||||
|
||||
onActionClick() {
|
||||
this.$emit('action-click');
|
||||
},
|
||||
|
||||
onSelectResultItem(tools, { index }) {
|
||||
const item = this.resultList[index];
|
||||
this.dataValue = item;
|
||||
this.isSelected = true;
|
||||
|
||||
this.$emit('change', { value: item });
|
||||
this.$emit('selectresult', { index, item });
|
||||
},
|
||||
highLight,
|
||||
// updateInnerMaxLen() {
|
||||
// // this.innerMaxLen = this.getInnerMaxLen();
|
||||
// },
|
||||
// getInnerMaxLen() {
|
||||
// const {
|
||||
// maxcharacter,
|
||||
// maxlength,
|
||||
// dataValue,
|
||||
// rawValue,
|
||||
// count,
|
||||
// } = this;
|
||||
// return getInnerMaxLen({
|
||||
// allowInputOverMax: false,
|
||||
// maxcharacter,
|
||||
// maxlength,
|
||||
// dataValue,
|
||||
// rawValue,
|
||||
// count,
|
||||
// });
|
||||
// },
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
</script>
|
||||
<style scoped>
|
||||
@import './search.css';
|
||||
</style>
|
||||
Reference in New Issue
Block a user