index.vue 1.93 KB
<template>
  <TreeSelect
    :model-value="modelValue"
    :data="permissionData"
    :field-names="fieldName"
    :placeholder="placeholder"
    :allow-clear="allowClear"
    :allow-search="allowSearch"
    :tree-props="treeProp"
    :filter-tree-node="onFilter"
    :fallback-option="false"
    :path-mode="true"
    @update:model-value="onUpdate"
  />
</template>

<script lang="ts" setup>
  import { TreeNodeData, TreeSelect } from '@arco-design/web-vue';
  import { computed, toRefs } from 'vue';
  import { SystemPermission } from '@/types/system-permission';
  import { isUndefined } from '@/utils/is';
  import { useAppStore } from '@/store';
  import { storeToRefs } from 'pinia';
  import { arrayToTree } from '@/utils';
  import { AnyObject } from '@/types/global';

  type PropType = {
    modelValue?: number | string | number[];
    guard?: 'Admin' | 'Manage' | '';
    allowClear?: boolean;
    allowSearch?: boolean;
    placeholder?: string;
  };

  const props = withDefaults(defineProps<PropType>(), {
    allowClear: false,
    allowSearch: false,
    placeholder: '请选择',
    modelValue: '',
    guard: '',
  });

  const { guard } = toRefs(props);

  const emits = defineEmits<{ (e: 'update:modelValue', value: number | string): void }>();
  const fieldName = { key: 'name', title: 'label', children: 'children', icon: 'icm' };
  const treeProp = { virtualListProps: { height: 300 } };
  const appStore = useAppStore();
  const { permissions } = storeToRefs(appStore);

  const onUpdate = (val: number | string | undefined) => emits('update:modelValue', isUndefined(val) ? '' : val);
  const onFilter = (searchKey: string, nodeData: SystemPermission) => nodeData.label.indexOf(searchKey) > -1;

  const permissionData = computed(() => {
    const list = permissions?.value?.filter((item) => item.type === 'Menu' && item.guard === guard.value) as AnyObject[];
    return arrayToTree(list) as TreeNodeData[];
  });
</script>

<style scoped></style>