commit
4c653112a2
@ -4,7 +4,7 @@
|
|||||||
::: title 基本介绍
|
::: title 基本介绍
|
||||||
:::
|
:::
|
||||||
|
|
||||||
::: describe 用于代替原生的选择器,或者需要一个更优雅的多选器时。
|
::: describe 用于代替原生的选择器,或者需要一个更优雅的多选器时。支持关键词查询
|
||||||
:::
|
:::
|
||||||
|
|
||||||
::: title 基础使用
|
::: title 基础使用
|
||||||
@ -40,10 +40,10 @@ export default {
|
|||||||
::: demo
|
::: demo
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<lay-button @click="change1">切换-当前值 : {{value}}</lay-button>
|
<lay-button @click="change1">切换-当前值 : {{value2}}</lay-button>
|
||||||
<br/>
|
<br/>
|
||||||
<br/>
|
<br/>
|
||||||
<lay-select v-model="value">
|
<lay-select v-model="value2">
|
||||||
<lay-select-option value="1" label="学习"></lay-select-option>
|
<lay-select-option value="1" label="学习"></lay-select-option>
|
||||||
<lay-select-option value="2" label="编码"></lay-select-option>
|
<lay-select-option value="2" label="编码"></lay-select-option>
|
||||||
<lay-select-option value="3" label="运动"></lay-select-option>
|
<lay-select-option value="3" label="运动"></lay-select-option>
|
||||||
@ -55,13 +55,13 @@ import { ref } from 'vue'
|
|||||||
|
|
||||||
export default {
|
export default {
|
||||||
setup() {
|
setup() {
|
||||||
const value = ref(null);
|
const value2 = ref(null);
|
||||||
var i = 1;
|
var i = 1;
|
||||||
function change1(){
|
function change1(){
|
||||||
value.value=i++%3+1
|
value2.value=i++%3+1
|
||||||
}
|
}
|
||||||
return {
|
return {
|
||||||
value,
|
value2,
|
||||||
change1
|
change1
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -100,13 +100,141 @@ export default {
|
|||||||
|
|
||||||
:::
|
:::
|
||||||
|
|
||||||
::: title 海量数据
|
::: title 关键词变化事件,可作为远程搜索处理算法
|
||||||
|
:::
|
||||||
|
|
||||||
|
::: demo
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<lay-select @search="search" v-model="selected">
|
||||||
|
<lay-select-option value="1" label="学习"></lay-select-option>
|
||||||
|
<lay-select-option value="2" label="编码" disabled></lay-select-option>
|
||||||
|
<lay-select-option value="3" label="运动"></lay-select-option>
|
||||||
|
</lay-select>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { ref } from 'vue'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
setup() {
|
||||||
|
const selected = ref('1');
|
||||||
|
function search(txt){
|
||||||
|
console.log('关键词:',txt)
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
selected,search
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
:::
|
||||||
|
|
||||||
|
::: title 选择项自定义搜索内容,可以在keyword属性中传入拼音用于支持拼音搜索
|
||||||
:::
|
:::
|
||||||
|
|
||||||
::: demo
|
::: demo
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<lay-select v-model="selected">
|
<lay-select v-model="selected">
|
||||||
|
<lay-select-option value="1" label="学习" keyword="学习xuexi"></lay-select-option>
|
||||||
|
<lay-select-option value="2" label="编码" disabled></lay-select-option>
|
||||||
|
<lay-select-option value="3" label="运动"></lay-select-option>
|
||||||
|
</lay-select>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { ref } from 'vue'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
setup() {
|
||||||
|
const selected = ref('1');
|
||||||
|
return {
|
||||||
|
selected
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
:::
|
||||||
|
|
||||||
|
::: title 传入items属性进行选项渲染
|
||||||
|
:::
|
||||||
|
|
||||||
|
::: demo
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<lay-select v-model="selected" :items="items">
|
||||||
|
</lay-select>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { ref } from 'vue'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
setup() {
|
||||||
|
const selected = ref('1');
|
||||||
|
const items=ref([
|
||||||
|
{label:'选项1',value:1,keyword:'选项xuanxiang1'},
|
||||||
|
{label:'选项2',value:2,keyword:'选项xuanxiang2'},
|
||||||
|
{label:'选项3',value:3,keyword:'选项xuanxiang3',disabled:true},
|
||||||
|
])
|
||||||
|
return {
|
||||||
|
selected,items
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
|
||||||
|
:::
|
||||||
|
|
||||||
|
::: title 传入create属性和接收create事件用于开启创建子项功能
|
||||||
|
:::
|
||||||
|
|
||||||
|
::: demo
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<lay-select v-model="selected" :items="items" :create="true" @create="createEvent">
|
||||||
|
</lay-select>
|
||||||
|
当前元素: {{items.map(o=>o.label).join()}}
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { ref } from 'vue'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
setup() {
|
||||||
|
const selected = ref('1');
|
||||||
|
const items=ref([
|
||||||
|
{label:'选项1',value:'1',keyword:'选项xuanxiang1'},
|
||||||
|
{label:'选项2',value:2,keyword:'选项xuanxiang2'},
|
||||||
|
{label:'选项3',value:3,keyword:'选项xuanxiang3',disabled:true},
|
||||||
|
]);
|
||||||
|
function createEvent(v){
|
||||||
|
items.value.push({
|
||||||
|
label:v,
|
||||||
|
value:items.value.length
|
||||||
|
})
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
selected,items,createEvent
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
|
||||||
|
:::
|
||||||
|
|
||||||
|
::: title 海量数据
|
||||||
|
:::
|
||||||
|
|
||||||
|
::: demo
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<lay-select v-model="selected2">
|
||||||
<lay-select-option value="1" label="学习"></lay-select-option>
|
<lay-select-option value="1" label="学习"></lay-select-option>
|
||||||
<lay-select-option value="3" label="运动"></lay-select-option>
|
<lay-select-option value="3" label="运动"></lay-select-option>
|
||||||
<lay-select-option value="1" label="学习"></lay-select-option>
|
<lay-select-option value="1" label="学习"></lay-select-option>
|
||||||
@ -132,10 +260,10 @@ import { ref } from 'vue'
|
|||||||
export default {
|
export default {
|
||||||
setup() {
|
setup() {
|
||||||
|
|
||||||
const selected = ref('1')
|
const selected2 = ref('1')
|
||||||
|
|
||||||
return {
|
return {
|
||||||
selected
|
selected2
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -193,6 +321,7 @@ export default {
|
|||||||
| disabled | 是否禁用 | `boolean` | `true` `false` | `false` |
|
| disabled | 是否禁用 | `boolean` | `true` `false` | `false` |
|
||||||
| showEmpty | 是否增加空提示选项 | `boolean` | `true` `false` | `true` |
|
| showEmpty | 是否增加空提示选项 | `boolean` | `true` `false` | `true` |
|
||||||
| multiple | 是否为多选 | `boolean` | `true` `false` | `false` |
|
| multiple | 是否为多选 | `boolean` | `true` `false` | `false` |
|
||||||
|
| create | 是否允许创建 | `boolean` | `true` `false` | `false` |
|
||||||
|
|
||||||
|
|
||||||
:::
|
:::
|
||||||
@ -205,6 +334,8 @@ export default {
|
|||||||
| 属性 | 描述 | 接收值 |
|
| 属性 | 描述 | 接收值 |
|
||||||
| ------ | ---------- | --------------- |
|
| ------ | ---------- | --------------- |
|
||||||
| change | 切换事件 | value |
|
| change | 切换事件 | value |
|
||||||
|
| search | 关键词变化事件 | 用户输入的关键词 string |
|
||||||
|
| create | 允许创建情况下的创建回调事件 | 用户输入的关键词 string |
|
||||||
|
|
||||||
:::
|
:::
|
||||||
|
|
||||||
@ -220,6 +351,7 @@ export default {
|
|||||||
| ------------ | --------------------- | ------------------------- | -------------- | -------- |
|
| ------------ | --------------------- | ------------------------- | -------------- | -------- |
|
||||||
| label | 标签值(`必填`) | `string` | - | - |
|
| label | 标签值(`必填`) | `string` | - | - |
|
||||||
| value | 值 | `string` / `number` | - | - |
|
| value | 值 | `string` / `number` | - | - |
|
||||||
|
| keyword | 用于匹配关键词的数据,传入文本+拼音可以支持拼音搜索 | `string` | - | - |
|
||||||
| disabled | 是否禁用 | `boolean` | `true` `false` | `false` |
|
| disabled | 是否禁用 | `boolean` | `true` `false` | `false` |
|
||||||
|
|
||||||
:::
|
:::
|
||||||
|
@ -29,6 +29,8 @@ export interface LaySelectProps {
|
|||||||
showEmpty?: boolean;
|
showEmpty?: boolean;
|
||||||
emptyMessage?: string;
|
emptyMessage?: string;
|
||||||
multiple?: boolean;
|
multiple?: boolean;
|
||||||
|
create?: boolean;
|
||||||
|
items?: { label: string, value: string | number | [] | null, key: string }[]
|
||||||
}
|
}
|
||||||
|
|
||||||
const selectRef = ref<null | HTMLElement>(null);
|
const selectRef = ref<null | HTMLElement>(null);
|
||||||
@ -43,6 +45,7 @@ const props = withDefaults(defineProps<LaySelectProps>(), {
|
|||||||
disabled: false,
|
disabled: false,
|
||||||
showEmpty: true,
|
showEmpty: true,
|
||||||
multiple: false,
|
multiple: false,
|
||||||
|
create: false
|
||||||
});
|
});
|
||||||
|
|
||||||
const openState = ref(false);
|
const openState = ref(false);
|
||||||
@ -54,9 +57,10 @@ const open = function () {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
openState.value = !openState.value;
|
openState.value = !openState.value;
|
||||||
|
console.log(props.create)
|
||||||
};
|
};
|
||||||
|
|
||||||
const emit = defineEmits(["update:modelValue", "change"]);
|
const emit = defineEmits(["update:modelValue", "change", 'search', 'create']);
|
||||||
const selectItem = ref<SelectItem>({
|
const selectItem = ref<SelectItem>({
|
||||||
value: !props.multiple
|
value: !props.multiple
|
||||||
? props.modelValue
|
? props.modelValue
|
||||||
@ -96,13 +100,31 @@ watch(props, () => {
|
|||||||
|
|
||||||
// 禁止操作子项
|
// 禁止操作子项
|
||||||
const disabledItemMap: { [key: string | number]: boolean } = {};
|
const disabledItemMap: { [key: string | number]: boolean } = {};
|
||||||
const selectItemHandle = function (
|
const txt = ref("")
|
||||||
|
const input = ref(false)
|
||||||
|
const value = computed({
|
||||||
|
set(v: any) {
|
||||||
|
txt.value = v;
|
||||||
|
emit('search', v)
|
||||||
|
},
|
||||||
|
get() {
|
||||||
|
if (input.value) {
|
||||||
|
return txt.value;
|
||||||
|
}
|
||||||
|
// return txt.value;
|
||||||
|
return !selectItem.value.multiple && selectItem.value.value !== null
|
||||||
|
? selectItem.value.label
|
||||||
|
: null
|
||||||
|
}
|
||||||
|
})
|
||||||
|
const selectItemHandle = async function (
|
||||||
_selectItem: SelectItem,
|
_selectItem: SelectItem,
|
||||||
isChecked?: boolean
|
isChecked?: boolean
|
||||||
) {
|
) {
|
||||||
if (!props.multiple) {
|
if (!props.multiple) {
|
||||||
openState.value = false;
|
openState.value = false;
|
||||||
}
|
}
|
||||||
|
txt.value = ""
|
||||||
disabledItemMap[_selectItem.value as string | number] =
|
disabledItemMap[_selectItem.value as string | number] =
|
||||||
_selectItem.disabled as boolean;
|
_selectItem.disabled as boolean;
|
||||||
if (typeof isChecked !== "boolean") {
|
if (typeof isChecked !== "boolean") {
|
||||||
@ -144,6 +166,7 @@ const selectItemPush = function (p: SelectItem) {
|
|||||||
provide("selectItemHandle", selectItemHandle);
|
provide("selectItemHandle", selectItemHandle);
|
||||||
provide("selectItemPush", selectItemPush);
|
provide("selectItemPush", selectItemPush);
|
||||||
provide("selectItem", selectItem);
|
provide("selectItem", selectItem);
|
||||||
|
provide("keyword", txt)
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
@ -163,12 +186,9 @@ provide("selectItem", selectItem);
|
|||||||
: emptyMessage ?? placeholder
|
: emptyMessage ?? placeholder
|
||||||
"
|
"
|
||||||
:disabled="disabled"
|
:disabled="disabled"
|
||||||
readonly
|
v-model="value"
|
||||||
:value="
|
@input="input = true"
|
||||||
!selectItem.multiple && selectItem.value !== null
|
@blur="input = false"
|
||||||
? selectItem.label
|
|
||||||
: null
|
|
||||||
"
|
|
||||||
:name="name"
|
:name="name"
|
||||||
:class="[
|
:class="[
|
||||||
'layui-input',
|
'layui-input',
|
||||||
@ -204,8 +224,7 @@ provide("selectItem", selectItem);
|
|||||||
: null,
|
: null,
|
||||||
})
|
})
|
||||||
"
|
"
|
||||||
>
|
></i>
|
||||||
</i>
|
|
||||||
</lay-badge>
|
</lay-badge>
|
||||||
</template>
|
</template>
|
||||||
</div>
|
</div>
|
||||||
@ -214,9 +233,22 @@ provide("selectItem", selectItem);
|
|||||||
|
|
||||||
<!-- 下拉内容 -->
|
<!-- 下拉内容 -->
|
||||||
<dl class="layui-anim layui-anim-upbit">
|
<dl class="layui-anim layui-anim-upbit">
|
||||||
<template v-if="!multiple && showEmpty">
|
<template v-if="!multiple && showEmpty && !props.create">
|
||||||
<lay-select-option :value="null" :label="emptyMessage ?? placeholder" />
|
<lay-select-option :value="null" :label="emptyMessage ?? placeholder" />
|
||||||
</template>
|
</template>
|
||||||
|
<template v-if="props.create">
|
||||||
|
<dd @click="emit('create', txt)">{{ txt }}</dd>
|
||||||
|
</template>
|
||||||
|
<template v-if="props.items">
|
||||||
|
<lay-select-option
|
||||||
|
v-for="(v, k) in props.items"
|
||||||
|
:key="k"
|
||||||
|
:value="v.value"
|
||||||
|
:label="v.label"
|
||||||
|
:disabled="v.disabled"
|
||||||
|
:keyword="v.keyword"
|
||||||
|
></lay-select-option>
|
||||||
|
</template>
|
||||||
<slot></slot>
|
<slot></slot>
|
||||||
</dl>
|
</dl>
|
||||||
</div>
|
</div>
|
||||||
|
@ -7,21 +7,25 @@ export default {
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import LayCheckbox from "../checkbox";
|
import LayCheckbox from "../checkbox";
|
||||||
import { SelectItem, SelectItemHandle, SelectItemPush } from "../../types";
|
import { SelectItem, SelectItemHandle, SelectItemPush } from "../../types";
|
||||||
import { computed, inject, onMounted, Ref } from "vue";
|
import { computed, inject, onMounted, Ref, ref } from "vue";
|
||||||
|
|
||||||
export interface LaySelectOptionProps {
|
export interface LaySelectOptionProps {
|
||||||
value: string | null | undefined;
|
value: string | null | undefined | number;
|
||||||
label?: string;
|
label: string;
|
||||||
|
keyword?: string;
|
||||||
disabled?: boolean;
|
disabled?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
const props = withDefaults(defineProps<LaySelectOptionProps>(), {
|
const props = withDefaults(defineProps<LaySelectOptionProps>(), {
|
||||||
disabled: false,
|
disabled: false,
|
||||||
|
keyword: "",
|
||||||
|
label: ""
|
||||||
});
|
});
|
||||||
|
|
||||||
const selectItemHandle = inject("selectItemHandle") as SelectItemHandle;
|
const selectItemHandle = inject("selectItemHandle") as SelectItemHandle;
|
||||||
const selectItem = inject("selectItem") as Ref<SelectItem>;
|
const selectItem = inject("selectItem") as Ref<SelectItem>;
|
||||||
const selectItemPush = inject("selectItemPush") as Ref<SelectItemPush>;
|
const selectItemPush = inject("selectItemPush") as Ref<SelectItemPush>;
|
||||||
|
const keyword = inject('keyword') as Ref<string>
|
||||||
|
|
||||||
const selectHandle = function () {
|
const selectHandle = function () {
|
||||||
!props.disabled && callSelectItemHandle(!selected.value);
|
!props.disabled && callSelectItemHandle(!selected.value);
|
||||||
@ -56,25 +60,24 @@ const callSelectItemPush = function () {
|
|||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
selectItemPush(item);
|
selectItemPush(item);
|
||||||
};
|
};
|
||||||
|
const search = ref("")
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
|
search.value = props.keyword || props.label
|
||||||
callSelectItemPush();
|
callSelectItemPush();
|
||||||
selected.value && callSelectItemHandle();
|
selected.value && callSelectItemHandle();
|
||||||
|
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<dd
|
<dd
|
||||||
|
v-show="keyword ? search.includes(keyword) : true"
|
||||||
:value="value"
|
:value="value"
|
||||||
:class="[{ 'layui-this': selected }, { 'layui-disabled': disabled }]"
|
:class="[{ 'layui-this': selected }, { 'layui-disabled': disabled }]"
|
||||||
@click="selectHandle"
|
@click="selectHandle"
|
||||||
>
|
>
|
||||||
<template v-if="selectItem.multiple">
|
<template v-if="selectItem.multiple">
|
||||||
<lay-checkbox
|
<lay-checkbox skin="primary" v-model="selected" @change="selectHandle" label />
|
||||||
skin="primary"
|
|
||||||
v-model="selected"
|
|
||||||
@change="selectHandle"
|
|
||||||
label=""
|
|
||||||
/>
|
|
||||||
</template>
|
</template>
|
||||||
<slot>{{ label }}</slot>
|
<slot>{{ label }}</slot>
|
||||||
</dd>
|
</dd>
|
||||||
|
Loading…
Reference in New Issue
Block a user