index.vue 1.62 KB
<template>
  <!--    :virtual-list-props="{ height: 240 }"-->

  <Select
    v-bind="$attrs"
    v-model="formValue"
    :fallback-option="false"
    :field-names="{ value: 'id', label: 'nick_name' }"
    :options="options"
    :placeholder="placeholder"
    :virtual-list-props="{ height: '240px' }"
    @exceed-limit="onExceedLimitError"
  >
    <template #option="{ data }">
      <Avatar v-if="hasAvatar" :size="28" :image-url="data.avatar" style="margin-right: 8px" />
      <span>{{ `${data.nick_name}(${data.real_name})` }}</span>
    </template>
  </Select>
</template>

<script lang="ts" setup>
  import { Avatar, Message, Select } from '@arco-design/web-vue';

  import { useSelectionStore } from '@/store';
  import { storeToRefs } from 'pinia';
  import { useVModels } from '@vueuse/core';
  import { computed } from 'vue';
  import { filter } from 'lodash';

  type PropType = {
    modelValue?: number | string | number[];
    placeholder?: string;
    limitErrorMsg?: string;
    hasAvatar?: boolean;
    filtrate?: (value: any) => boolean;
  };
  const { getUserOptions } = storeToRefs(useSelectionStore());

  const props = withDefaults(defineProps<PropType>(), {
    placeholder: '请选择',
    limitErrorMsg: '超出最大选中数',
    hasAvatar: true,
    filtrate: () => true,
  });
  const emits = defineEmits(['update:modelValue', 'update:loading']);

  const options = computed(() => filter(getUserOptions.value, props.filtrate));
  const { modelValue: formValue } = useVModels(props, emits);

  const onExceedLimitError = () => Message.warning({ content: props.limitErrorMsg, duration: 1500 });
</script>

<style scoped></style>