Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat ✨ drop menu 支持 filterable 本地搜索 #552

Open
wants to merge 7 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions docs/component/drop-menu.md
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,21 @@ const handleBeforeToggle: DropMenuItemBeforeToggle = ({ status, resolve }) => {
</wd-drop-menu>
```


## 可搜索

设置 `filterable` 属性支持本地搜索,设置 `filter-placeholder` 属性设置搜索框的提示占位文本。

```html
<wd-drop-menu>
<wd-drop-menu-item v-model="value1" :options="option1" @change="handleChange1" />
<wd-drop-menu-item v-model="value2" :options="option2" @change="handleChange2" filterable />
<wd-drop-menu-item v-model="value2" :options="option2" @change="handleChange2" filterable filter-placeholder="检索"/>
</wd-drop-menu>

```


## DropMenu Attributes

| 参数 | 说明 | 类型 | 可选值 | 默认值 | 最低版本 |
Expand Down
21 changes: 21 additions & 0 deletions src/pages/dropMenu/Index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,13 @@
<wd-drop-menu-item v-model="value9" :options="option2" @change="handleChange9" />
</wd-drop-menu>
</demo-block>
<demo-block title="可搜索" transparent>
<wd-drop-menu>
<wd-drop-menu-item v-model="value11" :options="option1" @change="handleChange11" />
<wd-drop-menu-item v-model="value12" :options="option2" @change="handleChange12" filterable />
<wd-drop-menu-item v-model="value13" :options="option2" @change="handleChange13" filterable filter-placeholder=“检索” />
</wd-drop-menu>
</demo-block>
</view>
</page-wraper>
</template>
Expand Down Expand Up @@ -83,6 +90,10 @@ const value7 = ref<number>(0)
const value8 = ref<number>(0)
const value9 = ref<number>(0)
const value10 = ref<number>(0)

const value11 = ref<number>(0)
const value12 = ref<number>(0)
const value13 = ref<number>(0)

const option1 = ref<Record<string, any>[]>([
{ label: '全部商品', value: 0 },
Expand Down Expand Up @@ -127,6 +138,16 @@ function handleChange9({ value }: any) {
console.log(value)
}

function handleChange11({ value }: any) {
console.log(value)
}
function handleChange12({ value }: any) {
console.log(value)
}
function handleChange13({ value }: any) {
console.log(value)
}

function confirm() {
dropMenu.value.close()
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,10 @@ export const dorpMenuItemProps = {
/**
* 列表数据,对应数据结构 [{text: '标题', value: '0', tip: '提示文字'}]
*/
/** 可搜索(目前只支持本地搜索) */
filterable: makeBooleanProp(false),
/** 搜索框占位符 */
filterPlaceholder: String,
options: makeArrayProp<Record<string, any>>(),
/**
* 禁用菜单
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,16 @@
@after-leave="afterLeave"
>
<view v-if="options.length">
<wd-search
v-if="filterable"
v-model="filterVal"
:placeholder="filterPlaceholder || translate('filterPlaceholder')"
hide-cancel
placeholder-left
@change="handleFilterChange"
/>
<view
v-for="(item, index) in options"
v-for="(item, index) in filterOptions"
:key="index"
@click="choose(index)"
:class="`wd-drop-item__option ${(item[valueKey] !== '' ? item[valueKey] : item) === modelValue ? 'is-active' : ''}`"
Expand Down Expand Up @@ -53,13 +61,17 @@ export default {
import wdPopup from '../wd-popup/wd-popup.vue'
import wdIcon from '../wd-icon/wd-icon.vue'
import { computed, getCurrentInstance, inject, onBeforeMount, onBeforeUnmount, ref, watch } from 'vue'

import { pushToQueue, removeFromQueue } from '../common/clickoutside'
import { type Queue, queueKey } from '../composables/useQueue'
import type { PopupType } from '../wd-popup/types'
import { useParent } from '../composables/useParent'
import { DROP_MENU_KEY } from '../wd-drop-menu/types'
import { isDef, isFunction } from '../common/util'
import { dorpMenuItemProps, type DropMenuItemExpose } from './types'
import { useTranslate } from '../composables/useTranslate'

const { translate } = useTranslate('drop-menu')

const props = defineProps(dorpMenuItemProps)
const emit = defineEmits(['change', 'update:modelValue', 'open', 'opened', 'closed', 'close'])
Expand All @@ -72,6 +84,8 @@ const zIndex = ref<number>(12)
const modal = ref<boolean>(true)
const closeOnClickModal = ref<boolean>(true)
const duration = ref<number>(0)
const filterVal = ref<string>('')
const filterOptions = ref<Array<Record<string, any>>>([])

const { parent: dropMenu } = useParent(DROP_MENU_KEY)

Expand Down Expand Up @@ -103,6 +117,22 @@ watch(
}
)

watch(
() => props.options,
(newValue) => {
console.log("🚀 ~ newValue:", newValue)
if (props.filterable && filterVal.value) {
formatFilterOptions(newValue, filterVal.value)
} else {
filterOptions.value = newValue
}
},
{
deep: true,
immediate: true
}
)

onBeforeMount(() => {
if (queue && queue.pushToQueue) {
queue.pushToQueue(proxy)
Expand All @@ -119,20 +149,51 @@ onBeforeUnmount(() => {
}
})

function handleFilterChange({ value }: { value: string }) {
if (value === '') {
filterOptions.value = []
filterVal.value = value
nextTick(() => {
filterOptions.value = props.options
})
} else {
filterVal.value = value
formatFilterOptions(props.options, value)
}
}

function formatFilterOptions(options: Record<string, any>[], filterVal: string) {
const filterOptionsTemp = options.filter((item) => {
return item[props.labelKey].indexOf(filterVal) > -1
})
filterOptions.value = []
nextTick(() => {
filterOptions.value = filterOptionsTemp
})
}


function getShowPop() {
return showPop.value
}
// 模拟单选操作 默认根据 value 选中操作
function choose(index: number) {
if (props.disabled) return
const { valueKey } = props
const item = props.options[index]
const item = filterOptions.value[index]
emit('update:modelValue', item[valueKey] !== '' && item[valueKey] !== undefined ? item[valueKey] : item)
emit('change', {
value: item[valueKey] !== '' && item[valueKey] !== undefined ? item[valueKey] : item,
selectedItem: item
})
close()

//关闭清空搜索 避免清空画面闪过
if(filterVal.value !== '') {
setTimeout(() => {
handleFilterChange({ value: ''})
}, 300);
}
}
// 外部关闭弹出框
function close() {
Expand Down