mirror of
https://github.com/nagisa77/OpenIsle.git
synced 2026-02-27 08:30:47 +08:00
feat: add mobile dropdown page and search
This commit is contained in:
@@ -58,7 +58,10 @@
|
||||
|
||||
<script>
|
||||
import { ref, computed, watch, onMounted, onBeforeUnmount } from 'vue'
|
||||
import { useRouter } from 'vue-router'
|
||||
import { hatch } from 'ldrs'
|
||||
import { isMobile } from '../utils/screen'
|
||||
import { registerDropdownStore, removeDropdownStore } from '../utils/mobileDropdown'
|
||||
hatch.register()
|
||||
|
||||
export default {
|
||||
@@ -76,7 +79,10 @@ export default {
|
||||
},
|
||||
emits: ['update:modelValue'],
|
||||
setup(props, { emit }) {
|
||||
const router = useRouter()
|
||||
const storeId = Math.random().toString(36).substring(2)
|
||||
const open = ref(false)
|
||||
const model = ref(props.modelValue)
|
||||
const search = ref('')
|
||||
const setSearch = (val) => {
|
||||
search.value = val
|
||||
@@ -87,7 +93,18 @@ export default {
|
||||
const wrapper = ref(null)
|
||||
|
||||
const toggle = () => {
|
||||
open.value = !open.value
|
||||
if (isMobile.value) {
|
||||
registerDropdownStore(storeId, {
|
||||
value: model,
|
||||
multiple: props.multiple,
|
||||
fetchOptions: props.fetchOptions,
|
||||
remote: props.remote,
|
||||
showSearch: props.showSearch
|
||||
})
|
||||
router.push(`/mobile-dropdown/${storeId}`)
|
||||
} else {
|
||||
open.value = !open.value
|
||||
}
|
||||
}
|
||||
|
||||
const close = () => {
|
||||
@@ -96,16 +113,16 @@ export default {
|
||||
|
||||
const select = id => {
|
||||
if (props.multiple) {
|
||||
const arr = Array.isArray(props.modelValue) ? [...props.modelValue] : []
|
||||
const arr = Array.isArray(model.value) ? [...model.value] : []
|
||||
const idx = arr.indexOf(id)
|
||||
if (idx > -1) {
|
||||
arr.splice(idx, 1)
|
||||
} else {
|
||||
arr.push(id)
|
||||
}
|
||||
emit('update:modelValue', arr)
|
||||
model.value = arr
|
||||
} else {
|
||||
emit('update:modelValue', id)
|
||||
model.value = id
|
||||
close()
|
||||
}
|
||||
search.value = ''
|
||||
@@ -145,6 +162,18 @@ export default {
|
||||
}
|
||||
}
|
||||
)
|
||||
watch(
|
||||
() => props.modelValue,
|
||||
val => {
|
||||
model.value = val
|
||||
}
|
||||
)
|
||||
watch(
|
||||
() => model.value,
|
||||
val => {
|
||||
emit('update:modelValue', val)
|
||||
}
|
||||
)
|
||||
|
||||
watch(open, async val => {
|
||||
if (val) {
|
||||
@@ -163,21 +192,26 @@ export default {
|
||||
})
|
||||
|
||||
onMounted(() => {
|
||||
document.addEventListener('click', clickOutside)
|
||||
if (!isMobile.value) {
|
||||
document.addEventListener('click', clickOutside)
|
||||
}
|
||||
if (!props.remote) {
|
||||
loadOptions()
|
||||
}
|
||||
})
|
||||
|
||||
onBeforeUnmount(() => {
|
||||
document.removeEventListener('click', clickOutside)
|
||||
if (!isMobile.value) {
|
||||
document.removeEventListener('click', clickOutside)
|
||||
}
|
||||
removeDropdownStore(storeId)
|
||||
})
|
||||
|
||||
const selectedLabels = computed(() => {
|
||||
if (props.multiple) {
|
||||
return options.value.filter(o => (props.modelValue || []).includes(o.id))
|
||||
return options.value.filter(o => (model.value || []).includes(o.id))
|
||||
}
|
||||
const match = options.value.find(o => o.id === props.modelValue)
|
||||
const match = options.value.find(o => o.id === model.value)
|
||||
return match ? [match] : []
|
||||
})
|
||||
|
||||
|
||||
Reference in New Issue
Block a user