Skip to content

Commit

Permalink
feat: enhance VXSelect component with slot support for custom item re…
Browse files Browse the repository at this point in the history
…ndering
  • Loading branch information
danni-cool committed Feb 24, 2025
1 parent c9e7236 commit 1da2995
Show file tree
Hide file tree
Showing 2 changed files with 131 additions and 15 deletions.
130 changes: 118 additions & 12 deletions ui/vuetifyx/vuetifyxjs/docs/Components/VXSelect/index.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,20 @@
# vx-select 选择器

## vx-select
## API

### Slot

#### v-slot:item

每一项的插槽,用来自定义渲染每一项,根元素必须使用 `v-list-item` 及绑定上 `v-bind="props"`

slot scope
```
{ item: ListItem; index: number; props: Record<string, unknown> }
```
[example](#slot-item)

## 示例(vx-select)

:::demo

Expand Down Expand Up @@ -60,7 +74,8 @@
item-value="id"
placeholder="choose a item"
closable-chips
/>
>
</vx-select>
<vx-select
v-model="valueNormal"
Expand All @@ -69,7 +84,8 @@
item-title="name"
item-value="id"
placeholder="choose a item"
/>
>
</vx-select>
<vx-select
label="Normal Select + required rule"
Expand Down Expand Up @@ -133,14 +149,14 @@ const srcs = {
5: 'https://cdn.vuetifyjs.com/images/lists/5.jpg'
}
const items = ref([
{ id: 1, name: 'Sandra Adams', group: 'Group 1', avatar: srcs[1] },
{ id: 2, name: 'Ali Connors', group: 'Group 1', avatar: srcs[2] },
{ id: 3, name: 'Trevor Hansen', group: 'Group 1', avatar: srcs[3] },
{ id: 4, name: 'Tucker Smith', group: 'Group 1', avatar: srcs[2] },
{ id: 5, name: 'Britta Holt', group: 'Group 2', avatar: srcs[4] },
{ id: 6, name: 'Jane Smith ', group: 'Group 2', avatar: srcs[5] },
{ id: 7, name: 'John Smith', group: 'Group 2', avatar: srcs[1] },
{ id: 8, name: 'Sandra Williams', group: 'Group 2', avatar: srcs[3] }
{ id: 1, name: 'Sandra Adams', group: 'Group 1', avatar: srcs[1], icon:"mdi-wifi" },
{ id: 2, name: 'Ali Connors', group: 'Group 1', avatar: srcs[2], icon:"mdi-wifi" },
{ id: 3, name: 'Trevor Hansen', group: 'Group 1', avatar: srcs[3], icon:"mdi-wifi" },
{ id: 4, name: 'Tucker Smith', group: 'Group 1', avatar: srcs[2], icon:"mdi-wifi" },
{ id: 5, name: 'Britta Holt', group: 'Group 2', avatar: srcs[4], icon:"mdi-wifi" },
{ id: 6, name: 'Jane Smith ', group: 'Group 2', avatar: srcs[5], icon:"mdi-wifi" },
{ id: 7, name: 'John Smith', group: 'Group 2', avatar: srcs[1], icon:"mdi-wifi" },
{ id: 8, name: 'Sandra Williams', group: 'Group 2', avatar: srcs[3], icon:"mdi-wifi" }
])
</script>
Expand All @@ -149,7 +165,97 @@ const items = ref([

:::

## vx-selectmany

### Slot(item)

item 的原始数据在 item.raw 里

:::demo

```vue
<template>
<vx-select
type="autocomplete"
v-model="valueAutoComplete"
multiple
chips
clearable
error-messages="error message"
label="autoComplete Select(state with error)"
:items="items"
item-title="name"
item-value="id"
placeholder="choose a item"
closable-chips
>
<template v-slot:item="{ props, item }">
<v-list-item
v-bind="props"
:title="item.title"
>
<template v-slot:prepend>
<v-icon :icon="item.raw.icon"></v-icon>
</template>
</v-list-item>
</template>
</vx-select>
<vx-select
v-model="valueNormal"
label="Normal Select"
:items="items"
item-title="name"
item-value="id"
placeholder="choose a item"
>
<template v-slot:item="{ props, item }">
<v-list-item
v-bind="props"
:title="item.title"
>
<template v-slot:prepend>
<v-icon :icon="item.raw.icon"></v-icon>
</template>
</v-list-item>
</template>
</vx-select>
</template>
<script setup lang="ts">
import { ref } from 'vue'
const valueAutoComplete = ref([1, 2, 3])
const valueNormal = ref([1])
const valueWithErrorMsg = ref([1])
const srcs = {
1: 'https://cdn.vuetifyjs.com/images/lists/1.jpg',
2: 'https://cdn.vuetifyjs.com/images/lists/2.jpg',
3: 'https://cdn.vuetifyjs.com/images/lists/3.jpg',
4: 'https://cdn.vuetifyjs.com/images/lists/4.jpg',
5: 'https://cdn.vuetifyjs.com/images/lists/5.jpg'
}
const items = ref([
{ id: 1, name: 'Sandra Adams', group: 'Group 1', avatar: srcs[1], icon:"mdi-wifi" },
{ id: 2, name: 'Ali Connors', group: 'Group 1', avatar: srcs[2], icon:"mdi-wifi" },
{ id: 3, name: 'Trevor Hansen', group: 'Group 1', avatar: srcs[3], icon:"mdi-wifi" },
{ id: 4, name: 'Tucker Smith', group: 'Group 1', avatar: srcs[2], icon:"mdi-wifi" },
{ id: 5, name: 'Britta Holt', group: 'Group 2', avatar: srcs[4], icon:"mdi-wifi" },
{ id: 6, name: 'Jane Smith ', group: 'Group 2', avatar: srcs[5], icon:"mdi-wifi" },
{ id: 7, name: 'John Smith', group: 'Group 2', avatar: srcs[1], icon:"mdi-wifi" },
{ id: 8, name: 'Sandra Williams', group: 'Group 2', avatar: srcs[3], icon:"mdi-wifi" }
])
</script>
<style scoped></style>
```

:::


## 示例(vx-selectmany)

> legacy component
Expand Down
16 changes: 13 additions & 3 deletions ui/vuetifyx/vuetifyxjs/src/lib/Form/VXSelect.vue
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,11 @@
density="compact"
color="primary"
@update:model-value="onUpdateModelValue"
/>
>
<template v-if="hasItemSlot" #item="{ props, index, item }">
<slot name="item" :props="props" :index="index" :item="item" />
</template>
</v-autocomplete>
<v-select
v-else
:closable-chips="closableChips"
Expand All @@ -44,17 +48,23 @@
density="compact"
color="primary"
@update:model-value="onUpdateModelValue"
/>
>
<template v-if="hasItemSlot" #item="{ props, index, item }">
<slot name="item" :props="props" :index="index" :item="item" />
</template>
</v-select>
</div>
</template>

<script setup lang="ts">
import { defineEmits, ref, watch, PropType } from 'vue'
import { defineEmits, ref, watch, PropType, useSlots, Slots } from 'vue'
import VXLabel from '../Common/VXLabel.vue'
import { useFilteredAttrs } from '@/lib/composables/useFilteredAttrs'
const { filteredAttrs } = useFilteredAttrs()
const emit = defineEmits(['update:modelValue'])
const slots: Slots = useSlots()
const hasItemSlot = slots['item'] !== undefined
const props = defineProps({
modelValue: null,
type: String,
Expand Down

0 comments on commit 1da2995

Please sign in to comment.