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
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