useSelectListPopup.ts 1.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677
  1. import { reactive, readonly, ref } from 'vue'
  2. export interface SelectListOption {
  3. /** 唯一值,用于回调与选中对比 */
  4. value: string | number
  5. /** 展示文案 */
  6. label: string
  7. /** 可选 icon */
  8. icon?: string
  9. }
  10. export interface SelectListPopupOptions {
  11. /** 弹窗标题,可选,例如“Language” */
  12. title?: string
  13. /** 需要展示的选项列表 */
  14. options: SelectListOption[]
  15. /** 默认选中值 */
  16. defaultValue?: SelectListOption['value']
  17. /**
  18. * 选中回调
  19. * - 点击某一项后立即触发
  20. * - 同时会自动关闭弹窗
  21. */
  22. onSelect?: (value: SelectListOption['value'], option: SelectListOption) => void
  23. }
  24. export interface SelectListPopupState {
  25. visible: boolean
  26. title: string
  27. options: SelectListOption[]
  28. selectedValue: SelectListOption['value'] | null
  29. }
  30. const state = reactive<SelectListPopupState>({
  31. visible: false,
  32. title: '',
  33. options: [],
  34. selectedValue: null,
  35. })
  36. const selectHandler = ref<
  37. ((value: SelectListOption['value'], option: SelectListOption) => void) | null
  38. >(null)
  39. const open = (options: SelectListPopupOptions) => {
  40. state.title = options.title ?? ''
  41. state.options = options.options ?? []
  42. state.selectedValue
  43. = options.defaultValue ?? (options.options?.[0]?.value ?? null)
  44. selectHandler.value = options.onSelect ?? null
  45. state.visible = true
  46. }
  47. const close = () => {
  48. state.visible = false
  49. }
  50. const select = (option: SelectListOption) => {
  51. state.selectedValue = option.value
  52. const handler = selectHandler.value
  53. if (handler) {
  54. handler(option.value, option)
  55. }
  56. state.visible = false
  57. }
  58. export const useSelectListPopup = () => {
  59. return {
  60. state: readonly(state),
  61. open,
  62. close,
  63. select,
  64. }
  65. }