Libary.vue 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
  1. <template>
  2. <el-scrollbar>
  3. <el-input
  4. v-model="search"
  5. placeholder="请输入组件名称"
  6. class="m-8px"
  7. style="width: calc(100% - 16px)"
  8. />
  9. <el-collapse v-model="activeCollapse">
  10. <el-collapse-item
  11. v-for="group in getGroups"
  12. :key="group.label"
  13. :title="group.label"
  14. :name="group.label"
  15. >
  16. <div class="px-2 pb-2 pt-1 grid grid-cols-[repeat(auto-fill,minmax(70px,1fr))] gap-row-2">
  17. <LibaryItem
  18. v-for="item in group.items"
  19. :key="item.key"
  20. :comp="item"
  21. @click="handleAdd(item)"
  22. />
  23. </div>
  24. </el-collapse-item>
  25. </el-collapse>
  26. <el-empty v-if="!getGroups.length" :image-size="80">
  27. <template #description>
  28. <div>没有找到组件</div>
  29. </template>
  30. </el-empty>
  31. </el-scrollbar>
  32. </template>
  33. <script setup lang="ts">
  34. import { computed, ref } from 'vue'
  35. import { ComponentArray } from '@/lvgl-widgets'
  36. import LibaryItem from './components/LibaryItem.vue'
  37. import { createWidget } from '@/model'
  38. import { getAddWidgetIndex } from '@/utils'
  39. import { useProjectStore } from '@/store/modules/project'
  40. import type { IComponentModelConfig } from '@/lvgl-widgets/type'
  41. const search = ref('')
  42. const activeCollapse = ref<string[]>([])
  43. const projectStore = useProjectStore()
  44. const groupMap = ref<{
  45. [key: string]: {
  46. label: string
  47. items: IComponentModelConfig[]
  48. }
  49. }>({})
  50. // 变量全部控件
  51. ComponentArray.filter((item) => !item.hideLibary).forEach((item) => {
  52. if (!groupMap.value[item.group]) {
  53. groupMap.value[item.group] = {
  54. label: item.group,
  55. items: []
  56. }
  57. }
  58. if (!item?.hideLibary) {
  59. groupMap.value[item.group].items.push(item)
  60. }
  61. return item.group
  62. })
  63. // 根据搜索条件获取分组信息
  64. const getGroups = computed(() => {
  65. const list = Object.values(groupMap.value).filter((item) =>
  66. item.items.some((item) => item.label.includes(search.value))
  67. )
  68. activeCollapse.value = list.map((item) => item.label)
  69. return list
  70. })
  71. // 处理点击添加控件
  72. function handleAdd(item: IComponentModelConfig) {
  73. const page = projectStore.activePage
  74. const index = getAddWidgetIndex(page!, item.key)
  75. const newWidget = createWidget(item, index)
  76. // 查找当前screen
  77. const screen = projectStore.project?.screens.find(
  78. (screen) => !!screen.pages.find((p) => page?.id === p.id)
  79. )
  80. // 随机位置
  81. const r = Math.floor(Math.random() * 100)
  82. if (screen) {
  83. newWidget.props.x = screen.width / 2 - newWidget.props.width / 2 + r
  84. newWidget.props.y = screen.height / 2 - newWidget.props.height / 2 + r
  85. }
  86. projectStore.activePage?.children?.unshift(newWidget)
  87. projectStore.setSelectWidgets([newWidget])
  88. }
  89. </script>
  90. <style scoped lang="less">
  91. ::v-deep(.el-collapse-item__content) {
  92. padding: 0;
  93. }
  94. </style>