✨(component): 更新日志
This commit is contained in:
parent
0e8a649fa2
commit
568b8f6131
@ -1,3 +1,8 @@
|
||||
@import "../checkbox/index.less";
|
||||
@import "../input/index.less";
|
||||
@import "../dropdown/index.less";
|
||||
@import "../tagInput/index.less";
|
||||
|
||||
.layui-select {
|
||||
width: 220px;
|
||||
|
||||
|
@ -1,176 +1,191 @@
|
||||
<script lang="ts">
|
||||
export default {
|
||||
name: "LaySelect",
|
||||
};
|
||||
</script>
|
||||
|
||||
<script setup lang="ts">
|
||||
import "./index.less";
|
||||
import {
|
||||
provide,
|
||||
computed,
|
||||
ref,
|
||||
Ref,
|
||||
useSlots,
|
||||
onMounted,
|
||||
VNode,
|
||||
Component,
|
||||
watch,
|
||||
} from "vue";
|
||||
import LayInput from "../input/index.vue";
|
||||
import LayTagInput from "../tagInput/index.vue";
|
||||
import LayDropdown from "../dropdown/index.vue";
|
||||
import LaySelectOption, {
|
||||
LaySelectOptionProps,
|
||||
} from "../selectOption/index.vue";
|
||||
|
||||
export interface LaySelectProps {
|
||||
name?: string;
|
||||
create?: boolean;
|
||||
disabled?: boolean;
|
||||
placeholder?: string;
|
||||
modelValue?: any;
|
||||
multiple?: boolean;
|
||||
items?: LaySelectOptionProps[];
|
||||
size?: "lg" | "md" | "sm" | "xs";
|
||||
allowClear?: boolean;
|
||||
}
|
||||
|
||||
export interface SelectEmits {
|
||||
(e: "update:modelValue", value: string): void;
|
||||
(e: "change", value: string): void;
|
||||
}
|
||||
|
||||
const props = withDefaults(defineProps<LaySelectProps>(), {
|
||||
modelValue: null,
|
||||
placeholder: "请选择",
|
||||
disabled: false,
|
||||
multiple: false,
|
||||
create: false,
|
||||
size: "md",
|
||||
allowClear: false,
|
||||
});
|
||||
|
||||
const slots = useSlots();
|
||||
const searchValue = ref("");
|
||||
const singleValue = ref("");
|
||||
const multipleValue = ref([]);
|
||||
const openState: Ref<boolean> = ref(false);
|
||||
const selectedItem: Ref<any> = ref([]);
|
||||
const options = ref<any>([]);
|
||||
const emits = defineEmits<SelectEmits>();
|
||||
|
||||
onMounted(() => {
|
||||
if (slots.default) {
|
||||
getOption(slots.default());
|
||||
export default {
|
||||
name: "LaySelect",
|
||||
};
|
||||
</script>
|
||||
|
||||
<script setup lang="ts">
|
||||
import "./index.less";
|
||||
import {
|
||||
provide,
|
||||
computed,
|
||||
ref,
|
||||
Ref,
|
||||
useSlots,
|
||||
onMounted,
|
||||
VNode,
|
||||
Component,
|
||||
watch,
|
||||
} from "vue";
|
||||
import LayInput from "../input/index.vue";
|
||||
import LayTagInput from "../tagInput/index.vue";
|
||||
import LayDropdown from "../dropdown/index.vue";
|
||||
import LaySelectOption, {
|
||||
LaySelectOptionProps,
|
||||
} from "../selectOption/index.vue";
|
||||
|
||||
export interface LaySelectProps {
|
||||
name?: string;
|
||||
create?: boolean;
|
||||
disabled?: boolean;
|
||||
placeholder?: string;
|
||||
showEmpty?: boolean;
|
||||
emptyMessage?: string;
|
||||
modelValue?: any;
|
||||
multiple?: boolean;
|
||||
items?: LaySelectOptionProps[];
|
||||
size?: "lg" | "md" | "sm" | "xs";
|
||||
collapseTagsTooltip?: boolean;
|
||||
minCollapsedNum?: number;
|
||||
allowClear?: boolean;
|
||||
}
|
||||
|
||||
Object.assign(options.value, props.items);
|
||||
|
||||
watch(
|
||||
selectedValue,
|
||||
() => {
|
||||
if (multiple.value) {
|
||||
multipleValue.value = selectedValue.value.map((value: any) =>{
|
||||
return options.value.find((item: any) => item.value === value)
|
||||
})
|
||||
} else {
|
||||
singleValue.value = options.value.find((item: any) => {
|
||||
return item.value === selectedValue.value;
|
||||
})?.label;
|
||||
}
|
||||
},
|
||||
{ immediate: true }
|
||||
);
|
||||
});
|
||||
|
||||
const getOption = function (nodes: VNode[]) {
|
||||
nodes?.map((item: VNode) => {
|
||||
let component = item.type as Component;
|
||||
if (component.name === LaySelectOption.name) {
|
||||
options.value.push(item.props);
|
||||
} else {
|
||||
getOption(item.children as VNode[]);
|
||||
}
|
||||
|
||||
export interface SelectEmits {
|
||||
(e: "update:modelValue", value: string): void;
|
||||
(e: "change", value: string): void;
|
||||
}
|
||||
|
||||
const props = withDefaults(defineProps<LaySelectProps>(), {
|
||||
modelValue: null,
|
||||
placeholder: "请选择",
|
||||
showEmpty: true,
|
||||
emptyMessage: "请选择",
|
||||
collapseTagsTooltip: true,
|
||||
minCollapsedNum: 3,
|
||||
disabled: false,
|
||||
multiple: false,
|
||||
create: false,
|
||||
size: "md",
|
||||
allowClear: false,
|
||||
});
|
||||
};
|
||||
|
||||
const selectedValue = computed({
|
||||
get() {
|
||||
return props.modelValue;
|
||||
},
|
||||
set(val) {
|
||||
emits("update:modelValue", val);
|
||||
emits("change", val);
|
||||
},
|
||||
});
|
||||
|
||||
const multiple = computed(() => {
|
||||
return props.multiple;
|
||||
});
|
||||
|
||||
provide("openState", openState);
|
||||
provide("selectedItem", selectedItem);
|
||||
provide("selectedValue", selectedValue);
|
||||
provide("searchValue", searchValue);
|
||||
provide("multiple", multiple);
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="layui-select">
|
||||
<lay-dropdown
|
||||
:disabled="disabled"
|
||||
:update-at-scroll="true"
|
||||
@show="openState = true"
|
||||
@hide="openState = false"
|
||||
>
|
||||
<lay-tag-input
|
||||
v-if="multiple"
|
||||
v-model="multipleValue"
|
||||
:allow-clear="allowClear"
|
||||
:disabledInput="true"
|
||||
|
||||
const slots = useSlots();
|
||||
const searchValue = ref("");
|
||||
const singleValue = ref("");
|
||||
const multipleValue = ref([]);
|
||||
const openState: Ref<boolean> = ref(false);
|
||||
const selectedItem: Ref<any> = ref([]);
|
||||
const options = ref<any>([]);
|
||||
const emits = defineEmits<SelectEmits>();
|
||||
|
||||
onMounted(() => {
|
||||
if (slots.default) {
|
||||
getOption(slots.default());
|
||||
}
|
||||
|
||||
Object.assign(options.value, props.items);
|
||||
|
||||
watch(
|
||||
selectedValue,
|
||||
() => {
|
||||
if (multiple.value) {
|
||||
multipleValue.value = selectedValue.value.map((value: any) => {
|
||||
return options.value.find((item: any) => {
|
||||
item.disabled == "" || item.disabled == true ? item.closable = false : item.closable = true;
|
||||
return item.value === value;
|
||||
});
|
||||
|
||||
});
|
||||
} else {
|
||||
singleValue.value = options.value.find((item: any) => {
|
||||
return item.value === selectedValue.value;
|
||||
})?.label;
|
||||
}
|
||||
},
|
||||
{ immediate: true }
|
||||
);
|
||||
});
|
||||
|
||||
const getOption = function (nodes: VNode[]) {
|
||||
nodes?.map((item: VNode) => {
|
||||
let component = item.type as Component;
|
||||
if (component.name === LaySelectOption.name) {
|
||||
options.value.push(item.props);
|
||||
} else {
|
||||
getOption(item.children as VNode[]);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
const selectedValue = computed({
|
||||
get() {
|
||||
return props.modelValue;
|
||||
},
|
||||
set(val) {
|
||||
emits("update:modelValue", val);
|
||||
emits("change", val);
|
||||
},
|
||||
});
|
||||
|
||||
const multiple = computed(() => {
|
||||
return props.multiple;
|
||||
});
|
||||
|
||||
provide("openState", openState);
|
||||
provide("selectedItem", selectedItem);
|
||||
provide("selectedValue", selectedValue);
|
||||
provide("searchValue", searchValue);
|
||||
provide("multiple", multiple);
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="layui-select">
|
||||
<lay-dropdown
|
||||
:disabled="disabled"
|
||||
:update-at-scroll="true"
|
||||
@show="openState = true"
|
||||
@hide="openState = false"
|
||||
>
|
||||
<template #suffix>
|
||||
<lay-icon
|
||||
type="layui-icon-triangle-d"
|
||||
:class="{ triangle: openState }"
|
||||
></lay-icon>
|
||||
</template>
|
||||
</lay-tag-input>
|
||||
<lay-input
|
||||
v-else
|
||||
v-model="singleValue"
|
||||
:placeholder="placeholder"
|
||||
:allow-clear="allowClear"
|
||||
:readonly="true"
|
||||
>
|
||||
<template #suffix>
|
||||
<lay-icon
|
||||
type="layui-icon-triangle-d"
|
||||
:class="{ triangle: openState }"
|
||||
></lay-icon>
|
||||
</template>
|
||||
</lay-input>
|
||||
<template #content>
|
||||
<dl class="layui-select-options">
|
||||
<div class="layui-select-search" v-if="multiple">
|
||||
<lay-input
|
||||
v-model="searchValue"
|
||||
prefix-icon="layui-icon-search"
|
||||
placeholder="请搜索"
|
||||
size="sm"
|
||||
></lay-input>
|
||||
</div>
|
||||
<template v-if="items">
|
||||
<lay-select-option
|
||||
v-for="(item, index) in items"
|
||||
v-bind="item"
|
||||
:key="index"
|
||||
></lay-select-option>
|
||||
<lay-tag-input
|
||||
v-if="multiple"
|
||||
v-model="multipleValue"
|
||||
:allow-clear="allowClear"
|
||||
:collapseTagsTooltip="collapseTagsTooltip"
|
||||
:minCollapsedNum="minCollapsedNum"
|
||||
:disabledInput="true"
|
||||
>
|
||||
<template #suffix>
|
||||
<lay-icon
|
||||
type="layui-icon-triangle-d"
|
||||
:class="{ triangle: openState }"
|
||||
></lay-icon>
|
||||
</template>
|
||||
<slot></slot>
|
||||
</dl>
|
||||
</template>
|
||||
</lay-dropdown>
|
||||
</div>
|
||||
</template>
|
||||
</lay-tag-input>
|
||||
<lay-input
|
||||
v-else
|
||||
v-model="singleValue"
|
||||
:placeholder="placeholder"
|
||||
:allow-clear="allowClear"
|
||||
:readonly="true"
|
||||
>
|
||||
<template #suffix>
|
||||
<lay-icon
|
||||
type="layui-icon-triangle-d"
|
||||
:class="{ triangle: openState }"
|
||||
></lay-icon>
|
||||
</template>
|
||||
</lay-input>
|
||||
<template #content>
|
||||
<dl class="layui-select-options">
|
||||
<div class="layui-select-search" v-if="multiple">
|
||||
<lay-input
|
||||
v-model="searchValue"
|
||||
prefix-icon="layui-icon-search"
|
||||
placeholder="请搜索"
|
||||
size="sm"
|
||||
></lay-input>
|
||||
</div>
|
||||
<lay-select-option v-if="showEmpty && !multiple" :label="emptyMessage" value=""></lay-select-option>
|
||||
<template v-if="items">
|
||||
<lay-select-option
|
||||
v-for="(item, index) in items"
|
||||
v-bind="item"
|
||||
:key="index"
|
||||
></lay-select-option>
|
||||
</template>
|
||||
<slot></slot>
|
||||
</dl>
|
||||
</template>
|
||||
</lay-dropdown>
|
||||
</div>
|
||||
</template>
|
@ -14,7 +14,6 @@ import {
|
||||
Ref,
|
||||
onMounted,
|
||||
} from "vue";
|
||||
import { arrayExpression } from "@babel/types";
|
||||
|
||||
export interface LaySelectOptionProps {
|
||||
label: string;
|
||||
|
@ -19,6 +19,8 @@
|
||||
<li>[新增] tag-input 标签输入框组件, 用于录入事物的属性与纬度。</li>
|
||||
<li>[新增] table 组件 header 插槽, 用于在工具栏与表格之间插入元素。</li>
|
||||
<li>[新增] tabitem 组件 icon 属性, 提供 title 属性前置 icon 设置。</li>
|
||||
<li>[新增] select 组件 collapseTagsTooltip 属性, 多选模式下是否悬浮显示折叠的选中项。</li>
|
||||
<li>[新增] select 组件 minCollapsedNum 属性, 多选模式选中项超过多少时折叠。</li>
|
||||
<li>[修复] tolltip 组件 content 变化时, 位置无法自动计算调整的问题。</li>
|
||||
<li>[修复] breadcrumb-item 组件无法正确传递 attrs, 导致 @click 等自定义事件失效。</li>
|
||||
<li>[修复] layout 组件仅引入了 footer 作为内容元素时, layui-layout-vertical 样式不生效, 导致布局错误。</li>
|
||||
|
Loading…
Reference in New Issue
Block a user