Merge branch 'next' into feat-tag
This commit is contained in:
commit
b0bccc3292
@ -6,6 +6,8 @@
|
|||||||
|
|
||||||
- 3.合理的建议
|
- 3.合理的建议
|
||||||
|
|
||||||
|
- 4.当前版本
|
||||||
|
|
||||||
## 思路
|
## 思路
|
||||||
|
|
||||||
描述大概的解决思路,可以包含 API 设计和伪代码等
|
描述大概的解决思路,可以包含 API 设计和伪代码等
|
||||||
|
18
.github/ISSUE_TEMPLATE.md
vendored
18
.github/ISSUE_TEMPLATE.md
vendored
@ -1,15 +1,17 @@
|
|||||||
## background
|
## 背景
|
||||||
|
|
||||||
- 1.Describe the problem you want to solve
|
- 1.描述你希望解决的问题
|
||||||
|
|
||||||
- 2.State the status of the problem
|
- 2.陈述问题的现状
|
||||||
|
|
||||||
- 3.Reasonable suggestion
|
- 3.合理的建议
|
||||||
|
|
||||||
## train of thought
|
- 4.当前版本
|
||||||
|
|
||||||
Idea describes the general solution idea, including API design, pseudo code, etc
|
## 思路
|
||||||
|
|
||||||
## follow-up
|
描述大概的解决思路,可以包含 API 设计和伪代码等
|
||||||
|
|
||||||
For subsequent editing, attach the corresponding pull request address in the form of ` - [] some task '.
|
## 跟进
|
||||||
|
|
||||||
|
后续编辑,附上对应的 Pull Request 地址,可以用 `- [ ] some task` 的方式。
|
@ -11,8 +11,6 @@
|
|||||||
|
|
||||||
layui - vue(谐音:类 UI) 是 一 套 Vue 3.0 的 桌 面 端 组 件 库.
|
layui - vue(谐音:类 UI) 是 一 套 Vue 3.0 的 桌 面 端 组 件 库.
|
||||||
|
|
||||||
QQ 群 :[➀ 336720831](https://jq.qq.com/?_wv=1027&k=oQA1SC80)
|
|
||||||
|
|
||||||
**Run with code Sandbox.**
|
**Run with code Sandbox.**
|
||||||
|
|
||||||
[](https://codesandbox.io/s/11mvy)
|
[](https://codesandbox.io/s/11mvy)
|
||||||
|
@ -10,8 +10,6 @@
|
|||||||
|
|
||||||
layui - vue(谐音:类 UI) 是 一 套 Vue 3.0 的 桌 面 端 组 件 库.
|
layui - vue(谐音:类 UI) 是 一 套 Vue 3.0 的 桌 面 端 组 件 库.
|
||||||
|
|
||||||
QQ 群 :[➀ 336720831](https://jq.qq.com/?_wv=1027&k=oQA1SC80)
|
|
||||||
|
|
||||||
**Run with code Sandbox.**
|
**Run with code Sandbox.**
|
||||||
|
|
||||||
[](https://codesandbox.io/s/11mvy)
|
[](https://codesandbox.io/s/11mvy)
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@layui/layui-vue",
|
"name": "@layui/layui-vue",
|
||||||
"version": "1.4.0-alpha.1",
|
"version": "1.4.5",
|
||||||
"author": "就眠儀式",
|
"author": "就眠儀式",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"description": "a component library for Vue 3 base on layui-vue",
|
"description": "a component library for Vue 3 base on layui-vue",
|
||||||
|
@ -16,6 +16,14 @@
|
|||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.layui-card .layui-card-footer {
|
||||||
|
height: 42px;
|
||||||
|
line-height: 42px;
|
||||||
|
padding: 0 15px;
|
||||||
|
border-top: 1px solid #f6f6f6;
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
.layui-card .layui-card-header .layui-card-header-extra {
|
.layui-card .layui-card-header .layui-card-header-extra {
|
||||||
float: right;
|
float: right;
|
||||||
}
|
}
|
||||||
|
@ -44,5 +44,8 @@ const classes = computed(() => {
|
|||||||
<slot name="body" v-if="slot.body"></slot>
|
<slot name="body" v-if="slot.body"></slot>
|
||||||
<slot v-else></slot>
|
<slot v-else></slot>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="layui-card-footer" v-if="slot.footer">
|
||||||
|
<slot name="footer"></slot>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
@ -12,10 +12,11 @@
|
|||||||
<lay-input
|
<lay-input
|
||||||
:name="name"
|
:name="name"
|
||||||
:readonly="readonly"
|
:readonly="readonly"
|
||||||
v-model="dateValue"
|
|
||||||
:placeholder="placeholder"
|
:placeholder="placeholder"
|
||||||
prefix-icon="layui-icon-date"
|
:prefix-icon="prefixIcon"
|
||||||
|
:suffix-icon="suffixIcon"
|
||||||
:disabled="disabled"
|
:disabled="disabled"
|
||||||
|
v-model="dateValue"
|
||||||
v-if="!range"
|
v-if="!range"
|
||||||
@change="onChange"
|
@change="onChange"
|
||||||
:allow-clear="!disabled && allowClear"
|
:allow-clear="!disabled && allowClear"
|
||||||
@ -130,6 +131,8 @@ export interface LayDatePickerProps {
|
|||||||
readonly?: boolean;
|
readonly?: boolean;
|
||||||
allowClear?: boolean;
|
allowClear?: boolean;
|
||||||
size?: "lg" | "md" | "sm" | "xs";
|
size?: "lg" | "md" | "sm" | "xs";
|
||||||
|
prefixIcon?: string;
|
||||||
|
suffixIcon?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
const props = withDefaults(defineProps<LayDatePickerProps>(), {
|
const props = withDefaults(defineProps<LayDatePickerProps>(), {
|
||||||
@ -142,6 +145,8 @@ const props = withDefaults(defineProps<LayDatePickerProps>(), {
|
|||||||
readonly: false,
|
readonly: false,
|
||||||
allowClear: false,
|
allowClear: false,
|
||||||
size: "md",
|
size: "md",
|
||||||
|
prefixIcon: "layui-icon-date",
|
||||||
|
suffixIcon: "",
|
||||||
});
|
});
|
||||||
|
|
||||||
const dropdownRef = ref(null);
|
const dropdownRef = ref(null);
|
||||||
@ -293,22 +298,29 @@ watch(
|
|||||||
props.range && props.modelValue
|
props.range && props.modelValue
|
||||||
? (props.modelValue as string[])[0] || ""
|
? (props.modelValue as string[])[0] || ""
|
||||||
: (props.modelValue as string);
|
: (props.modelValue as string);
|
||||||
hms.value.hh = dayjs(initModelValue).hour();
|
|
||||||
hms.value.mm = dayjs(initModelValue).minute();
|
hms.value.hh = isNaN(dayjs(initModelValue).hour())
|
||||||
hms.value.ss = dayjs(initModelValue).second();
|
? 0
|
||||||
|
: dayjs(initModelValue).hour();
|
||||||
|
hms.value.mm = isNaN(dayjs(initModelValue).minute())
|
||||||
|
? 0
|
||||||
|
: dayjs(initModelValue).minute();
|
||||||
|
hms.value.ss = isNaN(dayjs(initModelValue).second())
|
||||||
|
? 0
|
||||||
|
: dayjs(initModelValue).second();
|
||||||
|
|
||||||
if (initModelValue.length === 8 && props.type === "time") {
|
if (initModelValue.length === 8 && props.type === "time") {
|
||||||
//dayjs 解析时间容错
|
|
||||||
let modelValue = initModelValue;
|
let modelValue = initModelValue;
|
||||||
modelValue = "1970-01-01 " + modelValue;
|
modelValue = "1970-01-01 " + modelValue;
|
||||||
hms.value.hh = dayjs(modelValue).hour();
|
hms.value.hh = dayjs(modelValue).hour();
|
||||||
hms.value.mm = dayjs(modelValue).minute();
|
hms.value.mm = dayjs(modelValue).minute();
|
||||||
hms.value.ss = dayjs(modelValue).second();
|
hms.value.ss = dayjs(modelValue).second();
|
||||||
}
|
}
|
||||||
|
|
||||||
currentYear.value = initModelValue ? getYear(initModelValue) : -1;
|
currentYear.value = initModelValue ? getYear(initModelValue) : -1;
|
||||||
currentMonth.value = initModelValue ? getMonth(initModelValue) : -1;
|
currentMonth.value = initModelValue ? getMonth(initModelValue) : -1;
|
||||||
currentDay.value = initModelValue ? getDay(initModelValue) : -1;
|
currentDay.value = initModelValue ? getDay(initModelValue) : -1;
|
||||||
if (props.type === "date" || props.type === "datetime") {
|
if (props.type === "date" || props.type === "datetime") {
|
||||||
// date与datetime容错
|
|
||||||
if (currentYear.value === -1) currentYear.value = dayjs().year();
|
if (currentYear.value === -1) currentYear.value = dayjs().year();
|
||||||
if (currentMonth.value === -1) currentMonth.value = dayjs().month();
|
if (currentMonth.value === -1) currentMonth.value = dayjs().month();
|
||||||
}
|
}
|
||||||
|
33
package/component/src/component/dropdown/TeleportWrapper.vue
Normal file
33
package/component/src/component/dropdown/TeleportWrapper.vue
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
<script lang="ts">
|
||||||
|
export default {
|
||||||
|
name: "TeleportWrapper",
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import { onMounted, ref } from "vue";
|
||||||
|
|
||||||
|
export interface TeleportWrapperProps {
|
||||||
|
to?: string;
|
||||||
|
disabled?: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
const props = withDefaults(defineProps<TeleportWrapperProps>(), {
|
||||||
|
to: "",
|
||||||
|
disabled: false,
|
||||||
|
});
|
||||||
|
|
||||||
|
const target = ref<Element | null>(null);
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
if (!props.to) return;
|
||||||
|
const el = document.querySelector(props.to);
|
||||||
|
if (el) {
|
||||||
|
target.value = el;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
<template>
|
||||||
|
<Teleport :to="target" :disabled="!target || disabled">
|
||||||
|
<slot></slot>
|
||||||
|
</Teleport>
|
||||||
|
</template>
|
@ -6,7 +6,7 @@ export default {
|
|||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import "./index.less";
|
import "./index.less";
|
||||||
import { ComputedRef, CSSProperties, inject, reactive, Ref } from "vue";
|
import { ComputedRef, CSSProperties, inject, reactive, Ref, toRefs } from "vue";
|
||||||
import {
|
import {
|
||||||
computed,
|
computed,
|
||||||
nextTick,
|
nextTick,
|
||||||
@ -19,7 +19,6 @@ import {
|
|||||||
} from "vue";
|
} from "vue";
|
||||||
import {
|
import {
|
||||||
onClickOutside,
|
onClickOutside,
|
||||||
useMouse,
|
|
||||||
useResizeObserver,
|
useResizeObserver,
|
||||||
useThrottleFn,
|
useThrottleFn,
|
||||||
useWindowSize,
|
useWindowSize,
|
||||||
@ -30,6 +29,7 @@ import {
|
|||||||
ElementScrollRect,
|
ElementScrollRect,
|
||||||
DropdownContext,
|
DropdownContext,
|
||||||
} from "./interface";
|
} from "./interface";
|
||||||
|
import TeleportWrapper from "./TeleportWrapper.vue";
|
||||||
|
|
||||||
export type DropdownTrigger = "click" | "hover" | "focus" | "contextMenu";
|
export type DropdownTrigger = "click" | "hover" | "focus" | "contextMenu";
|
||||||
|
|
||||||
@ -47,12 +47,12 @@ export interface LayDropdownProps {
|
|||||||
blurToClose?: boolean;
|
blurToClose?: boolean;
|
||||||
clickOutsideToClose?: boolean;
|
clickOutsideToClose?: boolean;
|
||||||
contentOffset?: number;
|
contentOffset?: number;
|
||||||
// 以下暂不开放
|
|
||||||
mouseEnterDelay?: number;
|
mouseEnterDelay?: number;
|
||||||
mouseLeaveDelay?: number;
|
mouseLeaveDelay?: number;
|
||||||
focusDelay?: number;
|
focusDelay?: number;
|
||||||
|
// 未完善,暂不开放
|
||||||
alignPoint?: boolean;
|
alignPoint?: boolean;
|
||||||
popupContainer?: string | HTMLElement | undefined;
|
popupContainer?: string | undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
const props = withDefaults(defineProps<LayDropdownProps>(), {
|
const props = withDefaults(defineProps<LayDropdownProps>(), {
|
||||||
@ -77,18 +77,24 @@ const props = withDefaults(defineProps<LayDropdownProps>(), {
|
|||||||
});
|
});
|
||||||
|
|
||||||
const childrenRefs = new Set<Ref<HTMLElement>>();
|
const childrenRefs = new Set<Ref<HTMLElement>>();
|
||||||
const dropdownCtx = inject<DropdownContext>(dropdownInjectionKey, undefined);
|
const dropdownCtx = inject<DropdownContext | undefined>(
|
||||||
|
dropdownInjectionKey,
|
||||||
|
undefined
|
||||||
|
);
|
||||||
const dropdownRef = shallowRef<HTMLElement | undefined>();
|
const dropdownRef = shallowRef<HTMLElement | undefined>();
|
||||||
const contentRef = shallowRef<HTMLElement | undefined>();
|
const contentRef = shallowRef<HTMLElement | undefined>();
|
||||||
const contentStyle = ref<CSSProperties>({});
|
const contentStyle = ref<CSSProperties>({});
|
||||||
const { width: windowWidth, height: windowHeight } = useWindowSize();
|
const { width: windowWidth, height: windowHeight } = useWindowSize();
|
||||||
const { x: mouseLeft, y: mouseTop } = useMouse();
|
const mousePosition = reactive({
|
||||||
|
x: 0,
|
||||||
|
y: 0,
|
||||||
|
});
|
||||||
|
const { x: mouseLeft, y: mouseTop } = toRefs(mousePosition);
|
||||||
const openState = ref(false);
|
const openState = ref(false);
|
||||||
|
|
||||||
const containerRef = computed(() =>
|
const containerRef = computed(() =>
|
||||||
props.popupContainer
|
props.popupContainer
|
||||||
? // @ts-ignore
|
? document.querySelector<HTMLElement>(props.popupContainer) ?? document.body
|
||||||
document.querySelector<HTMLElement>(props.popupContainer) ?? document.body
|
|
||||||
: dropdownRef.value
|
: dropdownRef.value
|
||||||
) as ComputedRef<HTMLElement>;
|
) as ComputedRef<HTMLElement>;
|
||||||
|
|
||||||
@ -96,7 +102,7 @@ const triggerMethods = computed(() =>
|
|||||||
([] as Array<DropdownTrigger>).concat(props.trigger)
|
([] as Array<DropdownTrigger>).concat(props.trigger)
|
||||||
);
|
);
|
||||||
|
|
||||||
const emit = defineEmits(["open", "hide"]);
|
const emit = defineEmits(["show", "hide"]);
|
||||||
|
|
||||||
let delayTimer = 0;
|
let delayTimer = 0;
|
||||||
|
|
||||||
@ -107,10 +113,10 @@ const cleanDelayTimer = () => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const open = (delay?: number): void => {
|
const show = (delay?: number): void => {
|
||||||
if (props.disabled == false) {
|
if (props.disabled == false) {
|
||||||
changeVisible(true, delay);
|
changeVisible(true, delay);
|
||||||
emit("open");
|
emit("show");
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -124,7 +130,7 @@ const toggle = (): void => {
|
|||||||
if (openState.value) {
|
if (openState.value) {
|
||||||
hide();
|
hide();
|
||||||
} else {
|
} else {
|
||||||
open();
|
show();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -166,19 +172,32 @@ const getElementScrollRect = (element: HTMLElement, containerRect: DOMRect) => {
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const getTriggerRect = () => {
|
||||||
|
return {
|
||||||
|
top: mouseTop.value,
|
||||||
|
bottom: mouseTop.value,
|
||||||
|
left: mouseLeft.value,
|
||||||
|
right: mouseLeft.value,
|
||||||
|
scrollTop: mouseTop.value,
|
||||||
|
scrollBottom: mouseTop.value,
|
||||||
|
scrollLeft: mouseLeft.value,
|
||||||
|
scrollRight: mouseLeft.value,
|
||||||
|
width: 0,
|
||||||
|
height: 0,
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
const updateContentStyle = () => {
|
const updateContentStyle = () => {
|
||||||
if (!containerRef.value || !dropdownRef.value || !contentRef.value) {
|
if (!containerRef.value || !dropdownRef.value || !contentRef.value) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const containerRect = containerRef.value.getBoundingClientRect();
|
const containerRect = containerRef.value.getBoundingClientRect();
|
||||||
const triggerRect = getElementScrollRect(dropdownRef.value, containerRect);
|
const triggerRect = props.alignPoint
|
||||||
|
? getTriggerRect()
|
||||||
|
: getElementScrollRect(dropdownRef.value, containerRect);
|
||||||
const contentRect = getElementScrollRect(contentRef.value, containerRect);
|
const contentRect = getElementScrollRect(contentRef.value, containerRect);
|
||||||
const { style } = getContentStyle(
|
const { style } = getContentStyle(props.placement, triggerRect, contentRect);
|
||||||
props.placement,
|
|
||||||
triggerRect,
|
|
||||||
contentRect,
|
|
||||||
props.alignPoint
|
|
||||||
);
|
|
||||||
|
|
||||||
if (props.autoFitMinWidth) {
|
if (props.autoFitMinWidth) {
|
||||||
style.minWidth = `${triggerRect.width}px`;
|
style.minWidth = `${triggerRect.width}px`;
|
||||||
@ -190,10 +209,9 @@ const updateContentStyle = () => {
|
|||||||
|
|
||||||
if (props.autoFitPosition) {
|
if (props.autoFitPosition) {
|
||||||
nextTick(() => {
|
nextTick(() => {
|
||||||
const triggerRect = getElementScrollRect(
|
const triggerRect = props.alignPoint
|
||||||
dropdownRef.value as HTMLElement,
|
? getTriggerRect()
|
||||||
containerRect
|
: getElementScrollRect(dropdownRef.value as HTMLElement, containerRect);
|
||||||
);
|
|
||||||
const contentRect = getElementScrollRect(
|
const contentRect = getElementScrollRect(
|
||||||
contentRef.value as HTMLElement,
|
contentRef.value as HTMLElement,
|
||||||
containerRect
|
containerRect
|
||||||
@ -217,23 +235,25 @@ const updateContentStyle = () => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const updateMousePosition = (e: MouseEvent) => {
|
||||||
|
if (props.alignPoint) {
|
||||||
|
const { pageX, pageY } = e;
|
||||||
|
mousePosition.x = pageX;
|
||||||
|
mousePosition.y = pageY;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
const getContentStyle = (
|
const getContentStyle = (
|
||||||
placement: DropdownPlacement,
|
placement: DropdownPlacement,
|
||||||
triggerRect: ElementScrollRect,
|
triggerRect: ElementScrollRect,
|
||||||
contentRect: ElementScrollRect,
|
contentRect: ElementScrollRect,
|
||||||
isAlignPoint?: boolean,
|
|
||||||
{
|
{
|
||||||
customStyle = {},
|
customStyle = {},
|
||||||
}: {
|
}: {
|
||||||
customStyle?: CSSProperties;
|
customStyle?: CSSProperties;
|
||||||
} = {}
|
} = {}
|
||||||
) => {
|
) => {
|
||||||
let { top, left } = getContentOffset(
|
let { top, left } = getContentOffset(placement, triggerRect, contentRect);
|
||||||
placement,
|
|
||||||
triggerRect,
|
|
||||||
contentRect,
|
|
||||||
isAlignPoint
|
|
||||||
);
|
|
||||||
const style = {
|
const style = {
|
||||||
top: `${top}px`,
|
top: `${top}px`,
|
||||||
left: `${left}px`,
|
left: `${left}px`,
|
||||||
@ -315,15 +335,8 @@ const getFitPlacement = (
|
|||||||
const getContentOffset = (
|
const getContentOffset = (
|
||||||
placement: DropdownPlacement,
|
placement: DropdownPlacement,
|
||||||
triggerRect: ElementScrollRect,
|
triggerRect: ElementScrollRect,
|
||||||
contentRect: ElementScrollRect,
|
contentRect: ElementScrollRect
|
||||||
isAlignPoint?: boolean
|
|
||||||
) => {
|
) => {
|
||||||
if (isAlignPoint) {
|
|
||||||
return {
|
|
||||||
top: mouseTop.value - triggerRect.top,
|
|
||||||
left: mouseLeft.value - triggerRect.left,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
switch (placement) {
|
switch (placement) {
|
||||||
case "top":
|
case "top":
|
||||||
return {
|
return {
|
||||||
@ -426,11 +439,13 @@ const handleScroll = useThrottleFn(() => {
|
|||||||
}
|
}
|
||||||
}, 10);
|
}, 10);
|
||||||
|
|
||||||
const handleClick = () => {
|
const handleClick = (e: MouseEvent) => {
|
||||||
|
e.stopPropagation();
|
||||||
if (props.disabled || (openState.value && !props.clickToClose)) {
|
if (props.disabled || (openState.value && !props.clickToClose)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (triggerMethods.value.includes("click")) {
|
if (triggerMethods.value.includes("click")) {
|
||||||
|
updateMousePosition(e);
|
||||||
toggle();
|
toggle();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -444,6 +459,7 @@ const handleContextMenuClick = (e: MouseEvent) => {
|
|||||||
if (props.alignPoint) {
|
if (props.alignPoint) {
|
||||||
hide();
|
hide();
|
||||||
}
|
}
|
||||||
|
updateMousePosition(e);
|
||||||
toggle();
|
toggle();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -452,7 +468,7 @@ const handleMouseEnter = (e: MouseEvent) => {
|
|||||||
if (props.disabled || !triggerMethods.value.includes("hover")) {
|
if (props.disabled || !triggerMethods.value.includes("hover")) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
open(props.mouseEnterDelay);
|
show(props.mouseEnterDelay);
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleMouseEnterWithContext = (e: MouseEvent) => {
|
const handleMouseEnterWithContext = (e: MouseEvent) => {
|
||||||
@ -482,7 +498,7 @@ const handleFocusin = () => {
|
|||||||
if (props.disabled || !triggerMethods.value.includes("focus")) {
|
if (props.disabled || !triggerMethods.value.includes("focus")) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
open(props.focusDelay);
|
show(props.focusDelay);
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleFocusout = () => {
|
const handleFocusout = () => {
|
||||||
@ -504,16 +520,6 @@ const removeChildRef = (ref: any) => {
|
|||||||
dropdownCtx?.removeChildRef(ref);
|
dropdownCtx?.removeChildRef(ref);
|
||||||
};
|
};
|
||||||
|
|
||||||
provide(
|
|
||||||
dropdownInjectionKey,
|
|
||||||
reactive({
|
|
||||||
onMouseenter: handleMouseEnterWithContext,
|
|
||||||
onMouseleave: handleMouseLeaveWithContext,
|
|
||||||
addChildRef,
|
|
||||||
removeChildRef,
|
|
||||||
})
|
|
||||||
);
|
|
||||||
|
|
||||||
dropdownCtx?.addChildRef(contentRef);
|
dropdownCtx?.addChildRef(contentRef);
|
||||||
|
|
||||||
const { stop: removeContentResizeObserver } = useResizeObserver(
|
const { stop: removeContentResizeObserver } = useResizeObserver(
|
||||||
@ -534,20 +540,29 @@ const { stop: removeTriggerResizeObserver } = useResizeObserver(
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
onClickOutside(dropdownRef, (e) => {
|
onClickOutside(
|
||||||
|
dropdownRef,
|
||||||
|
(e) => {
|
||||||
if (
|
if (
|
||||||
!props.clickOutsideToClose ||
|
!props.clickOutsideToClose ||
|
||||||
|
!openState.value ||
|
||||||
dropdownRef.value?.contains(e.target as HTMLElement) ||
|
dropdownRef.value?.contains(e.target as HTMLElement) ||
|
||||||
contentRef.value?.contains(e.target as HTMLElement)
|
contentRef.value?.contains(e.target as HTMLElement)
|
||||||
)
|
) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
for (const item of childrenRefs) {
|
for (const item of childrenRefs) {
|
||||||
if (item.value?.contains(e.target as HTMLElement)) {
|
if (item.value?.contains(e.target as HTMLElement)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
hide();
|
hide();
|
||||||
});
|
},
|
||||||
|
{
|
||||||
|
capture: false,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
let scrollElements: HTMLElement[] | undefined;
|
let scrollElements: HTMLElement[] | undefined;
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
@ -579,24 +594,20 @@ watch(
|
|||||||
{ immediate: true }
|
{ immediate: true }
|
||||||
);
|
);
|
||||||
|
|
||||||
const getTriggerRect = (isAlignPoint: boolean) => {
|
provide(
|
||||||
return isAlignPoint
|
dropdownInjectionKey,
|
||||||
? ({
|
reactive({
|
||||||
top: mouseTop.value,
|
onMouseenter: handleMouseEnterWithContext,
|
||||||
bottom: mouseTop.value,
|
onMouseleave: handleMouseLeaveWithContext,
|
||||||
left: mouseLeft.value,
|
addChildRef,
|
||||||
right: mouseLeft.value,
|
removeChildRef,
|
||||||
width: 0,
|
hide,
|
||||||
height: 0,
|
})
|
||||||
x: mouseLeft.value,
|
);
|
||||||
y: mouseTop.value,
|
|
||||||
} as DOMRect)
|
|
||||||
: dropdownRef.value!.getBoundingClientRect();
|
|
||||||
};
|
|
||||||
|
|
||||||
provide("openState", openState);
|
provide("openState", openState);
|
||||||
|
|
||||||
defineExpose({ open, hide, toggle });
|
defineExpose({ show, hide, toggle });
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
@ -609,10 +620,10 @@ defineExpose({ open, hide, toggle });
|
|||||||
@focusout="handleFocusout()"
|
@focusout="handleFocusout()"
|
||||||
:class="{ 'layui-dropdown-up': openState }"
|
:class="{ 'layui-dropdown-up': openState }"
|
||||||
>
|
>
|
||||||
<div @click="handleClick()" @contextmenu="handleContextMenuClick">
|
<div @click="handleClick" @contextmenu="handleContextMenuClick">
|
||||||
<slot></slot>
|
<slot></slot>
|
||||||
</div>
|
</div>
|
||||||
<Teleport :to="popupContainer" :disabled="!popupContainer">
|
<TeleportWrapper :to="popupContainer">
|
||||||
<dl
|
<dl
|
||||||
v-if="openState"
|
v-if="openState"
|
||||||
ref="contentRef"
|
ref="contentRef"
|
||||||
@ -623,6 +634,6 @@ defineExpose({ open, hide, toggle });
|
|||||||
>
|
>
|
||||||
<slot name="content"></slot>
|
<slot name="content"></slot>
|
||||||
</dl>
|
</dl>
|
||||||
</Teleport>
|
</TeleportWrapper>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
@ -31,6 +31,7 @@ export interface DropdownContext {
|
|||||||
onMouseleave: Function;
|
onMouseleave: Function;
|
||||||
addChildRef: Function;
|
addChildRef: Function;
|
||||||
removeChildRef: Function;
|
removeChildRef: Function;
|
||||||
|
hide: Function;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const dropdownInjectionKey = Symbol("dropdownInjectKey");
|
export const dropdownInjectionKey = Symbol("dropdownInjectKey");
|
||||||
|
@ -6,6 +6,7 @@ export default {
|
|||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { inject, Ref } from "vue";
|
import { inject, Ref } from "vue";
|
||||||
|
import { DropdownContext, dropdownInjectionKey } from "../dropdown/interface";
|
||||||
|
|
||||||
export interface LayDropdownMenuItemProps {
|
export interface LayDropdownMenuItemProps {
|
||||||
disabled?: boolean;
|
disabled?: boolean;
|
||||||
@ -16,12 +17,16 @@ const props = withDefaults(defineProps<LayDropdownMenuItemProps>(), {
|
|||||||
});
|
});
|
||||||
|
|
||||||
const openState: Ref<boolean> = inject("openState") as Ref<boolean>;
|
const openState: Ref<boolean> = inject("openState") as Ref<boolean>;
|
||||||
|
const dropdownCtx = inject<DropdownContext | undefined>(
|
||||||
|
dropdownInjectionKey,
|
||||||
|
undefined
|
||||||
|
);
|
||||||
|
|
||||||
const handleClick = () => {
|
const handleClick = () => {
|
||||||
if (props.disabled) {
|
if (props.disabled) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
openState.value = false;
|
dropdownCtx?.hide();
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
@ -71,8 +71,10 @@
|
|||||||
border-color: #d2d2d2 !important;
|
border-color: #d2d2d2 !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.layui-input-clear,
|
||||||
.layui-input-prefix,
|
.layui-input-prefix,
|
||||||
.layui-input-suffix {
|
.layui-input-suffix,
|
||||||
|
.layui-input-password {
|
||||||
background-color: white;
|
background-color: white;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -90,8 +92,8 @@
|
|||||||
padding: 0 15px;
|
padding: 0 15px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.layui-input-password,
|
.layui-input-clear,
|
||||||
.layui-input-clear {
|
.layui-input-password {
|
||||||
flex: none;
|
flex: none;
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
@ -103,6 +105,10 @@
|
|||||||
line-height: 1.3;
|
line-height: 1.3;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.layui-input input::-ms-reveal {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
.layui-input{
|
.layui-input{
|
||||||
&[size="lg"] {
|
&[size="lg"] {
|
||||||
.set-size(@input-lg);
|
.set-size(@input-lg);
|
||||||
|
@ -50,7 +50,7 @@ const menuTheme = computed(() => props.theme);
|
|||||||
|
|
||||||
const openKeys = computed({
|
const openKeys = computed({
|
||||||
get() {
|
get() {
|
||||||
return props.openKeys;
|
return props.collapse ? [] : props.openKeys;
|
||||||
},
|
},
|
||||||
set(val) {
|
set(val) {
|
||||||
emit("update:openKeys", val);
|
emit("update:openKeys", val);
|
||||||
@ -77,8 +77,7 @@ watch(
|
|||||||
} else {
|
} else {
|
||||||
openKeys.value = oldOpenKeys.value;
|
openKeys.value = oldOpenKeys.value;
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
{ immediate: true }
|
|
||||||
);
|
);
|
||||||
|
|
||||||
provideLevel(1);
|
provideLevel(1);
|
||||||
|
@ -41,24 +41,24 @@ const props = withDefaults(defineProps<LayPageProps>(), {
|
|||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
const slots = useSlots();
|
const slots = useSlots();
|
||||||
|
|
||||||
|
const maxPage = ref(0);
|
||||||
const limits = ref(props.limits);
|
const limits = ref(props.limits);
|
||||||
const pages = Math.floor(props.pages / 2);
|
const pages = Math.floor(props.pages / 2);
|
||||||
|
const currentPage: Ref<number> = ref(props.modelValue);
|
||||||
|
const currentPageShow: Ref<number> = ref(currentPage.value);
|
||||||
|
const inlimit = ref(props.limit);
|
||||||
|
|
||||||
const inlimit = computed({
|
watch(
|
||||||
get() {
|
() => props.limit,
|
||||||
return props.limit;
|
() => {
|
||||||
},
|
inlimit.value = props.limit;
|
||||||
set(v: number) {
|
}
|
||||||
emit("limit", v);
|
);
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
const maxPage = ref(0);
|
|
||||||
|
|
||||||
const totalPage = computed(() => {
|
const totalPage = computed(() => {
|
||||||
maxPage.value = Math.ceil(props.total / props.limit);
|
maxPage.value = Math.ceil(props.total / inlimit.value);
|
||||||
let r: number[] = [],
|
let r: number[] = [];
|
||||||
start =
|
let start =
|
||||||
maxPage.value <= props.pages
|
maxPage.value <= props.pages
|
||||||
? 1
|
? 1
|
||||||
: currentPage.value > pages
|
: currentPage.value > pages
|
||||||
@ -73,51 +73,59 @@ const totalPage = computed(() => {
|
|||||||
return r;
|
return r;
|
||||||
});
|
});
|
||||||
|
|
||||||
const currentPage: Ref<number> = ref(props.modelValue);
|
const emit = defineEmits(["update:modelValue", "update:limit", "change"]);
|
||||||
const currentPageShow: Ref<number> = ref(currentPage.value);
|
|
||||||
|
|
||||||
const emit = defineEmits(["jump", "limit", "update:modelValue"]);
|
const prev = () => {
|
||||||
|
|
||||||
const prev = function () {
|
|
||||||
if (currentPage.value === 1) {
|
if (currentPage.value === 1) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
currentPage.value--;
|
currentPage.value--;
|
||||||
|
emit("change", { current: currentPage.value, limit: inlimit.value });
|
||||||
};
|
};
|
||||||
|
|
||||||
const next = function () {
|
const next = () => {
|
||||||
if (currentPage.value === maxPage.value) {
|
if (currentPage.value === maxPage.value || maxPage.value === 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
currentPage.value++;
|
currentPage.value++;
|
||||||
|
emit("change", { current: currentPage.value, limit: inlimit.value });
|
||||||
};
|
};
|
||||||
|
|
||||||
const jump = function (page: number) {
|
const jump = (page: number) => {
|
||||||
currentPage.value = page;
|
currentPage.value = page;
|
||||||
|
emit("change", { current: currentPage.value, limit: inlimit.value });
|
||||||
};
|
};
|
||||||
|
|
||||||
const jumpPage = function () {
|
const jumpPage = () => {
|
||||||
currentPage.value = currentPageShow.value;
|
currentPage.value = currentPageShow.value;
|
||||||
|
emit("change", { current: currentPage.value, limit: inlimit.value });
|
||||||
};
|
};
|
||||||
|
|
||||||
watch(inlimit, function () {
|
const changelimit = () => {
|
||||||
currentPage.value = 1;
|
currentPage.value = 1;
|
||||||
|
emit("change", { current: currentPage.value, limit: inlimit.value });
|
||||||
|
};
|
||||||
|
|
||||||
|
const refresh = () => {
|
||||||
|
emit("change", { current: currentPage.value, limit: inlimit.value });
|
||||||
|
};
|
||||||
|
|
||||||
|
watch(inlimit, () => {
|
||||||
|
emit("update:limit", inlimit.value);
|
||||||
});
|
});
|
||||||
|
|
||||||
watch(currentPage, function () {
|
watch(currentPage, () => {
|
||||||
if (currentPage.value > totalPage.value[totalPage.value.length - 1]) {
|
const min = totalPage.value[0];
|
||||||
currentPage.value = totalPage.value[totalPage.value.length - 1];
|
const max = totalPage.value[totalPage.value.length - 1];
|
||||||
}
|
if (currentPage.value > max) currentPage.value = max;
|
||||||
if (currentPage.value < totalPage.value[0]) {
|
if (currentPage.value < min) currentPage.value = min;
|
||||||
currentPage.value = totalPage.value[0];
|
|
||||||
}
|
|
||||||
currentPageShow.value = currentPage.value;
|
currentPageShow.value = currentPage.value;
|
||||||
emit("jump", { current: currentPage.value });
|
|
||||||
emit("update:modelValue", currentPage.value);
|
emit("update:modelValue", currentPage.value);
|
||||||
});
|
});
|
||||||
|
|
||||||
watch(
|
watch(
|
||||||
() => props.modelValue,
|
() => props.modelValue,
|
||||||
function () {
|
() => {
|
||||||
currentPage.value = props.modelValue;
|
currentPage.value = props.modelValue;
|
||||||
currentPageShow.value = currentPage.value;
|
currentPageShow.value = currentPage.value;
|
||||||
}
|
}
|
||||||
@ -159,13 +167,14 @@ watch(
|
|||||||
>
|
>
|
||||||
</template>
|
</template>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<a
|
<a
|
||||||
href="javascript:;"
|
href="javascript:;"
|
||||||
class="layui-laypage-next"
|
class="layui-laypage-next"
|
||||||
:class="[
|
:class="[
|
||||||
currentPage === maxPage ? 'layui-disabled' : '',
|
currentPage === maxPage || maxPage === 0 ? 'layui-disabled' : '',
|
||||||
theme && currentPage !== maxPage ? 'layui-laypage-a-' + theme : '',
|
theme && currentPage !== maxPage && maxPage !== 0
|
||||||
|
? 'layui-laypage-a-' + theme
|
||||||
|
: '',
|
||||||
]"
|
]"
|
||||||
@click="next()"
|
@click="next()"
|
||||||
>
|
>
|
||||||
@ -173,13 +182,18 @@ watch(
|
|||||||
<template v-else>{{ t("page.next") }}</template>
|
<template v-else>{{ t("page.next") }}</template>
|
||||||
</a>
|
</a>
|
||||||
<span v-if="showLimit" class="layui-laypage-limits">
|
<span v-if="showLimit" class="layui-laypage-limits">
|
||||||
<select v-model="inlimit">
|
<select v-model="inlimit" @change="changelimit">
|
||||||
<option v-for="val of limits" :key="val" :value="val">
|
<option v-for="val of limits" :key="val" :value="val">
|
||||||
{{ val }} 条/页
|
{{ val }} 条/页
|
||||||
</option>
|
</option>
|
||||||
</select>
|
</select>
|
||||||
</span>
|
</span>
|
||||||
<a v-if="showRefresh" href="javascript:;" class="layui-laypage-refresh">
|
<a
|
||||||
|
v-if="showRefresh"
|
||||||
|
href="javascript:;"
|
||||||
|
@click="refresh"
|
||||||
|
class="layui-laypage-refresh"
|
||||||
|
>
|
||||||
<i class="layui-icon layui-icon-refresh"></i>
|
<i class="layui-icon layui-icon-refresh"></i>
|
||||||
</a>
|
</a>
|
||||||
<span v-if="props.showSkip" class="layui-laypage-skip">
|
<span v-if="props.showSkip" class="layui-laypage-skip">
|
||||||
@ -194,7 +208,7 @@ watch(
|
|||||||
type="button"
|
type="button"
|
||||||
class="layui-laypage-btn"
|
class="layui-laypage-btn"
|
||||||
@click="jumpPage()"
|
@click="jumpPage()"
|
||||||
:disabled="currentPageShow > maxPage"
|
:disabled="currentPageShow > maxPage || currentPageShow == currentPage"
|
||||||
>
|
>
|
||||||
确定
|
确定
|
||||||
</button>
|
</button>
|
||||||
|
@ -15,10 +15,7 @@ const props = defineProps<LayQuoteProps>();
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<blockquote
|
<div class="layui-quote" :class="[type ? `layui-quote-${props.type}` : '']">
|
||||||
class="layui-quote"
|
|
||||||
:class="[type ? `layui-quote-${props.type}` : '']"
|
|
||||||
>
|
|
||||||
<slot></slot>
|
<slot></slot>
|
||||||
</blockquote>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
@ -56,8 +56,8 @@ const props = withDefaults(defineProps<LayScrollProps>(), {
|
|||||||
|
|
||||||
const emit = defineEmits(["arrive"]);
|
const emit = defineEmits(["arrive"]);
|
||||||
|
|
||||||
const scrollRef = ref<HTMLElement | null>(null);
|
const scrollRef = ref<HTMLElement | null | undefined>();
|
||||||
const barRef = ref<HTMLElement | null>(null);
|
const barRef = ref<HTMLElement | null | undefined>();
|
||||||
|
|
||||||
const data = reactive({
|
const data = reactive({
|
||||||
translateY: 0, // 滚动块平移的距离
|
translateY: 0, // 滚动块平移的距离
|
||||||
@ -66,38 +66,33 @@ const data = reactive({
|
|||||||
winWidth: document.body.clientWidth, //初始化浏览器页面宽度
|
winWidth: document.body.clientWidth, //初始化浏览器页面宽度
|
||||||
});
|
});
|
||||||
|
|
||||||
let time = null; // 定时器
|
let time: NodeJS.Timeout; // 定时器
|
||||||
let isMove = false; // 判断鼠标是否点击滑块(为松开)
|
let isMove = false; // 判断鼠标是否点击滑块(为松开)
|
||||||
let moveClientY = 0; // 鼠标点击滑块时,相对滑块的位置
|
let moveClientY = 0; // 鼠标点击滑块时,相对滑块的位置
|
||||||
let trackHeight = 0; // 滚动条轨道高度
|
let trackHeight = 0; // 滚动条轨道高度
|
||||||
let wrapHeight = 0; // 容器高度(可视高度)
|
let wrapHeight = 0; // 容器高度(可视高度)
|
||||||
let wrapContentHeight = 0; // 内容高度(可滚动内容的高度)
|
let wrapContentHeight = 0; // 内容高度(可滚动内容的高度)
|
||||||
|
|
||||||
// 页面挂载后计算滚动条
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
monitorWindow(); //监听窗口尺寸
|
monitorWindow();
|
||||||
monitorScrollBar(); //监听内容元素尺寸
|
monitorScrollBar();
|
||||||
nextTick(() => {
|
nextTick(() => {
|
||||||
//dom渲染后
|
calculationLength();
|
||||||
calculationLength(); //初始化延迟更新滚动条
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
// 页面卸载清除定时器
|
// 页面卸载清除定时器
|
||||||
onUnmounted(() => {
|
onUnmounted(() => {
|
||||||
window.clearInterval(time);
|
window.clearInterval(time);
|
||||||
time = null;
|
|
||||||
});
|
});
|
||||||
|
|
||||||
// 监听页面尺寸改变计算滚动条
|
// 监听页面尺寸改变计算滚动条
|
||||||
const monitorWindow = function () {
|
const monitorWindow = function () {
|
||||||
let time; //定时器,防抖,窗口持续变化,延迟更新滚动条
|
let time: NodeJS.Timeout;
|
||||||
window.addEventListener("resize", () => {
|
window.addEventListener("resize", () => {
|
||||||
data.winWidth = document.body.clientWidth; //页面改变监听宽度控制移动端隐藏滚动条
|
data.winWidth = document.body.clientWidth;
|
||||||
clearTimeout(time);
|
clearTimeout(time);
|
||||||
time = setTimeout(() => {
|
time = setTimeout(() => {
|
||||||
//页面宽度变化继续监听,如果小于500就关闭自定义滚动条
|
|
||||||
// console.log("浏览器窗口变化更新滚动条");
|
|
||||||
initScrollListner();
|
initScrollListner();
|
||||||
}, 500);
|
}, 500);
|
||||||
});
|
});
|
||||||
@ -105,24 +100,23 @@ const monitorWindow = function () {
|
|||||||
|
|
||||||
//监听内容元素尺寸变化
|
//监听内容元素尺寸变化
|
||||||
const monitorScrollBar = function () {
|
const monitorScrollBar = function () {
|
||||||
var monitorUl = scrollRef.value.children[0];
|
// @ts-ignore
|
||||||
// var monitorDiv= document; // 监听document
|
var monitorUl = scrollRef.value;
|
||||||
let MutationObserver =
|
let MutationObserver =
|
||||||
window.MutationObserver ||
|
window.MutationObserver ||
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
window.WebKitMutationObserver ||
|
window.WebKitMutationObserver ||
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
window.MozMutationObserver;
|
window.MozMutationObserver;
|
||||||
let observer = new MutationObserver(function (mutations) {
|
let observer = new MutationObserver((mutations) => {
|
||||||
// console.log("内容元素变化更新滚动条");
|
|
||||||
initScrollListner();
|
initScrollListner();
|
||||||
});
|
});
|
||||||
|
if (monitorUl) {
|
||||||
// 监听子节点增加或者内容撑起的尺寸
|
|
||||||
observer.observe(monitorUl, {
|
observer.observe(monitorUl, {
|
||||||
attributes: true,
|
attributes: true,
|
||||||
childList: true,
|
childList: true,
|
||||||
});
|
});
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// 初始化延迟监听滚动条
|
// 初始化延迟监听滚动条
|
||||||
@ -137,7 +131,6 @@ const calculationLength = function () {
|
|||||||
// 间隔500毫秒清除定时器,滑块缩短会有动画效果,时间可延长没有影响
|
// 间隔500毫秒清除定时器,滑块缩短会有动画效果,时间可延长没有影响
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
window.clearInterval(time);
|
window.clearInterval(time);
|
||||||
time = null;
|
|
||||||
}, 2000);
|
}, 2000);
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -146,11 +139,10 @@ const initScrollListner = function () {
|
|||||||
let scroll = scrollRef.value;
|
let scroll = scrollRef.value;
|
||||||
let bar = barRef.value;
|
let bar = barRef.value;
|
||||||
// scroll有时候拿不到元素,要判断一下
|
// scroll有时候拿不到元素,要判断一下
|
||||||
if (scroll) {
|
if (scroll && bar) {
|
||||||
wrapContentHeight = scroll.scrollHeight;
|
wrapContentHeight = scroll.scrollHeight;
|
||||||
wrapHeight = scroll.clientHeight;
|
wrapHeight = scroll.clientHeight;
|
||||||
trackHeight = bar.clientHeight;
|
trackHeight = bar.clientHeight;
|
||||||
// console.log(wrapContentHeight ,wrapHeight);
|
|
||||||
// 容器高度 / 内容高度 100 150
|
// 容器高度 / 内容高度 100 150
|
||||||
data.heightPre = wrapHeight / wrapContentHeight;
|
data.heightPre = wrapHeight / wrapContentHeight;
|
||||||
// 滑动块的高度 根据 容器和内容的比 乘以 滚动轨道 计算出 滑动块的高度
|
// 滑动块的高度 根据 容器和内容的比 乘以 滚动轨道 计算出 滑动块的高度
|
||||||
@ -159,11 +151,7 @@ const initScrollListner = function () {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// 内容滚动时,计算滑块移动的距离
|
// 内容滚动时,计算滑块移动的距离
|
||||||
const onMosewheel = function (e) {
|
const onMosewheel = (e: any) => {
|
||||||
// scrollTop页面顶部滚出的高度
|
|
||||||
// offsetHeight页面可视区域高度
|
|
||||||
// scrollHeight页面正文全文高度
|
|
||||||
// data.translateY滚动块平移的距离
|
|
||||||
data.translateY = e.target.scrollTop * data.heightPre;
|
data.translateY = e.target.scrollTop * data.heightPre;
|
||||||
if (data.translateY == 0) {
|
if (data.translateY == 0) {
|
||||||
// 到达顶部
|
// 到达顶部
|
||||||
@ -178,12 +166,12 @@ const onMosewheel = function (e) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// 到达顶部或者底部通知父级元素
|
// 到达顶部或者底部通知父级元素
|
||||||
const arrive = function name(tb) {
|
const arrive = (tb: string) => {
|
||||||
emit("arrive", tb);
|
emit("arrive", tb);
|
||||||
};
|
};
|
||||||
|
|
||||||
// 鼠标点击滑块时
|
// 鼠标点击滑块时
|
||||||
const moveStart = function (e) {
|
const moveStart = (e: any) => {
|
||||||
isMove = true;
|
isMove = true;
|
||||||
// clientY:当鼠标事件发生时,鼠标相对于浏览器(这里说的是浏览器的有效区域)y轴的位置
|
// clientY:当鼠标事件发生时,鼠标相对于浏览器(这里说的是浏览器的有效区域)y轴的位置
|
||||||
// data.translateY 滚动块平移的距离
|
// data.translateY 滚动块平移的距离
|
||||||
@ -194,7 +182,7 @@ const moveStart = function (e) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// 鼠标移动,改变thumb的位置以及容器scrollTop的位置
|
// 鼠标移动,改变thumb的位置以及容器scrollTop的位置
|
||||||
const moveTo = function () {
|
const moveTo = () => {
|
||||||
document.onmousemove = (e) => {
|
document.onmousemove = (e) => {
|
||||||
// 移动时候判断是不是松开,松开就不在执行滑块移动操作
|
// 移动时候判断是不是松开,松开就不在执行滑块移动操作
|
||||||
if (isMove) {
|
if (isMove) {
|
||||||
@ -203,15 +191,17 @@ const moveTo = function () {
|
|||||||
// 滑块到达 底部 就不在改变滑块translateY值
|
// 滑块到达 底部 就不在改变滑块translateY值
|
||||||
data.translateY = trackHeight - data.barHeight;
|
data.translateY = trackHeight - data.barHeight;
|
||||||
} else if (e.clientY - moveClientY < 0) {
|
} else if (e.clientY - moveClientY < 0) {
|
||||||
// 滑块到达 顶部 就不在改变滑块translateY值
|
// 滑块到达 顶部 就不在改变滑块 translateY 值
|
||||||
data.translateY = 0;
|
data.translateY = 0;
|
||||||
} else {
|
} else {
|
||||||
//改变滑块位置
|
//改变滑块位置
|
||||||
data.translateY = e.clientY - moveClientY;
|
data.translateY = e.clientY - moveClientY;
|
||||||
}
|
}
|
||||||
// 计算出内容盒子滚出顶部的距离
|
// 计算出内容盒子滚出顶部的距离
|
||||||
|
if (scrollRef.value) {
|
||||||
scrollRef.value.scrollTop = data.translateY / data.heightPre;
|
scrollRef.value.scrollTop = data.translateY / data.heightPre;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
26
package/component/src/component/space/Renderer.ts
Normal file
26
package/component/src/component/space/Renderer.ts
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
import { defineComponent } from "vue";
|
||||||
|
|
||||||
|
import type { PropType } from "vue";
|
||||||
|
|
||||||
|
export default defineComponent({
|
||||||
|
name: "Renderer",
|
||||||
|
props: {
|
||||||
|
renderFn: {
|
||||||
|
type: Function,
|
||||||
|
default: null,
|
||||||
|
},
|
||||||
|
data: {
|
||||||
|
type: Object as PropType<Record<string, any>>,
|
||||||
|
default: undefined,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
setup(props) {
|
||||||
|
return () => {
|
||||||
|
if (typeof props.renderFn !== "function") {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return props.renderFn(props.data);
|
||||||
|
};
|
||||||
|
},
|
||||||
|
});
|
42
package/component/src/component/space/index.less
Normal file
42
package/component/src/component/space/index.less
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
.layui-space {
|
||||||
|
display: inline-flex;
|
||||||
|
|
||||||
|
&-horizontal {
|
||||||
|
.layui-space-item {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&-vertical {
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
&-wrap {
|
||||||
|
flex-wrap: wrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
&-fill {
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
|
||||||
|
&-align-start {
|
||||||
|
align-items: flex-start;
|
||||||
|
}
|
||||||
|
|
||||||
|
&-align-center {
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
&-align-end {
|
||||||
|
align-items: flex-end;
|
||||||
|
}
|
||||||
|
|
||||||
|
&-align-baseline {
|
||||||
|
align-items: baseline;
|
||||||
|
}
|
||||||
|
|
||||||
|
&-item {
|
||||||
|
width: inherit;
|
||||||
|
}
|
||||||
|
}
|
5
package/component/src/component/space/index.ts
Normal file
5
package/component/src/component/space/index.ts
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
import { withInstall, WithInstallType } from "../../utils";
|
||||||
|
import Component from "./index.vue";
|
||||||
|
|
||||||
|
const component: WithInstallType<typeof Component> = withInstall(Component);
|
||||||
|
export default component;
|
132
package/component/src/component/space/index.vue
Normal file
132
package/component/src/component/space/index.vue
Normal file
@ -0,0 +1,132 @@
|
|||||||
|
<script lang="ts">
|
||||||
|
export default {
|
||||||
|
name: "LaySpace",
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import "./index.less";
|
||||||
|
import {
|
||||||
|
computed,
|
||||||
|
h,
|
||||||
|
useSlots,
|
||||||
|
Comment,
|
||||||
|
VNode,
|
||||||
|
Fragment,
|
||||||
|
isVNode,
|
||||||
|
createTextVNode,
|
||||||
|
VNodeArrayChildren,
|
||||||
|
StyleValue,
|
||||||
|
} from "vue";
|
||||||
|
import Renderer from "./Renderer";
|
||||||
|
|
||||||
|
export type SpaceSize = "lg" | "md" | "sm" | "xs" | number | string;
|
||||||
|
|
||||||
|
export interface LaySpaceProps {
|
||||||
|
/* 对齐方式 */
|
||||||
|
align?: "start" | "end" | "center" | "baseline";
|
||||||
|
/* 间距方向 */
|
||||||
|
direction?: "horizontal" | "vertical";
|
||||||
|
/* 子元素是否填充父容器 */
|
||||||
|
fill?: boolean;
|
||||||
|
/* 间距大小 */
|
||||||
|
size?: SpaceSize | [SpaceSize, SpaceSize];
|
||||||
|
/* 是否自动折行 */
|
||||||
|
wrap?: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
const props = withDefaults(defineProps<LaySpaceProps>(), {
|
||||||
|
align: "center",
|
||||||
|
direction: "horizontal",
|
||||||
|
size: "sm",
|
||||||
|
});
|
||||||
|
|
||||||
|
const slots = useSlots();
|
||||||
|
|
||||||
|
const extractChildren = () => {
|
||||||
|
const result: VNode[] = [];
|
||||||
|
const children = slots.default && (slots?.default() as VNodeArrayChildren);
|
||||||
|
const elementData = Array.isArray(children) ? [...children] : [];
|
||||||
|
|
||||||
|
while (elementData.length) {
|
||||||
|
const vnode = elementData.shift();
|
||||||
|
|
||||||
|
if (vnode === null) continue;
|
||||||
|
|
||||||
|
if (Array.isArray(vnode)) {
|
||||||
|
elementData.unshift(...vnode);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!isVNode(vnode) || vnode.type === Comment) continue;
|
||||||
|
|
||||||
|
if (vnode.type === Fragment && Array.isArray(vnode.children)) {
|
||||||
|
elementData.unshift(vnode.children);
|
||||||
|
} else if (typeof vnode === "string" || typeof vnode === "number") {
|
||||||
|
result.push(createTextVNode(vnode));
|
||||||
|
} else {
|
||||||
|
result.push(vnode);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
};
|
||||||
|
|
||||||
|
const spaceClass = computed(() => [
|
||||||
|
"layui-space",
|
||||||
|
{
|
||||||
|
[`layui-space-align-${props.align}`]: props.align,
|
||||||
|
[`layui-space-${props.direction}`]: props.direction,
|
||||||
|
[`layui-space-wrap`]: props.wrap,
|
||||||
|
[`layui-space-fill`]: props.fill,
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
|
||||||
|
const spaceStyle = computed(() => {
|
||||||
|
const sizeMap = { xs: "4px", sm: "8px", md: "16px", lg: "24px" };
|
||||||
|
let gap = "";
|
||||||
|
|
||||||
|
if (Array.isArray(props.size)) {
|
||||||
|
gap = props.size
|
||||||
|
.map((size) => {
|
||||||
|
if (typeof size === "number") {
|
||||||
|
return `${size}px`;
|
||||||
|
}
|
||||||
|
if (typeof size === "string") {
|
||||||
|
return sizeMap[props.size as keyof Omit<SpaceSize, number>] || size;
|
||||||
|
}
|
||||||
|
return size;
|
||||||
|
})
|
||||||
|
.join(" ");
|
||||||
|
} else if (typeof props.size === "string") {
|
||||||
|
gap = sizeMap[props.size as keyof Omit<SpaceSize, string>] || props.size;
|
||||||
|
} else if (typeof props.size === "number") {
|
||||||
|
gap = `${props.size}px`;
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
gap,
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
const itemStyle = computed<StyleValue>(() => [
|
||||||
|
props.fill ? { flexGrow: 1, minWidth: "100%" } : {},
|
||||||
|
]);
|
||||||
|
|
||||||
|
const children = extractChildren();
|
||||||
|
|
||||||
|
const renderSpaceItems = () =>
|
||||||
|
children.map((child, index) => {
|
||||||
|
return h(
|
||||||
|
"div",
|
||||||
|
{
|
||||||
|
class: "layui-space-item",
|
||||||
|
style: itemStyle.value,
|
||||||
|
},
|
||||||
|
h(child)
|
||||||
|
);
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
<template>
|
||||||
|
<div :class="spaceClass" :style="spaceStyle">
|
||||||
|
<Renderer :renderFn="renderSpaceItems"></Renderer>
|
||||||
|
</div>
|
||||||
|
</template>
|
@ -1,4 +1,5 @@
|
|||||||
.layui-tab {
|
.layui-tab {
|
||||||
|
display: flex;
|
||||||
margin: 10px 0;
|
margin: 10px 0;
|
||||||
text-align: left !important;
|
text-align: left !important;
|
||||||
}
|
}
|
||||||
@ -7,14 +8,20 @@
|
|||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.layui-tab.is-left {
|
||||||
|
flex-direction: row;
|
||||||
|
}
|
||||||
|
|
||||||
.layui-tab.is-right {
|
.layui-tab.is-right {
|
||||||
display: flex;
|
|
||||||
flex-direction: row-reverse;
|
flex-direction: row-reverse;
|
||||||
justify-content: space-between
|
justify-content: space-between
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.layui-tab.is-top {
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
.layui-tab.is-bottom {
|
.layui-tab.is-bottom {
|
||||||
display: flex;
|
|
||||||
flex-direction: column-reverse
|
flex-direction: column-reverse
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -316,6 +323,7 @@
|
|||||||
|
|
||||||
.layui-tab-content {
|
.layui-tab-content {
|
||||||
padding: 15px 0;
|
padding: 15px 0;
|
||||||
|
flex: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
.layui-tab.is-right>.layui-tab-content,
|
.layui-tab.is-right>.layui-tab-content,
|
||||||
|
62
package/component/src/component/table/TablePage.vue
Normal file
62
package/component/src/component/table/TablePage.vue
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
<script lang="ts">
|
||||||
|
export default {
|
||||||
|
name: "TablePage",
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import { LayIcon } from "@layui/icons-vue";
|
||||||
|
import LayPage from "../page/index.vue";
|
||||||
|
|
||||||
|
export interface LayTablePageProps {
|
||||||
|
showPage?: boolean;
|
||||||
|
showSkip?: boolean;
|
||||||
|
showLimit?: boolean;
|
||||||
|
showCount?: boolean;
|
||||||
|
showRefresh?: boolean;
|
||||||
|
modelValue: number;
|
||||||
|
limits?: number[];
|
||||||
|
pages?: number;
|
||||||
|
total: number;
|
||||||
|
limit?: number;
|
||||||
|
theme?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
const props = withDefaults(defineProps<LayTablePageProps>(), {
|
||||||
|
showPage: true,
|
||||||
|
showLimit: true,
|
||||||
|
showSkip: true,
|
||||||
|
});
|
||||||
|
|
||||||
|
const emit = defineEmits(["update:modelValue", "update:limit", "change"]);
|
||||||
|
|
||||||
|
const change = (pageData: any) => {
|
||||||
|
emit("change", pageData);
|
||||||
|
emit("update:modelValue", pageData.current);
|
||||||
|
emit("update:limit", pageData.limit);
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<lay-page
|
||||||
|
:total="total"
|
||||||
|
:show-page="showPage"
|
||||||
|
:show-skip="showSkip"
|
||||||
|
:show-limit="showLimit"
|
||||||
|
:show-count="showCount"
|
||||||
|
:show-refresh="showRefresh"
|
||||||
|
:limits="limits"
|
||||||
|
:theme="theme"
|
||||||
|
:pages="pages"
|
||||||
|
v-model:modelValue="modelValue"
|
||||||
|
v-model:limit="limit"
|
||||||
|
@change="change"
|
||||||
|
>
|
||||||
|
<template #prev>
|
||||||
|
<lay-icon type="layui-icon-left" />
|
||||||
|
</template>
|
||||||
|
<template #next>
|
||||||
|
<lay-icon type="layui-icon-right" />
|
||||||
|
</template>
|
||||||
|
</lay-page>
|
||||||
|
</template>
|
@ -39,6 +39,7 @@ export interface LayTableRowProps {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const slot = useSlots();
|
const slot = useSlots();
|
||||||
|
|
||||||
const emit = defineEmits([
|
const emit = defineEmits([
|
||||||
"row",
|
"row",
|
||||||
"row-double",
|
"row-double",
|
||||||
@ -183,7 +184,7 @@ const renderFixedStyle = (column: any, columnIndex: number) => {
|
|||||||
props.columns[i].fixed == "left" &&
|
props.columns[i].fixed == "left" &&
|
||||||
props.tableColumnKeys.includes(props.columns[i].key)
|
props.tableColumnKeys.includes(props.columns[i].key)
|
||||||
) {
|
) {
|
||||||
left = left + props.columns[i]?.width.replace("px", "");
|
left = left + props.columns[i]?.width?.replace("px", "");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return { left: `${left}px` } as StyleValue;
|
return { left: `${left}px` } as StyleValue;
|
||||||
@ -195,7 +196,7 @@ const renderFixedStyle = (column: any, columnIndex: number) => {
|
|||||||
props.columns[i].fixed == "right" &&
|
props.columns[i].fixed == "right" &&
|
||||||
props.tableColumnKeys.includes(props.columns[i].key)
|
props.tableColumnKeys.includes(props.columns[i].key)
|
||||||
) {
|
) {
|
||||||
right = right + props.columns[i]?.width.replace("px", "");
|
right = right + props.columns[i]?.width?.replace("px", "");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return { right: `${right}px` } as StyleValue;
|
return { right: `${right}px` } as StyleValue;
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
@import "../checkbox/index.less";
|
@import "../checkbox/index.less";
|
||||||
|
@import "../radio/index.less";
|
||||||
@import "../dropdown/index.less";
|
@import "../dropdown/index.less";
|
||||||
@import "../page/index.less";
|
@import "../page/index.less";
|
||||||
|
|
||||||
.layui-table-col-special {
|
.layui-table-col-special {
|
||||||
width: 34px;
|
width: 34px;
|
||||||
}
|
}
|
||||||
@ -17,6 +19,13 @@
|
|||||||
font-weight: 400;
|
font-weight: 400;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.layui-table-footer {
|
||||||
|
min-height: 50px;
|
||||||
|
line-height: 30px;
|
||||||
|
background-color: #FAFAFA;
|
||||||
|
padding: 10px 15px;
|
||||||
|
}
|
||||||
|
|
||||||
.layui-table-mend,
|
.layui-table-mend,
|
||||||
.layui-table-tool,
|
.layui-table-tool,
|
||||||
.layui-table-total,
|
.layui-table-total,
|
||||||
|
@ -15,15 +15,16 @@ import {
|
|||||||
StyleValue,
|
StyleValue,
|
||||||
WritableComputedRef,
|
WritableComputedRef,
|
||||||
computed,
|
computed,
|
||||||
|
onBeforeUnmount,
|
||||||
} from "vue";
|
} from "vue";
|
||||||
import { v4 as uuidv4 } from "../../utils/guidUtil";
|
import { v4 as uuidv4 } from "../../utils/guidUtil";
|
||||||
import { Recordable } from "../../types";
|
import { Recordable } from "../../types";
|
||||||
import { LayIcon } from "@layui/icons-vue";
|
import { LayIcon } from "@layui/icons-vue";
|
||||||
import LayCheckbox from "../checkbox/index.vue";
|
import LayCheckbox from "../checkbox/index.vue";
|
||||||
import LayDropdown from "../dropdown/index.vue";
|
import LayDropdown from "../dropdown/index.vue";
|
||||||
import LayPage from "../page/index.vue";
|
|
||||||
import LayEmpty from "../empty/index.vue";
|
import LayEmpty from "../empty/index.vue";
|
||||||
import TableRow from "./TableRow.vue";
|
import TableRow from "./TableRow.vue";
|
||||||
|
import TablePage from "./TablePage.vue";
|
||||||
import { nextTick } from "vue";
|
import { nextTick } from "vue";
|
||||||
|
|
||||||
export interface LayTableProps {
|
export interface LayTableProps {
|
||||||
@ -92,6 +93,7 @@ const emit = defineEmits([
|
|||||||
const slot = useSlots();
|
const slot = useSlots();
|
||||||
const slots = slot.default && slot.default();
|
const slots = slot.default && slot.default();
|
||||||
|
|
||||||
|
const s = "";
|
||||||
const allChecked = ref(false);
|
const allChecked = ref(false);
|
||||||
const hasChecked = ref(false);
|
const hasChecked = ref(false);
|
||||||
const tableDataSource = ref<any[]>([...props.dataSource]);
|
const tableDataSource = ref<any[]>([...props.dataSource]);
|
||||||
@ -209,6 +211,10 @@ const findFinalNode = (level: number, columns: any[]) => {
|
|||||||
if (!tableHeadColumns.value[level]) {
|
if (!tableHeadColumns.value[level]) {
|
||||||
tableHeadColumns.value[level] = [];
|
tableHeadColumns.value[level] = [];
|
||||||
}
|
}
|
||||||
|
// 如果列固定,并且 width 不存在, 设置默认值
|
||||||
|
if (column.fixed && !column.width) {
|
||||||
|
column.type ? (column.width = "50px") : (column.width = "100px");
|
||||||
|
}
|
||||||
tableHeadColumns.value[level].push(column);
|
tableHeadColumns.value[level].push(column);
|
||||||
findFinalNode(level + 1, column.children);
|
findFinalNode(level + 1, column.children);
|
||||||
} else {
|
} else {
|
||||||
@ -217,6 +223,10 @@ const findFinalNode = (level: number, columns: any[]) => {
|
|||||||
if (!tableHeadColumns.value[level]) {
|
if (!tableHeadColumns.value[level]) {
|
||||||
tableHeadColumns.value[level] = [];
|
tableHeadColumns.value[level] = [];
|
||||||
}
|
}
|
||||||
|
// 如果列固定,并且 width 不存在, 设置默认值
|
||||||
|
if (column.fixed && !column.width) {
|
||||||
|
column.type ? (column.width = "50px") : (column.width = "100px");
|
||||||
|
}
|
||||||
tableHeadColumns.value[level].push(column);
|
tableHeadColumns.value[level].push(column);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -256,6 +266,8 @@ watch(
|
|||||||
() => props.dataSource,
|
() => props.dataSource,
|
||||||
() => {
|
() => {
|
||||||
tableDataSource.value = [...props.dataSource];
|
tableDataSource.value = [...props.dataSource];
|
||||||
|
tableSelectedKeys.value = [];
|
||||||
|
tableSelectedKey.value = s;
|
||||||
nextTick(() => {
|
nextTick(() => {
|
||||||
getScrollWidth();
|
getScrollWidth();
|
||||||
});
|
});
|
||||||
@ -264,17 +276,15 @@ watch(
|
|||||||
);
|
);
|
||||||
|
|
||||||
const changeAll = (isChecked: boolean) => {
|
const changeAll = (isChecked: boolean) => {
|
||||||
// Selected
|
|
||||||
if (isChecked) {
|
if (isChecked) {
|
||||||
const datasources = props.dataSource.filter((item: any, index: number) => {
|
const datasources = props.dataSource.filter((item: any, index: number) => {
|
||||||
return !props.getCheckboxProps(item, index).disabled;
|
return !props.getCheckboxProps(item, index)?.disabled;
|
||||||
});
|
});
|
||||||
const ids = datasources.map((item) => {
|
const ids = datasources.map((item) => {
|
||||||
return item[props.id];
|
return item[props.id];
|
||||||
});
|
});
|
||||||
tableSelectedKeys.value = [...ids];
|
tableSelectedKeys.value = [...ids];
|
||||||
} else {
|
} else {
|
||||||
// unSelected
|
|
||||||
tableSelectedKeys.value = [];
|
tableSelectedKeys.value = [];
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -317,11 +327,12 @@ const rowDoubleClick = function (data: any, evt: MouseEvent) {
|
|||||||
emit("row-double", data, evt);
|
emit("row-double", data, evt);
|
||||||
};
|
};
|
||||||
|
|
||||||
const rowContextmenu = function (data: any, evt: MouseEvent) {
|
const rowContextmenu = (data: any, evt: MouseEvent) => {
|
||||||
emit("row-contextmenu", data, evt);
|
emit("row-contextmenu", data, evt);
|
||||||
};
|
};
|
||||||
|
|
||||||
const print = function () {
|
// 页面打印
|
||||||
|
const print = () => {
|
||||||
let subOutputRankPrint = document.getElementById(tableId) as HTMLElement;
|
let subOutputRankPrint = document.getElementById(tableId) as HTMLElement;
|
||||||
let newContent = subOutputRankPrint.innerHTML;
|
let newContent = subOutputRankPrint.innerHTML;
|
||||||
let oldContent = document.body.innerHTML;
|
let oldContent = document.body.innerHTML;
|
||||||
@ -331,9 +342,7 @@ const print = function () {
|
|||||||
document.body.innerHTML = oldContent;
|
document.body.innerHTML = oldContent;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
// 报表导出
|
||||||
* excel 导出
|
|
||||||
*/
|
|
||||||
const exportData = () => {
|
const exportData = () => {
|
||||||
var tableStr = ``;
|
var tableStr = ``;
|
||||||
for (let tableHeadColumn of tableHeadColumns.value) {
|
for (let tableHeadColumn of tableHeadColumns.value) {
|
||||||
@ -381,11 +390,12 @@ const exportData = () => {
|
|||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
|
||||||
//输出base64编码
|
// BASE64编码
|
||||||
function base64(s: string) {
|
function base64(s: string) {
|
||||||
return window.btoa(unescape(encodeURIComponent(s)));
|
return window.btoa(unescape(encodeURIComponent(s)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 列排序
|
||||||
const sortTable = (e: any, key: string, sort: string) => {
|
const sortTable = (e: any, key: string, sort: string) => {
|
||||||
let currentSort = e.target.parentNode.getAttribute("lay-sort");
|
let currentSort = e.target.parentNode.getAttribute("lay-sort");
|
||||||
if (sort === "desc") {
|
if (sort === "desc") {
|
||||||
@ -437,6 +447,15 @@ const classes = computed(() => {
|
|||||||
];
|
];
|
||||||
});
|
});
|
||||||
|
|
||||||
|
watch(
|
||||||
|
() => [props.height, props.maxHeight, props.dataSource],
|
||||||
|
() => {
|
||||||
|
nextTick(() => {
|
||||||
|
getScrollWidth();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
getScrollWidth();
|
getScrollWidth();
|
||||||
getFixedColumn();
|
getFixedColumn();
|
||||||
@ -504,7 +523,7 @@ const renderFixedStyle = (column: any, columnIndex: number) => {
|
|||||||
props.columns[i].fixed == "left" &&
|
props.columns[i].fixed == "left" &&
|
||||||
tableColumnKeys.value.includes(props.columns[i].key)
|
tableColumnKeys.value.includes(props.columns[i].key)
|
||||||
) {
|
) {
|
||||||
left = left + props.columns[i]?.width.replace("px", "");
|
left = left + props.columns[i]?.width?.replace("px", "");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return { left: `${left}px` } as StyleValue;
|
return { left: `${left}px` } as StyleValue;
|
||||||
@ -516,7 +535,7 @@ const renderFixedStyle = (column: any, columnIndex: number) => {
|
|||||||
props.columns[i].fixed == "right" &&
|
props.columns[i].fixed == "right" &&
|
||||||
tableColumnKeys.value.includes(props.columns[i].key)
|
tableColumnKeys.value.includes(props.columns[i].key)
|
||||||
) {
|
) {
|
||||||
right = right + props.columns[i]?.width.replace("px", "");
|
right = right + props.columns[i]?.width?.replace("px", "");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return { right: `${right}px` } as StyleValue;
|
return { right: `${right}px` } as StyleValue;
|
||||||
@ -592,6 +611,10 @@ const renderTotalRowCell = (column: any) => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
onBeforeUnmount(() => {
|
||||||
|
window.onresize = null;
|
||||||
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
@ -833,24 +856,26 @@ const renderTotalRowCell = (column: any) => {
|
|||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="layui-table-footer" v-if="slot.footer">
|
||||||
|
<slot name="footer"></slot>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div v-if="page" class="layui-table-page">
|
<div v-if="page" class="layui-table-page">
|
||||||
<lay-page
|
<table-page
|
||||||
show-page
|
:show-page="page.showPage"
|
||||||
show-skip
|
:showSkip="page.showSkip"
|
||||||
show-limit
|
:showLimit="page.showLimit"
|
||||||
|
:showCount="page.showCount"
|
||||||
|
:limits="page.limits"
|
||||||
|
:showRefresh="page.showRefresh"
|
||||||
:total="page.total"
|
:total="page.total"
|
||||||
:limit="page.limit"
|
:pages="page.pages"
|
||||||
|
:theme="page.theme"
|
||||||
v-model="page.current"
|
v-model="page.current"
|
||||||
@jump="change"
|
v-model:limit="page.limit"
|
||||||
|
@change="change"
|
||||||
>
|
>
|
||||||
<template #prev>
|
</table-page>
|
||||||
<lay-icon type="layui-icon-left" />
|
|
||||||
</template>
|
|
||||||
<template #next>
|
|
||||||
<lay-icon type="layui-icon-right" />
|
|
||||||
</template>
|
|
||||||
</lay-page>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -5,6 +5,7 @@ export default {
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
|
import { LayIcon } from "@layui/icons-vue";
|
||||||
import { computed } from "vue";
|
import { computed } from "vue";
|
||||||
import "./index.less";
|
import "./index.less";
|
||||||
|
|
||||||
|
@ -21,12 +21,13 @@ import { templateRef } from "@vueuse/core";
|
|||||||
import { LayLayer } from "@layui/layer-vue";
|
import { LayLayer } from "@layui/layer-vue";
|
||||||
import LayButton from "../button/index.vue";
|
import LayButton from "../button/index.vue";
|
||||||
import Cropper from "cropperjs";
|
import Cropper from "cropperjs";
|
||||||
// 组件的参数字段类型
|
import { arrayExpression } from "@babel/types";
|
||||||
//https://www.layuiweb.com/doc/modules/upload.html#options
|
|
||||||
export interface LayerButton {
|
export interface LayerButton {
|
||||||
text: string;
|
text: string;
|
||||||
callback: Function;
|
callback: Function;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface LayerModal {
|
export interface LayerModal {
|
||||||
title?: string;
|
title?: string;
|
||||||
resize?: boolean;
|
resize?: boolean;
|
||||||
@ -46,6 +47,7 @@ export interface LayerModal {
|
|||||||
anim?: boolean;
|
anim?: boolean;
|
||||||
isOutAnim?: boolean;
|
isOutAnim?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface cutOptions {
|
export interface cutOptions {
|
||||||
layerOption: LayerModal;
|
layerOption: LayerModal;
|
||||||
copperOption?: typeof Cropper;
|
copperOption?: typeof Cropper;
|
||||||
@ -55,7 +57,7 @@ export interface LayUploadProps {
|
|||||||
url?: string;
|
url?: string;
|
||||||
data?: any;
|
data?: any;
|
||||||
headers?: Recordable;
|
headers?: Recordable;
|
||||||
acceptMime?: "images" | "file" | "video" | "audio";
|
acceptMime?: string;
|
||||||
field?: string;
|
field?: string;
|
||||||
size?: number;
|
size?: number;
|
||||||
multiple?: boolean;
|
multiple?: boolean;
|
||||||
@ -73,7 +75,6 @@ const getCutDownResult = () => {
|
|||||||
let imgData = canvas.toDataURL('"image/png"');
|
let imgData = canvas.toDataURL('"image/png"');
|
||||||
let currentTimeStamp = new Date().valueOf();
|
let currentTimeStamp = new Date().valueOf();
|
||||||
let orgInfo = activeUploadFiles.value[0];
|
let orgInfo = activeUploadFiles.value[0];
|
||||||
console.log(orgInfo);
|
|
||||||
emit(
|
emit(
|
||||||
"cutdone",
|
"cutdone",
|
||||||
Object.assign({ currentTimeStamp, cutResult: imgData, orginal: orgInfo })
|
Object.assign({ currentTimeStamp, cutResult: imgData, orginal: orgInfo })
|
||||||
@ -111,9 +112,10 @@ let defaultCutLayerOption: LayerModal = {
|
|||||||
shadeClose: true,
|
shadeClose: true,
|
||||||
type: "component",
|
type: "component",
|
||||||
};
|
};
|
||||||
|
|
||||||
const props = withDefaults(defineProps<LayUploadProps>(), {
|
const props = withDefaults(defineProps<LayUploadProps>(), {
|
||||||
acceptMime: "images",
|
|
||||||
field: "file",
|
field: "file",
|
||||||
|
acceptMime: "MIME_type",
|
||||||
size: 0,
|
size: 0,
|
||||||
multiple: false,
|
multiple: false,
|
||||||
number: 0,
|
number: 0,
|
||||||
@ -136,11 +138,8 @@ const emit = defineEmits([
|
|||||||
"cutcancel",
|
"cutcancel",
|
||||||
]);
|
]);
|
||||||
|
|
||||||
// 内部变量
|
|
||||||
const isDragEnter = ref(false);
|
const isDragEnter = ref(false);
|
||||||
// 待处理的上传文件
|
|
||||||
const activeUploadFiles = ref<any[]>([]);
|
const activeUploadFiles = ref<any[]>([]);
|
||||||
// 待处理的上传图片
|
|
||||||
const activeUploadFilesImgs = ref<any[]>([]);
|
const activeUploadFilesImgs = ref<any[]>([]);
|
||||||
const orgFileInput = templateRef<HTMLElement>("orgFileInput");
|
const orgFileInput = templateRef<HTMLElement>("orgFileInput");
|
||||||
let _cropper: any = null;
|
let _cropper: any = null;
|
||||||
@ -153,25 +152,27 @@ if (props.cutOptions && props.cutOptions.layerOption) {
|
|||||||
computedCutLayerOption = computed(() => defaultCutLayerOption);
|
computedCutLayerOption = computed(() => defaultCutLayerOption);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 统一异常提示的常量
|
|
||||||
const defaultErrorMsg = "上传失败";
|
const defaultErrorMsg = "上传失败";
|
||||||
const urlErrorMsg = "上传地址格式不合法";
|
const urlErrorMsg = "上传地址格式不合法";
|
||||||
const numberErrorMsg = "文件上传超过规定的个数";
|
const numberErrorMsg = "文件上传超过规定的个数";
|
||||||
const sizeErrorMsg = "文件大小超过限制";
|
const sizeErrorMsg = "文件大小超过限制";
|
||||||
const uploadRemoteErrorMsg = "请求上传接口出现异常";
|
const uploadRemoteErrorMsg = "请求上传接口出现异常";
|
||||||
const cutInitErrorMsg = "剪裁插件初始化失败";
|
const cutInitErrorMsg = "剪裁插件初始化失败";
|
||||||
// 统一成功提示
|
|
||||||
const uploadSuccess = "上传成功";
|
const uploadSuccess = "上传成功";
|
||||||
|
|
||||||
//内部方法 -> start
|
|
||||||
//文件上传事务流程的方法参数类型
|
|
||||||
interface localUploadTransaction {
|
interface localUploadTransaction {
|
||||||
url: string;
|
url: string;
|
||||||
files: File[] | Blob[];
|
files: File[] | Blob[];
|
||||||
[propMame: string]: any;
|
[propMame: string]: any;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface localUploadOption {
|
||||||
|
url: string;
|
||||||
|
[propMame: string]: any;
|
||||||
|
}
|
||||||
|
|
||||||
const innerCutVisible = ref<boolean>(false);
|
const innerCutVisible = ref<boolean>(false);
|
||||||
|
|
||||||
const localUploadTransaction = (option: localUploadTransaction) => {
|
const localUploadTransaction = (option: localUploadTransaction) => {
|
||||||
const { url, files } = option;
|
const { url, files } = option;
|
||||||
let formData = new FormData();
|
let formData = new FormData();
|
||||||
@ -182,10 +183,9 @@ const localUploadTransaction = (option: localUploadTransaction) => {
|
|||||||
if (Array.isArray(files) && files.length > 0) {
|
if (Array.isArray(files) && files.length > 0) {
|
||||||
for (let i = 0; i < files.length; i++) {
|
for (let i = 0; i < files.length; i++) {
|
||||||
let _file = files[i];
|
let _file = files[i];
|
||||||
formData.append("file[" + i + "]", _file);
|
formData.append(props.field + "[" + i + "]", _file);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// 对应Upload属性的data字段,额外的上传参数
|
|
||||||
if (props.data && props.data instanceof Object) {
|
if (props.data && props.data instanceof Object) {
|
||||||
let _requestDate = props.data;
|
let _requestDate = props.data;
|
||||||
for (const key in _requestDate) {
|
for (const key in _requestDate) {
|
||||||
@ -199,11 +199,6 @@ const localUploadTransaction = (option: localUploadTransaction) => {
|
|||||||
}, 200);
|
}, 200);
|
||||||
};
|
};
|
||||||
|
|
||||||
//单文件上传的方法参数类型
|
|
||||||
interface localUploadOption {
|
|
||||||
url: string;
|
|
||||||
[propMame: string]: any;
|
|
||||||
}
|
|
||||||
const dataURLtoFile = (dataurl: string) => {
|
const dataURLtoFile = (dataurl: string) => {
|
||||||
let arr: any[] = dataurl.split(",");
|
let arr: any[] = dataurl.split(",");
|
||||||
let mime: string = "";
|
let mime: string = "";
|
||||||
@ -234,10 +229,7 @@ const localUpload = (option: localUploadOption, callback: Function) => {
|
|||||||
url = option.url;
|
url = option.url;
|
||||||
let formData = option.formData;
|
let formData = option.formData;
|
||||||
const cb = callback;
|
const cb = callback;
|
||||||
//事件回调
|
|
||||||
// event callbacks
|
|
||||||
xhr.onreadystatechange = function () {
|
xhr.onreadystatechange = function () {
|
||||||
// 发起
|
|
||||||
let currentTimeStamp = new Date().valueOf();
|
let currentTimeStamp = new Date().valueOf();
|
||||||
if (xhr.readyState === 1) {
|
if (xhr.readyState === 1) {
|
||||||
if (
|
if (
|
||||||
@ -252,9 +244,7 @@ const localUpload = (option: localUploadOption, callback: Function) => {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
} else if (xhr.readyState === 4) {
|
} else if (xhr.readyState === 4) {
|
||||||
// 完成
|
|
||||||
let successText = xhr.responseText ? xhr.responseText : uploadSuccess;
|
let successText = xhr.responseText ? xhr.responseText : uploadSuccess;
|
||||||
console.log(xhr);
|
|
||||||
if (
|
if (
|
||||||
(xhr.status >= 200 && xhr.status <= 300) ||
|
(xhr.status >= 200 && xhr.status <= 300) ||
|
||||||
xhr.status === 304 ||
|
xhr.status === 304 ||
|
||||||
@ -265,8 +255,7 @@ const localUpload = (option: localUploadOption, callback: Function) => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
xhr.open("post", url, true); //不能是GET, get请求数据发送只能拼接在URL后面
|
xhr.open("post", url, true);
|
||||||
// 对应Upload属性的headers字段,额外的上传参数
|
|
||||||
if (props.headers) {
|
if (props.headers) {
|
||||||
for (let key in props.headers) {
|
for (let key in props.headers) {
|
||||||
xhr.setRequestHeader(key, props.headers[key]);
|
xhr.setRequestHeader(key, props.headers[key]);
|
||||||
@ -274,7 +263,6 @@ const localUpload = (option: localUploadOption, callback: Function) => {
|
|||||||
} else {
|
} else {
|
||||||
xhr.setRequestHeader("Accept", "application/json, text/javascript");
|
xhr.setRequestHeader("Accept", "application/json, text/javascript");
|
||||||
}
|
}
|
||||||
// 上传事务开启前的回调
|
|
||||||
let currentTimeStamp = new Date().valueOf();
|
let currentTimeStamp = new Date().valueOf();
|
||||||
emit("before", Object.assign(option, currentTimeStamp));
|
emit("before", Object.assign(option, currentTimeStamp));
|
||||||
xhr.send(formData);
|
xhr.send(formData);
|
||||||
@ -282,6 +270,7 @@ const localUpload = (option: localUploadOption, callback: Function) => {
|
|||||||
cb();
|
cb();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const filetoDataURL = (file: File, fn: Function) => {
|
const filetoDataURL = (file: File, fn: Function) => {
|
||||||
const reader = new FileReader();
|
const reader = new FileReader();
|
||||||
reader.onloadend = function (e: any) {
|
reader.onloadend = function (e: any) {
|
||||||
@ -289,15 +278,14 @@ const filetoDataURL = (file: File, fn: Function) => {
|
|||||||
};
|
};
|
||||||
reader.readAsDataURL(file);
|
reader.readAsDataURL(file);
|
||||||
};
|
};
|
||||||
|
|
||||||
const getUploadChange = (e: any) => {
|
const getUploadChange = (e: any) => {
|
||||||
const files = e.target.files;
|
const files = e.target.files;
|
||||||
const _files = [...files];
|
const _files = [...files];
|
||||||
// 对应Upload属性的number字段,控制单次上传个数
|
|
||||||
if (props.multiple && props.number != 0 && props.number < _files.length) {
|
if (props.multiple && props.number != 0 && props.number < _files.length) {
|
||||||
errorF(numberErrorMsg);
|
errorF(numberErrorMsg);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// 对应Upload属性的size字段,控制上传图片的大小
|
|
||||||
if (props.size && props.size != 0) {
|
if (props.size && props.size != 0) {
|
||||||
let _cache = [];
|
let _cache = [];
|
||||||
for (let i = 0; i < _files.length; i++) {
|
for (let i = 0; i < _files.length; i++) {
|
||||||
@ -324,8 +312,14 @@ const getUploadChange = (e: any) => {
|
|||||||
activeUploadFilesImgs.value.push(res);
|
activeUploadFilesImgs.value.push(res);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
let arm1 = props.cut && props.acceptMime == "images" && !props.multiple;
|
let arm1 =
|
||||||
let arm2 = props.cut && props.acceptMime == "images" && props.multiple;
|
props.cut &&
|
||||||
|
props.acceptMime.indexOf("image") != -1 &&
|
||||||
|
props.multiple == false;
|
||||||
|
let arm2 =
|
||||||
|
props.cut &&
|
||||||
|
props.acceptMime.indexOf("image") != -1 &&
|
||||||
|
props.multiple == true;
|
||||||
if (arm1) {
|
if (arm1) {
|
||||||
innerCutVisible.value = true;
|
innerCutVisible.value = true;
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
@ -339,12 +333,13 @@ const getUploadChange = (e: any) => {
|
|||||||
} else {
|
} else {
|
||||||
if (arm2) {
|
if (arm2) {
|
||||||
console.warn(
|
console.warn(
|
||||||
"layui-vue:当前版本暂不支持单次多文件剪裁,尝试设置 multiple 为false,通过@done获取返回文件对象"
|
"当前版本暂不支持单次多文件剪裁,尝试设置 multiple 为 false, 通过 @done 获取返回文件对象"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
commonUploadTransaction(_files);
|
commonUploadTransaction(_files);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const commonUploadTransaction = (_files: any[]) => {
|
const commonUploadTransaction = (_files: any[]) => {
|
||||||
let currentTimeStamp = new Date().valueOf();
|
let currentTimeStamp = new Date().valueOf();
|
||||||
let successText = uploadSuccess;
|
let successText = uploadSuccess;
|
||||||
@ -357,16 +352,19 @@ const commonUploadTransaction = (_files: any[]) => {
|
|||||||
emit("done", { currentTimeStamp, msg: successText, data: _files });
|
emit("done", { currentTimeStamp, msg: successText, data: _files });
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const chooseFile = () => {
|
const chooseFile = () => {
|
||||||
let _target = orgFileInput.value;
|
let _target = orgFileInput.value;
|
||||||
if (_target) {
|
if (_target) {
|
||||||
_target.click();
|
_target.click();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const clickOrgInput = () => {
|
const clickOrgInput = () => {
|
||||||
let currentTimeStamp = new Date().valueOf();
|
let currentTimeStamp = new Date().valueOf();
|
||||||
emit("choose", currentTimeStamp);
|
emit("choose", currentTimeStamp);
|
||||||
};
|
};
|
||||||
|
|
||||||
const cutTransaction = () => {};
|
const cutTransaction = () => {};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
@ -61,7 +61,6 @@ import LayDropdownSubMenu from "./component/dropdownSubMenu/index";
|
|||||||
import LayTab from "./component/tab/index";
|
import LayTab from "./component/tab/index";
|
||||||
import LayTabItem from "./component/tabItem/index";
|
import LayTabItem from "./component/tabItem/index";
|
||||||
import LayTree from "./component/tree/index";
|
import LayTree from "./component/tree/index";
|
||||||
import LayTreeSelect from "./component/treeSelect/index";
|
|
||||||
import LayTable from "./component/table/index";
|
import LayTable from "./component/table/index";
|
||||||
import LayPage from "./component/page/index";
|
import LayPage from "./component/page/index";
|
||||||
import LayTransfer from "./component/transfer/index";
|
import LayTransfer from "./component/transfer/index";
|
||||||
@ -89,8 +88,7 @@ import LayNoticeBar from "./component/noticeBar/index";
|
|||||||
import LayPageHeader from "./component/pageHeader/index";
|
import LayPageHeader from "./component/pageHeader/index";
|
||||||
import LayCascader from "./component/cascader/index";
|
import LayCascader from "./component/cascader/index";
|
||||||
import LayAffix from "./component/affix/index";
|
import LayAffix from "./component/affix/index";
|
||||||
import LayTag from "./component/tag/index";
|
import LaySpace from "./component/space/index";
|
||||||
import LayTagInput from "./component/tagInput/index";
|
|
||||||
import LayConfigProvider from "./provider";
|
import LayConfigProvider from "./provider";
|
||||||
import { InstallOptions } from "./types";
|
import { InstallOptions } from "./types";
|
||||||
|
|
||||||
@ -149,7 +147,6 @@ const components: Record<string, Plugin> = {
|
|||||||
LayTabItem,
|
LayTabItem,
|
||||||
LayIconPicker,
|
LayIconPicker,
|
||||||
LayTree,
|
LayTree,
|
||||||
LayTreeSelect,
|
|
||||||
LayTable,
|
LayTable,
|
||||||
LayPage,
|
LayPage,
|
||||||
LayTransfer,
|
LayTransfer,
|
||||||
@ -178,8 +175,7 @@ const components: Record<string, Plugin> = {
|
|||||||
LayPageHeader,
|
LayPageHeader,
|
||||||
LayCascader,
|
LayCascader,
|
||||||
LayAffix,
|
LayAffix,
|
||||||
LayTag,
|
LaySpace,
|
||||||
LayTagInput,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const install = (app: App, options?: InstallOptions): void => {
|
const install = (app: App, options?: InstallOptions): void => {
|
||||||
@ -245,7 +241,6 @@ export {
|
|||||||
LayTabItem,
|
LayTabItem,
|
||||||
LayIconPicker,
|
LayIconPicker,
|
||||||
LayTree,
|
LayTree,
|
||||||
LayTreeSelect,
|
|
||||||
LayTable,
|
LayTable,
|
||||||
LayPage,
|
LayPage,
|
||||||
LayTransfer,
|
LayTransfer,
|
||||||
@ -274,8 +269,7 @@ export {
|
|||||||
LayPageHeader,
|
LayPageHeader,
|
||||||
LayCascader,
|
LayCascader,
|
||||||
LayAffix,
|
LayAffix,
|
||||||
LayTag,
|
LaySpace,
|
||||||
LayTagInput,
|
|
||||||
install,
|
install,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -55,6 +55,9 @@ export default {
|
|||||||
<template v-slot:body>
|
<template v-slot:body>
|
||||||
内容
|
内容
|
||||||
</template>
|
</template>
|
||||||
|
<template v-slot:footer>
|
||||||
|
底部
|
||||||
|
</template>
|
||||||
</lay-card>
|
</lay-card>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@ -213,12 +216,13 @@ export default {
|
|||||||
|
|
||||||
::: table
|
::: table
|
||||||
|
|
||||||
| 插槽 | 描述 | 可选值 |
|
| 插槽 | 描述 | 可选值 | 版本 |
|
||||||
| ------- | -------- | ------ |
|
| ------- | -------- | ------ |------ |
|
||||||
| default | 默认插槽 | -- |
|
| default | 默认插槽 | -- |-- |
|
||||||
| header | 头部插槽 | -- |
|
| header | 头部插槽 | -- |-- |
|
||||||
| body | 内容插槽 | -- |
|
| body | 内容插槽 | -- |-- |
|
||||||
| extra | 扩展插槽 | -- |
|
| extra | 扩展插槽 | -- |-- |
|
||||||
|
| footer | 扩展插槽 | -- |`1.4.3`|
|
||||||
:::
|
:::
|
||||||
|
|
||||||
::: contributor card
|
::: contributor card
|
||||||
|
@ -49,7 +49,7 @@ import { ref } from 'vue'
|
|||||||
export default {
|
export default {
|
||||||
setup() {
|
setup() {
|
||||||
|
|
||||||
const endTime2 = ref("2022-06-04 17:35:00");
|
const endTime2 = ref("");
|
||||||
|
|
||||||
return {
|
return {
|
||||||
endTime2
|
endTime2
|
||||||
@ -254,15 +254,17 @@ const rangeTime3 = ref(['2022-01-01','2023-02-1']);
|
|||||||
|
|
||||||
::: table
|
::: table
|
||||||
|
|
||||||
| 属性 | 描述 | 类型 | 默认值 | 可选值 |
|
| 属性 | 描述 | 类型 | 默认值 | 可选值 | 版本 |
|
||||||
| ------------- | ------------------------------------------------------------ | -------------- | ------ | -------------- |
|
| ------------- | ------------------------------------------------------------ | -------------- | ------ | -------------- |-------------- |
|
||||||
| v-model | 当前时间 | `string` | -- | — |
|
| v-model | 当前时间 | `string` | -- | -- | -- |
|
||||||
| type | 选择类型 | `string` | `date` | `date` `datetime` `year` `month` `time` `yearmonth` |
|
| type | 选择类型 | `string` | `date` | `date` `datetime` `year` `month` `time` `yearmonth` | -- |
|
||||||
| disabled | 是否禁止修改 | `boolean` | false | — |
|
| disabled | 是否禁止修改 | `boolean` | false | — | — |
|
||||||
| simple | 一次性选择,无需点击确认按钮 | `boolean` | false | — |
|
| simple | 一次性选择,无需点击确认按钮 | `boolean` | false | -- | -- |
|
||||||
| readonly | 只读 | `boolean` | false | — |
|
| readonly | 只读 | `boolean` | false | -- | -- |
|
||||||
| allowClear | 允许清空 | `boolean` | true | — |
|
| allowClear | 允许清空 | `boolean` | true | -- | -- |
|
||||||
| size | 尺寸 | `string` | `lg` `md` `sm` `xs` | `md` |
|
| size | 尺寸 | `string` | `lg` `md` `sm` `xs` | `md` | -- |
|
||||||
|
| prefix-icon | 前置图标 | `string` | `layui-icon-date` | 内置图标集 | `1.4.0` |
|
||||||
|
| suffix-icon | 后置图标 | `string` | -- | 内置图标集 | `1.4.0` |
|
||||||
|
|
||||||
:::
|
:::
|
||||||
|
|
||||||
|
@ -120,7 +120,7 @@ export default {
|
|||||||
::: demo
|
::: demo
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<lay-button @click="manualRef.open()">打开</lay-button>
|
<lay-button @click="manualRef.show()">打开</lay-button>
|
||||||
<lay-button @click="manualRef.hide()">关闭</lay-button>
|
<lay-button @click="manualRef.hide()">关闭</lay-button>
|
||||||
<br><br>
|
<br><br>
|
||||||
<lay-dropdown ref="manualRef" :clickOutsideToClose="false" :clickToClose="false" updateAtScroll>
|
<lay-dropdown ref="manualRef" :clickOutsideToClose="false" :clickToClose="false" updateAtScroll>
|
||||||
@ -222,7 +222,7 @@ export default {
|
|||||||
::: demo
|
::: demo
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<lay-dropdown @open="stat='开启'" @hide="stat='关闭'" updateAtScroll>
|
<lay-dropdown @show="stat='开启'" @hide="stat='关闭'" updateAtScroll>
|
||||||
<lay-button type="primary" >当前状态:{{stat}}</lay-button>
|
<lay-button type="primary" >当前状态:{{stat}}</lay-button>
|
||||||
<template #content>
|
<template #content>
|
||||||
<lay-dropdown-menu>
|
<lay-dropdown-menu>
|
||||||
@ -516,42 +516,11 @@ export default {
|
|||||||
<lay-dropdown-menu-item>选项三</lay-dropdown-menu-item>
|
<lay-dropdown-menu-item>选项三</lay-dropdown-menu-item>
|
||||||
</lay-dropdown-menu>
|
</lay-dropdown-menu>
|
||||||
</template>
|
</template>
|
||||||
</lay-dropdown>
|
|
||||||
|
|
||||||
<br><br>
|
|
||||||
<lay-button @click="triggerHeight += 100">改变触发器尺寸</lay-button>
|
|
||||||
<lay-button @click="contentHeight += 100">改变面板尺寸</lay-button>
|
|
||||||
<br><br>
|
|
||||||
<lay-dropdown placement="bottom-left" trigger="focus" :autoFitPosition="true" :autoFixPosition="true" :blurToClose="false" :clickOutsideToClose="false" updateAtScroll>
|
|
||||||
<lay-input placeholder="autoFixPosition" :style="{height: triggerHeight + 'px'}"></lay-input>
|
|
||||||
<template #content>
|
|
||||||
<div :style="{width:'350px', height: contentHeight + 'px'}"></div>
|
|
||||||
</template>
|
|
||||||
</lay-dropdown>
|
</lay-dropdown>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script setup>
|
||||||
import { ref, computed } from 'vue'
|
import { ref, computed } from 'vue'
|
||||||
|
|
||||||
export default {
|
|
||||||
setup() {
|
|
||||||
|
|
||||||
const btnSize = ref('')
|
|
||||||
const toogleSize = () => {
|
|
||||||
btnSize.value = btnSize.value ? '' : 'lg'
|
|
||||||
}
|
|
||||||
|
|
||||||
const triggerHeight = ref(100)
|
|
||||||
const contentHeight = ref(200)
|
|
||||||
|
|
||||||
return {
|
|
||||||
btnSize,
|
|
||||||
toogleSize,
|
|
||||||
triggerWidth,
|
|
||||||
triggerStyle,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
:::
|
:::
|
||||||
@ -576,6 +545,9 @@ export default {
|
|||||||
| blurToClose | 是否在触发器失去焦点时关闭面板,默认 `true` |`true` `false`|
|
| blurToClose | 是否在触发器失去焦点时关闭面板,默认 `true` |`true` `false`|
|
||||||
| clickOutsideToClose| 是否点击外部关闭下拉面板,默认 `true`|`true` `false`|
|
| clickOutsideToClose| 是否点击外部关闭下拉面板,默认 `true`|`true` `false`|
|
||||||
| contentOffset | 下拉面板距离触发器的偏移距离,默认 2| -|
|
| contentOffset | 下拉面板距离触发器的偏移距离,默认 2| -|
|
||||||
|
| mouseEnterDelay | mouseEnter 事件延迟触发的时间, trigger hover 有效 | - |
|
||||||
|
| mouseLeaveDelay | mouseLeave 事件延迟触发的时间, trigger hover 有效| - |
|
||||||
|
| focusDelay| focus 事件延迟触发的时间, trigger focus 有效 | - |
|
||||||
|
|
||||||
|
|
||||||
:::
|
:::
|
||||||
@ -599,8 +571,8 @@ export default {
|
|||||||
|
|
||||||
| 插槽 | 描述 | 参数 |
|
| 插槽 | 描述 | 参数 |
|
||||||
| ------- | -------- | ------ |
|
| ------- | -------- | ------ |
|
||||||
| hide | 隐藏下拉内容后触发 | -- |
|
| hide | 隐藏下拉面板后触发 | -- |
|
||||||
| open | 显示下拉内容后触发 | -- |
|
| show | 显示下拉面板后触发 | -- |
|
||||||
|
|
||||||
:::
|
:::
|
||||||
|
|
||||||
|
@ -142,7 +142,7 @@ export default {
|
|||||||
|
|
||||||
:::
|
:::
|
||||||
|
|
||||||
::: title 表单基本校验功能
|
::: title 表单验证
|
||||||
:::
|
:::
|
||||||
|
|
||||||
::: demo
|
::: demo
|
||||||
@ -231,7 +231,7 @@ export default {
|
|||||||
|
|
||||||
:::
|
:::
|
||||||
|
|
||||||
::: title 校验规则 - 通过表单配置
|
::: title 校验规则
|
||||||
:::
|
:::
|
||||||
|
|
||||||
::: demo
|
::: demo
|
||||||
|
@ -735,6 +735,18 @@ export default {
|
|||||||
|
|
||||||
:::
|
:::
|
||||||
|
|
||||||
|
::: title Menu 事件
|
||||||
|
:::
|
||||||
|
|
||||||
|
::: table
|
||||||
|
|
||||||
|
| 属性 | 描述 | 参数 |
|
||||||
|
| ------------------- | ------------------- | -------------- |
|
||||||
|
| changeSelectedKey | 选中菜单回调 | value: string |
|
||||||
|
| changeOpenKeys | 展开目录回调 | value: string[] |
|
||||||
|
|
||||||
|
:::
|
||||||
|
|
||||||
::: title Menu Item 属性
|
::: title Menu Item 属性
|
||||||
:::
|
:::
|
||||||
|
|
||||||
|
@ -13,7 +13,7 @@
|
|||||||
::: demo 使用 `lay-page` 标签, 创建分页
|
::: demo 使用 `lay-page` 标签, 创建分页
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<lay-page v-model="currentPage" :limit="limit" @limit="limit = $event" :total="total" :show-page="showPage"></lay-page>
|
<lay-page v-model="currentPage" :limit="limit" :total="total" :show-page="true"></lay-page>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
@ -24,13 +24,11 @@ export default {
|
|||||||
|
|
||||||
const limit = ref(20)
|
const limit = ref(20)
|
||||||
const total = ref(100)
|
const total = ref(100)
|
||||||
const showPage = ref(true)
|
|
||||||
const currentPage = ref(2);
|
const currentPage = ref(2);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
limit,
|
limit,
|
||||||
total,
|
total,
|
||||||
showPage,
|
|
||||||
currentPage
|
currentPage
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -39,13 +37,13 @@ export default {
|
|||||||
|
|
||||||
:::
|
:::
|
||||||
|
|
||||||
::: title 简单模式
|
::: title 简洁模式
|
||||||
:::
|
:::
|
||||||
|
|
||||||
::: demo
|
::: demo
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<lay-page :limit="limit" @limit="limit = $event" :total="total"></lay-page>
|
<lay-page :limit="limit1" v-model="current1" :total="total1"></lay-page>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
@ -54,12 +52,14 @@ import { ref } from 'vue'
|
|||||||
export default {
|
export default {
|
||||||
setup() {
|
setup() {
|
||||||
|
|
||||||
const limit = ref(20)
|
const limit1 = ref(10);
|
||||||
const total = ref(100)
|
const total1 = ref(100);
|
||||||
|
const current1 = ref(1);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
limit,
|
limit1,
|
||||||
total
|
total1,
|
||||||
|
current1
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -67,16 +67,13 @@ export default {
|
|||||||
|
|
||||||
:::
|
:::
|
||||||
|
|
||||||
::: title 插槽使用
|
::: title 设置主题
|
||||||
:::
|
:::
|
||||||
|
|
||||||
::: demo
|
::: demo
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<lay-page :limit="limit" @limit="limit = $event" :total="total">
|
<lay-page :limit="limit2" :total="total2" :show-page="true" theme="blue"></lay-page>
|
||||||
<template v-slot:prev>上</template>
|
|
||||||
<template v-slot:next>下</template>
|
|
||||||
</lay-page>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
@ -85,12 +82,12 @@ import { ref } from 'vue'
|
|||||||
export default {
|
export default {
|
||||||
setup() {
|
setup() {
|
||||||
|
|
||||||
const limit = ref(20)
|
const limit2 = ref(20)
|
||||||
const total = ref(100)
|
const total2 = ref(100)
|
||||||
|
|
||||||
return {
|
return {
|
||||||
limit,
|
limit2,
|
||||||
total
|
total2,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -98,17 +95,13 @@ export default {
|
|||||||
|
|
||||||
:::
|
:::
|
||||||
|
|
||||||
::: title 不同主题
|
::: title 分页容量
|
||||||
:::
|
:::
|
||||||
|
|
||||||
::: demo
|
::: demo
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<lay-page :limit="limit" @limit="limit = $event" :total="total" :show-page="showPage" theme="red"></lay-page>
|
<lay-page :limit="limit3" :total="total3" showCount showPage :limits="limits3"></lay-page>
|
||||||
<br>
|
|
||||||
<lay-page :limit="limit" @limit="limit = $event" :total="total" :show-page="showPage" theme="blue"></lay-page>
|
|
||||||
<br>
|
|
||||||
<lay-page :limit="limit" @limit="limit = $event" :total="total" :show-page="showPage" theme="orange"></lay-page>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
@ -117,14 +110,14 @@ import { ref } from 'vue'
|
|||||||
export default {
|
export default {
|
||||||
setup() {
|
setup() {
|
||||||
|
|
||||||
const limit = ref(20)
|
const limit3 = ref(5)
|
||||||
const total = ref(100)
|
const total3 = ref(100)
|
||||||
const showPage = ref(true)
|
const limits3 = ref([5, 10, 50, 100, 200])
|
||||||
|
|
||||||
return {
|
return {
|
||||||
limit,
|
limit3,
|
||||||
total,
|
total3,
|
||||||
showPage
|
limits3
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -132,58 +125,33 @@ export default {
|
|||||||
|
|
||||||
:::
|
:::
|
||||||
|
|
||||||
::: title 指定分页容量
|
|
||||||
|
::: title 回调事件
|
||||||
:::
|
:::
|
||||||
|
|
||||||
::: demo
|
::: demo
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<lay-page :limit="limit" :total="total" showCount showPage :limits="[10,50,100,200]" @limit="limit=$event"></lay-page>
|
<lay-page :limit="limit4" :total="total4" @change="change4" :show-page="true"></lay-page>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { ref } from 'vue'
|
import { ref } from 'vue'
|
||||||
|
import { layer } from "@layui/layui-vue";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
setup() {
|
setup() {
|
||||||
|
|
||||||
const limit = ref(20)
|
const limit4 = ref(20)
|
||||||
const total = ref(100)
|
const total4 = ref(100)
|
||||||
|
const change4 = ({ current, limit }) => {
|
||||||
|
layer.msg("current:" + current + " limit:" + limit);
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
limit,
|
limit4,
|
||||||
total
|
total4,
|
||||||
}
|
change4
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
:::
|
|
||||||
|
|
||||||
::: title 每页数量切换事件(limit)
|
|
||||||
:::
|
|
||||||
|
|
||||||
::: demo
|
|
||||||
|
|
||||||
<template>
|
|
||||||
<lay-page :limit="limit" showPage showCount :total="total" @limit="limit=$event" :show-limit="showLimit" ></lay-page>
|
|
||||||
<div>每页数量:{{limit}}</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import { ref } from 'vue'
|
|
||||||
|
|
||||||
export default {
|
|
||||||
setup() {
|
|
||||||
|
|
||||||
const limit = ref(5)
|
|
||||||
const total = ref(9999)
|
|
||||||
const showLimit = ref(true)
|
|
||||||
|
|
||||||
return {
|
|
||||||
limit,
|
|
||||||
total,
|
|
||||||
showLimit,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -197,8 +165,12 @@ export default {
|
|||||||
::: demo
|
::: demo
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<lay-page :limit="limit1" :pages="pages1" :total="total1" :show-count="showCount1" @limit="limit1=$event" :show-page="showPage1" :show-limit="showLimit1" :show-refresh="showRefresh1" :showSkip="showSkip1"></lay-page>
|
<lay-button-container>
|
||||||
每页数量:{{limit1}}
|
<lay-button type="primary" size="sm" @click="changeCurrent5">update model {{ current5 }}</lay-button>
|
||||||
|
<lay-button type="primary" size="sm" @click="changeLimit5">update limit {{ limit5 }}</lay-button>
|
||||||
|
</lay-button-container>
|
||||||
|
<br/>
|
||||||
|
<lay-page v-model="current5" v-model:limit="limit5" :pages="pages5" :total="total5" :show-count="true" :show-page="true" :show-limit="true" :show-refresh="true" :showSkip="true" @change="change5"></lay-page>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
@ -207,60 +179,27 @@ import { ref } from 'vue'
|
|||||||
export default {
|
export default {
|
||||||
setup() {
|
setup() {
|
||||||
|
|
||||||
const limit1 = ref(5)
|
const limit5 = ref(10)
|
||||||
const total1 = ref(99)
|
const total5 = ref(99)
|
||||||
const showCount1 = ref(true)
|
const pages5 = ref(6);
|
||||||
const showPage1 = ref(true)
|
const current5 = ref(1);
|
||||||
const showLimit1 = ref(true)
|
const changeCurrent5 = () => {
|
||||||
const showRefresh1 = ref(true)
|
current5.value = 2;
|
||||||
const showSkip1 = ref(true)
|
}
|
||||||
const pages1 = ref(6);
|
const changeLimit5 = () => {
|
||||||
|
limit5.value = 20;
|
||||||
|
}
|
||||||
|
const change5 = ({ current, limit }) => {
|
||||||
|
layer.msg("current:" + current + " limit:" + limit);
|
||||||
|
}
|
||||||
return {
|
return {
|
||||||
limit1,
|
limit5,
|
||||||
total1,
|
total5,
|
||||||
pages1,
|
pages5,
|
||||||
showCount1,
|
current5,
|
||||||
showPage1,
|
changeCurrent5,
|
||||||
showLimit1,
|
changeLimit5,
|
||||||
showRefresh1,
|
change5
|
||||||
showSkip1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
:::
|
|
||||||
|
|
||||||
::: title 页码切换事件(jump)
|
|
||||||
:::
|
|
||||||
|
|
||||||
::: demo
|
|
||||||
|
|
||||||
<template>
|
|
||||||
<lay-page :limit="limit" :total="total" @jump="jump" @limit="limit = $event" :show-page="showSkip"></lay-page>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import { ref } from 'vue'
|
|
||||||
|
|
||||||
export default {
|
|
||||||
setup() {
|
|
||||||
|
|
||||||
const limit = ref(20)
|
|
||||||
const total = ref(100)
|
|
||||||
const showPage = ref(true)
|
|
||||||
const showSkip = ref(true)
|
|
||||||
const jump = function({ current }) {
|
|
||||||
console.log("当前页:" + current)
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
limit,
|
|
||||||
total,
|
|
||||||
jump,
|
|
||||||
showPage,
|
|
||||||
showSkip
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -294,10 +233,11 @@ export default {
|
|||||||
|
|
||||||
::: table
|
::: table
|
||||||
|
|
||||||
| 事件 | 描述 | 参数 |
|
| 事件 | 描述 | 参数 | 版本 |
|
||||||
| ---- | -------- | --------------------- |
|
| ---- | -------- | --------------------- |--------------------- |
|
||||||
| jump | 切换回调 | { current: 当前页面 } |
|
| jump | 切换回调 | { current: 当前页面 } | `移除` |
|
||||||
| limit | 每页数量变化 | 变化后的值 |
|
| limit | 每页数量变化 | 变化后的值 | `移除` |
|
||||||
|
| change | 分页事件 | { current: 当前页码, limit: 每页数量 } | `1.4.3` |
|
||||||
|
|
||||||
:::
|
:::
|
||||||
|
|
||||||
|
@ -13,8 +13,10 @@
|
|||||||
::: demo 使用 `lay-scroll` 标签, 创建一个虚拟滚动容器
|
::: demo 使用 `lay-scroll` 标签, 创建一个虚拟滚动容器
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
|
<lay-button @click="changeTotal">修改数据</lay-button>
|
||||||
|
<lay-button @click="changeMaxTotal">修改数据</lay-button>
|
||||||
<lay-scroll height="200px" style="background-color:whitesmoke;">
|
<lay-scroll height="200px" style="background-color:whitesmoke;">
|
||||||
<lay-panel v-for="(n,index) in 50" :key="n" style="margin:10px;padding:10px;">内容</lay-panel>
|
<lay-panel v-for="(n,index) in total" :key="n" style="margin:10px;padding:10px;">内容</lay-panel>
|
||||||
</lay-scroll>
|
</lay-scroll>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@ -23,8 +25,20 @@ import { ref } from 'vue'
|
|||||||
|
|
||||||
export default {
|
export default {
|
||||||
setup() {
|
setup() {
|
||||||
|
const total = ref(50);
|
||||||
|
|
||||||
|
const changeTotal = () => {
|
||||||
|
total.value = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
const changeMaxTotal = () => {
|
||||||
|
total.value = 50;
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
total,
|
||||||
|
changeTotal,
|
||||||
|
changeMaxTotal
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,245 @@
|
|||||||
|
::: anchor
|
||||||
|
:::
|
||||||
|
|
||||||
|
::: title 基本介绍
|
||||||
|
:::
|
||||||
|
|
||||||
|
::: describe 控制组件之间的间距。
|
||||||
|
:::
|
||||||
|
|
||||||
|
::: title 基础使用
|
||||||
|
:::
|
||||||
|
|
||||||
|
::: demo 默认横向排列,控制相邻组件的水平间距
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<lay-space>
|
||||||
|
<lay-button v-for="idx of 5" type="normal">按钮 {{idx}}</lay-button>
|
||||||
|
</lay-space>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { ref } from 'vue'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
setup() {
|
||||||
|
|
||||||
|
return {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
:::
|
||||||
|
|
||||||
|
|
||||||
|
::: title 垂直方向
|
||||||
|
:::
|
||||||
|
|
||||||
|
::: demo 通过 `direction="vertical"` 设置垂直方向
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<lay-space direction="vertical" fill wrap>
|
||||||
|
<lay-button v-for="idx of 5" type="normal" fluid="true">按钮 {{idx}}</lay-button>
|
||||||
|
</lay-space>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { ref } from 'vue'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
setup() {
|
||||||
|
|
||||||
|
return {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
:::
|
||||||
|
|
||||||
|
|
||||||
|
::: title 间距大小
|
||||||
|
:::
|
||||||
|
|
||||||
|
::: demo 通过 `size` 控制组件大小 `xs, sm, md , lg`, 分别对应 `4px, 8px, 16px, 24px` 的间距,默认`md`。`size` 也支持通过数组设置间距 `[row-gap, column-gap]`
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<lay-radio
|
||||||
|
v-for="sizeKey of sizeKeys"
|
||||||
|
v-model="sizeSelected"
|
||||||
|
name="action"
|
||||||
|
:value="sizeKey"
|
||||||
|
@change="changeSize">
|
||||||
|
{{sizeKey}}
|
||||||
|
</lay-radio>
|
||||||
|
<br><br>
|
||||||
|
<lay-space :size="spaceSize">
|
||||||
|
<lay-button v-for="idx of 5" type="normal">按钮 {{idx}}</lay-button>
|
||||||
|
</lay-space>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { ref } from 'vue'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
setup() {
|
||||||
|
const sizeKeys = ["xs","sm","md","lg"];
|
||||||
|
const spaceSize = ref();
|
||||||
|
|
||||||
|
const sizeSelected = ref("sm");
|
||||||
|
const changeSize = function( key ) {
|
||||||
|
spaceSize.value = key;
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
sizeSelected,
|
||||||
|
changeSize,
|
||||||
|
spaceSize,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
:::
|
||||||
|
|
||||||
|
|
||||||
|
::: title 自定义间距大小
|
||||||
|
:::
|
||||||
|
|
||||||
|
::: demo
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<lay-slider v-model="customSize"></lay-slider>
|
||||||
|
<br><br>
|
||||||
|
<lay-space :size="customSize">
|
||||||
|
<lay-button v-for="idx of 5" type="normal">按钮 {{idx}}</lay-button>
|
||||||
|
</lay-space>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { ref } from 'vue'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
setup() {
|
||||||
|
const customSize = ref(8);
|
||||||
|
|
||||||
|
return {
|
||||||
|
customSize,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
:::
|
||||||
|
|
||||||
|
|
||||||
|
::: title 对齐方式
|
||||||
|
:::
|
||||||
|
|
||||||
|
::: demo
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<lay-radio
|
||||||
|
v-for="alignKey of alignKeys"
|
||||||
|
v-model="alignSelected"
|
||||||
|
name="action"
|
||||||
|
:value="alignKey"
|
||||||
|
@change="changeAlign">
|
||||||
|
{{alignKey}}
|
||||||
|
</lay-radio>
|
||||||
|
<br><br>
|
||||||
|
<lay-space :align="spaceAlign" style="backgroundColor: whitesmoke;padding: 10px;">
|
||||||
|
<span>Space:</span>
|
||||||
|
<lay-button>默认按钮</lay-button>
|
||||||
|
<lay-card title="标题">
|
||||||
|
内容
|
||||||
|
</lay-card>
|
||||||
|
</lay-space>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { ref } from 'vue'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
setup() {
|
||||||
|
const alignKeys = ["start", "center","end","baseline"];
|
||||||
|
const spaceAlign = ref();
|
||||||
|
|
||||||
|
const alignSelected = ref("center");
|
||||||
|
const changeAlign = function( key ) {
|
||||||
|
spaceAlign.value = key;
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
alignSelected,
|
||||||
|
changeAlign,
|
||||||
|
spaceAlign,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
:::
|
||||||
|
|
||||||
|
|
||||||
|
::: title 自动换行
|
||||||
|
:::
|
||||||
|
|
||||||
|
::: demo
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<lay-space wrap :size="[16,24]">
|
||||||
|
<lay-button v-for="_ of 20">默认按钮{{_}}</lay-button>
|
||||||
|
</lay-space>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { ref } from 'vue'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
setup() {
|
||||||
|
|
||||||
|
return {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
:::
|
||||||
|
|
||||||
|
|
||||||
|
::: title Space 属性
|
||||||
|
:::
|
||||||
|
|
||||||
|
::: table
|
||||||
|
|
||||||
|
| 属性 | 描述 | 类型 | 默认值 | 可选值 |
|
||||||
|
| ----------- | -------- | ------ | ------ | ------ |
|
||||||
|
| align | 对齐方式 | string| `center`| `start` `end` `center` `baseline`|
|
||||||
|
| direction | 间距方向 | string | `horizontal` | `horizontal` `vertical`|
|
||||||
|
| fill | 子元素是否填充父容器 | boolean| `false`| -|
|
||||||
|
| size | 间距大小 | string | md | `lg` `md` `sm` `xs` `number` `string` `[spaceSize,spaceSize]`|
|
||||||
|
| wrap | 是否自动折行 | boolean| `false`| -|
|
||||||
|
|
||||||
|
:::
|
||||||
|
|
||||||
|
>`type spaceSize = "lg" | "md" | "sm" | "xs" | number | string`
|
||||||
|
|
||||||
|
> `[row-gap, column-gap], eg: ['xs','md'] ['10px', '15px'] [10, 15]`
|
||||||
|
|
||||||
|
:::title Space 插槽
|
||||||
|
:::
|
||||||
|
|
||||||
|
:::table
|
||||||
|
| 插槽 | 描述 | 参数 |
|
||||||
|
|------ |----------|-----------|
|
||||||
|
| default | 默认插槽 | - |
|
||||||
|
:::
|
||||||
|
|
||||||
|
|
||||||
|
::: contributor space
|
||||||
|
:::
|
||||||
|
|
||||||
|
::: previousNext space
|
||||||
|
:::
|
@ -119,23 +119,26 @@ export default {
|
|||||||
::: demo
|
::: demo
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
|
page props: {{ page3 }}
|
||||||
<lay-table :columns="columns3" :data-source="dataSource3" :page="page3" @change="change3"></lay-table>
|
<lay-table :columns="columns3" :data-source="dataSource3" :page="page3" @change="change3"></lay-table>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { ref } from 'vue'
|
import { ref } from 'vue';
|
||||||
|
import { layer } from "@layui/layer-vue";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
setup() {
|
setup() {
|
||||||
|
|
||||||
const page3 = {
|
const page3 = ref({
|
||||||
total: 100,
|
total: 100,
|
||||||
limit: 10,
|
limit: 10,
|
||||||
current: 2
|
current: 2,
|
||||||
}
|
showRefresh: true,
|
||||||
|
})
|
||||||
|
|
||||||
const change3 = function({ current }){
|
const change3 = ({ current, limit }) => {
|
||||||
console.log("当前页:" + JSON.stringify(current))
|
layer.msg("current:" + current + " limit:" + limit);
|
||||||
}
|
}
|
||||||
|
|
||||||
const columns3 = [
|
const columns3 = [
|
||||||
@ -697,8 +700,9 @@ export default {
|
|||||||
::: demo 通过 `columns` 配置 `type:'checkbox'` 开启单选列。
|
::: demo 通过 `columns` 配置 `type:'checkbox'` 开启单选列。
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<lay-button @click="changeSelectedKeys">修改选中值 {{ selectedKeys5 }}</lay-button>
|
<lay-button @click="changeSelectedKeys">修改选中</lay-button>
|
||||||
<lay-table :columns="columns23" :data-source="dataSource23" v-model:selectedKeys="selectedKeys5" :getCheckboxProps="getCheckboxProps"></lay-table>
|
<lay-button @click="changeDataSource23">修改数据</lay-button>
|
||||||
|
<lay-table :columns="columns23" :data-source="dataSource23" v-model:selectedKeys="selectedKeys5"></lay-table>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
@ -720,14 +724,23 @@ export default {
|
|||||||
selectedKeys5.value = ["2"]
|
selectedKeys5.value = ["2"]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const changeDataSource23 = () => {
|
||||||
|
dataSource23.value = [
|
||||||
|
{id:"1",username:"root", password:"root",sex:"男", age:"18", remark: 'layui - vue(谐音:类 UI) '},
|
||||||
|
{id:"2",username:"root", password:"root",sex:"男", age:"18", remark: 'layui - vue(谐音:类 UI) '}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
const columns23 = [
|
const columns23 = [
|
||||||
{
|
{
|
||||||
|
fixed: "left",
|
||||||
type: "checkbox",
|
type: "checkbox",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title:"账户",
|
title:"账户",
|
||||||
width:"200px",
|
width:"200px",
|
||||||
key:"username"
|
key:"username",
|
||||||
|
fixed: "left"
|
||||||
},{
|
},{
|
||||||
title:"密码",
|
title:"密码",
|
||||||
width: "300px",
|
width: "300px",
|
||||||
@ -747,20 +760,21 @@ export default {
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
||||||
const dataSource23 = [
|
const dataSource23 = ref([
|
||||||
{id:"1",username:"root", password:"root",sex:"男", age:"18", remark: 'layui - vue(谐音:类 UI) '},
|
{id:"1",username:"root", password:"root",sex:"男", age:"18", remark: 'layui - vue(谐音:类 UI) '},
|
||||||
{id:"2",username:"root", password:"root",sex:"男", age:"18", remark: 'layui - vue(谐音:类 UI) '},
|
{id:"2",username:"root", password:"root",sex:"男", age:"18", remark: 'layui - vue(谐音:类 UI) '},
|
||||||
{id:"3",username:"woow", password:"woow",sex:"男", age:"20", remark: 'layui - vue(谐音:类 UI) '},
|
{id:"3",username:"woow", password:"woow",sex:"男", age:"20", remark: 'layui - vue(谐音:类 UI) '},
|
||||||
{id:"4",username:"woow", password:"woow",sex:"男", age:"20", remark: 'layui - vue(谐音:类 UI) '},
|
{id:"4",username:"woow", password:"woow",sex:"男", age:"20", remark: 'layui - vue(谐音:类 UI) '},
|
||||||
{id:"5",username:"woow", password:"woow",sex:"男", age:"20", remark: 'layui - vue(谐音:类 UI) '}
|
{id:"5",username:"woow", password:"woow",sex:"男", age:"20", remark: 'layui - vue(谐音:类 UI) '}
|
||||||
]
|
])
|
||||||
|
|
||||||
return {
|
return {
|
||||||
columns23,
|
columns23,
|
||||||
dataSource23,
|
dataSource23,
|
||||||
selectedKeys5,
|
selectedKeys5,
|
||||||
changeSelectedKeys,
|
changeSelectedKeys,
|
||||||
getCheckboxProps
|
getCheckboxProps,
|
||||||
|
changeDataSource23
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1455,7 +1469,7 @@ export default {
|
|||||||
| row | 行单击 | data : 当前行 |
|
| row | 行单击 | data : 当前行 |
|
||||||
| row-double | 行双击 | data : 当前行 |
|
| row-double | 行双击 | data : 当前行 |
|
||||||
| row-contextmenu | 行右击 | data : 当前行 |
|
| row-contextmenu | 行右击 | data : 当前行 |
|
||||||
|
| change | 分页事件 | { current: 当前页码, limit: 每页数量 } |
|
||||||
:::
|
:::
|
||||||
|
|
||||||
::: title Table 插槽
|
::: title Table 插槽
|
||||||
@ -1463,9 +1477,10 @@ export default {
|
|||||||
|
|
||||||
::: table
|
::: table
|
||||||
|
|
||||||
| 插槽 | 描述 | 参数 |
|
| 插槽 | 描述 | 参数 | 版本 |
|
||||||
| ------- | ------------ | ---- |
|
| ------- | ------------ | ---- |---- |
|
||||||
| toolbar | 自定义工具栏 | -- |
|
| toolbar | 自定义工具栏 | -- |-- |
|
||||||
|
| footer | 底部扩展 | -- | `1.4.4` |
|
||||||
|
|
||||||
:::
|
:::
|
||||||
|
|
||||||
@ -1476,7 +1491,7 @@ export default {
|
|||||||
|
|
||||||
::: table
|
::: table
|
||||||
|
|
||||||
| 插槽 | 描述 | 类型 | 默认值 | 可选值 | 可选值 |
|
| 插槽 | 描述 | 类型 | 默认值 | 可选值 | 版本 |
|
||||||
| --------------- | ------------------------------ | --------- | ------- | --------------------------- | --------------------------- |
|
| --------------- | ------------------------------ | --------- | ------- | --------------------------- | --------------------------- |
|
||||||
| title | 列标题 | -- | -- | -- | -- |
|
| title | 列标题 | -- | -- | -- | -- |
|
||||||
| key | 数据字段 | -- | -- | -- | -- |
|
| key | 数据字段 | -- | -- | -- | -- |
|
||||||
|
@ -13,7 +13,7 @@
|
|||||||
::: demo 使用 `lay-upload` 标签, 创建一个上传按钮
|
::: demo 使用 `lay-upload` 标签, 创建一个上传按钮
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<lay-upload @done="getUploadFile" @choose="beginChoose">
|
<lay-upload @done="getUploadFile" field="bigFile" @choose="beginChoose">
|
||||||
<template #preview>
|
<template #preview>
|
||||||
<div v-for="(item,index) in picList" :key="`demo1-pic-'${index}`">
|
<div v-for="(item,index) in picList" :key="`demo1-pic-'${index}`">
|
||||||
<img :src="item"/>
|
<img :src="item"/>
|
||||||
@ -249,7 +249,7 @@ export default {
|
|||||||
| url | 服务端上传接口的地址 | string | -- | -- |
|
| url | 服务端上传接口的地址 | string | -- | -- |
|
||||||
| data | 请求上传接口的额外参数 | object | -- | -- |
|
| data | 请求上传接口的额外参数 | object | -- | -- |
|
||||||
| headers | 接口的请求头 | object | -- | -- |
|
| headers | 接口的请求头 | object | -- | -- |
|
||||||
| acceptMime | 文件选择框时的可选文件类型 | string | `images` | `images` |
|
| acceptMime | 文件选择框时的可选文件类型 | string | `MIME_type` | `MIME_type` |
|
||||||
| field | 设定文件域的字段名 | string | `file` | -- |
|
| field | 设定文件域的字段名 | string | `file` | -- |
|
||||||
| size | 设置文件最大可允许上传的大小,单位 KB。不支持ie8/9 | number | `0(不限制)` | -- |
|
| size | 设置文件最大可允许上传的大小,单位 KB。不支持ie8/9 | number | `0(不限制)` | -- |
|
||||||
| multiple | 是否允许多文件上传。设置 true即可开启。不支持ie8/9 | boolean | false | -- |
|
| multiple | 是否允许多文件上传。设置 true即可开启。不支持ie8/9 | boolean | false | -- |
|
||||||
|
@ -10,6 +10,115 @@
|
|||||||
::: demo
|
::: demo
|
||||||
<template>
|
<template>
|
||||||
<lay-timeline>
|
<lay-timeline>
|
||||||
|
<lay-timeline-item title="1.4.x">
|
||||||
|
<ul>
|
||||||
|
<a name="1-4-6"></a>
|
||||||
|
<li>
|
||||||
|
<h3>1.4.6 <span class="layui-badge-rim">2022-0x-xx</span></h3>
|
||||||
|
<ul>
|
||||||
|
<li>[修复] dropdown 组件 hide 事件触发异常。</li>
|
||||||
|
<li>[优化] dropdown 组件 open 方法修改为 show 方法。</li>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
<ul>
|
||||||
|
<a name="1-4-5"></a>
|
||||||
|
<li>
|
||||||
|
<h3>1.4.5 <span class="layui-badge-rim">2022-08-26</span></h3>
|
||||||
|
<ul>
|
||||||
|
<li>[修复] upload 组件 field 属性无效。</li>
|
||||||
|
<li>[修复] upload 组件 acceptMime 属性 默认值 无效。</li>
|
||||||
|
<li>[修复] menu 组件 changeOpenKeys 事件, 初始化时回调的问题。</li>
|
||||||
|
<li>[修复] dropdown 组件 popupContainer 不适用于 vue 自身渲染的元素的问题。</li>
|
||||||
|
<li>[优化] table 组件 page 属性, 与 page 组件属性对应, 并全部启用。 </li>
|
||||||
|
<li>[优化] input 组件 password 属性, 在 edge 的兼容问题。 </li>
|
||||||
|
<li>[优化] page 组件 total 属性为 0 时, 下一页仍可用的问题。</li>
|
||||||
|
<li>[优化] upload 组件 acceptMime 属性默认值为 MIME_type。</li>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
<ul>
|
||||||
|
<a name="1-4-4"></a>
|
||||||
|
<li>
|
||||||
|
<h3>1.4.4 <span class="layui-badge-rim">2022-08-18</span></h3>
|
||||||
|
<ul>
|
||||||
|
<li>[新增] table 组件 footer 插槽, 用在 page 与 body 之间自定义内容。</li>
|
||||||
|
<li>[修复] date-picker 组件 v-model 为空时, 无法完成日期时间选择。</li>
|
||||||
|
<li>[修复] quote 组件 margin 属性错误 。</li>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
<ul>
|
||||||
|
<a name="1-4-3"></a>
|
||||||
|
<li>
|
||||||
|
<h3>1.4.3 <span class="layui-badge-rim">2022-08-16</span></h3>
|
||||||
|
<ul>
|
||||||
|
<li>[新增] page 组件 change 事件。</li>
|
||||||
|
<li>[新增] card 组件 footer 插槽, 用于自定义底部。</li>
|
||||||
|
<li>[新增] table 组件 change 事件 limit 参数, 代表每页数量。</li>
|
||||||
|
<li>[修复] scroll 组件 default slots 改变时, 滑块不更新的问题。</li>
|
||||||
|
<li>[修复] table 组件 loading 属性造成的单元格错位。</li>
|
||||||
|
<li>[优化] page 组件 跳转 操作, 当输入页码为当前页启用禁用状态。</li>
|
||||||
|
<li>[过时] page 组件 limit 事件, 由 change 事件代替。</li>
|
||||||
|
<li>[过时] page 组件 jump 事件, 由 change 事件代替。</li>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
<ul>
|
||||||
|
<a name="1-4-2"></a>
|
||||||
|
<li>
|
||||||
|
<h3>1.4.2 <span class="layui-badge-rim">2022-08-15</span></h3>
|
||||||
|
<ul>
|
||||||
|
<li>[修复] table 组件 fixed 属性开启时, 不设置 width 产生的错误。</li>
|
||||||
|
<li>[修复] table 组件 dataSource 属性改变时, 清空 selectedKeys 内容。</li>
|
||||||
|
<li>[修复] table 组件 dataSource 属性改变时, 清空 selectedKey 内容。</li>
|
||||||
|
<li>[优化] table 组件 fixed 属性开启时, 根据 column 的 type 属性, 设置默认宽度。 </li>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
<ul>
|
||||||
|
<a name="1-4-1"></a>
|
||||||
|
<li>
|
||||||
|
<h3>1.4.1 <span class="layui-badge-rim">2022-08-14</span></h3>
|
||||||
|
<ul>
|
||||||
|
<li>[修复] 表格开启复选框之后,不使用getCheckboxProps属性,点击时全选会报错。</li>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
<ul>
|
||||||
|
<a name="1-4-0"></a>
|
||||||
|
<li>
|
||||||
|
<h3>1.4.0 <span class="layui-badge-rim">2022-08-13</span></h3>
|
||||||
|
<ul>
|
||||||
|
<li>[新增] button 组件 dropdown 下拉 demo。</li>
|
||||||
|
<li>[新增] button 组件 loading-icon 属性, 允许自定义加载图标。</li>
|
||||||
|
<li>[新增] table 组件 loading 属性, 数据过渡。</li>
|
||||||
|
<li>[新增] table 组件 column 属性 children 配置, 支持表头分组。</li>
|
||||||
|
<li>[新增] table 组件 getRadioProps 属性, 启用单选列时, 定义 radio 配置选项。</li>
|
||||||
|
<li>[新增] table 组件 getCheckboxProps 属性, 启用复选列, 定义 checkbox 配置选项。</li>
|
||||||
|
<li>[新增] transfer 组件 datasource 属性 disabled 配置, 允许选项禁用。</li>
|
||||||
|
<li>[新增] switch 组件 loading 属性, 开启加载状态, 默认为 false。</li>
|
||||||
|
<li>[新增] switch 组件 loading-icon 属性, 允许自定义加载图标, 可选值为内置图标集。</li>
|
||||||
|
<li>[新增] date-picker 组件 prefix-icon 属性, 用于自定义输入框前置图标, layui-icon-date 为默认值。</li>
|
||||||
|
<li>[新增] date-picker 组件 suffix-icon 属性, 用于自定义输入框后置图标。</li>
|
||||||
|
<li>[修复] table 组件 column 属性为 fixed 时, 隐藏该列时不重新计算距离。</li>
|
||||||
|
<li>[修复] input 组件 v-model 属性输入拼字阶段触发更新的问题。</li>
|
||||||
|
<li>[修复] table 组件 height 属性修改时, 造成单元格错位。</li>
|
||||||
|
<li>[修复] table 组件 demand 模式缺失 radio.css 文件。</li>
|
||||||
|
<li>[修复] menu 组件 demand 模式缺失 dropdown.css 文件。</li>
|
||||||
|
<li>[修复] textarea 组件无法解析 lay-icon 的警告。</li>
|
||||||
|
<li>[优化] input 组件 password 属性开启时的默认图标。</li>
|
||||||
|
<li>[优化] table 组件 dropdown 筛选列面板随滚动条移动。</li>
|
||||||
|
<li>[优化] table 组件 column 无对应列时仍保持列占位。</li>
|
||||||
|
<li>[优化] table 组件 skin 属性为 row 时 header 高出 1 像素。</li>
|
||||||
|
<li>[优化] transfer 组件 title 在特殊分辨率下显示不全。</li>
|
||||||
|
<li>[优化] notice-bar 组件 width 越界。</li>
|
||||||
|
<li>[优化] input 组件 clear 操作背景透明的问题。</li>
|
||||||
|
<li>[优化] input 组件 password 操作背景透明的问题。</li>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</lay-timeline-item>
|
||||||
<lay-timeline-item title="1.3.x">
|
<lay-timeline-item title="1.3.x">
|
||||||
<ul>
|
<ul>
|
||||||
<a name="1-3-14"></a>
|
<a name="1-3-14"></a>
|
||||||
|
@ -429,6 +429,11 @@ const zhCN = [
|
|||||||
component: () => import("../document/zh-CN/components/tagInput.md"),
|
component: () => import("../document/zh-CN/components/tagInput.md"),
|
||||||
meta: { title: "标签" },
|
meta: { title: "标签" },
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
path: "/zh-CN/components/space",
|
||||||
|
component: () => import("../document/zh-CN/components/space.md"),
|
||||||
|
meta: { title: "间距" },
|
||||||
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
@ -32,7 +32,7 @@
|
|||||||
>
|
>
|
||||||
<span
|
<span
|
||||||
>{{ t("home.download") }}:<em class="site-showdowns"
|
>{{ t("home.download") }}:<em class="site-showdowns"
|
||||||
>20,894</em
|
>24,177</em
|
||||||
></span
|
></span
|
||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
@ -43,7 +43,7 @@
|
|||||||
rel="nofollow"
|
rel="nofollow"
|
||||||
class="site-star"
|
class="site-star"
|
||||||
>
|
>
|
||||||
<i class="layui-icon"></i> Star <cite id="getStars">1398</cite>
|
<i class="layui-icon"></i> Star <cite id="getStars">1465</cite>
|
||||||
</a>
|
</a>
|
||||||
<a
|
<a
|
||||||
href="https://gitee.com/layui-vue"
|
href="https://gitee.com/layui-vue"
|
||||||
@ -179,14 +179,14 @@
|
|||||||
</lay-tooltip>
|
</lay-tooltip>
|
||||||
</lay-col>
|
</lay-col>
|
||||||
<lay-col :md="3">
|
<lay-col :md="3">
|
||||||
<lay-tooltip content="Pear Admin" position="top">
|
<lay-tooltip content="Sa-Token" position="top">
|
||||||
<a
|
<a
|
||||||
style="height: 40px; display: inline-block"
|
style="height: 40px; display: inline-block"
|
||||||
href="http://www.pearadmin.com"
|
href="https://sa-token.dev33.cn/"
|
||||||
target="_blank"
|
target="_blank"
|
||||||
>
|
>
|
||||||
<lay-avatar
|
<lay-avatar
|
||||||
src="https://portrait.gitee.com/uploads/avatars/namespace/2319/6958819_pear-admin_1643085106.png!avatar100"
|
src="https://sa-token.dev33.cn/doc/logo.png"
|
||||||
style="background: transparent"
|
style="background: transparent"
|
||||||
></lay-avatar>
|
></lay-avatar>
|
||||||
</a>
|
</a>
|
||||||
|
@ -88,6 +88,12 @@ const menus = [
|
|||||||
subTitle: "skeleton",
|
subTitle: "skeleton",
|
||||||
path: "/zh-CN/components/skeleton",
|
path: "/zh-CN/components/skeleton",
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
id: 12,
|
||||||
|
title: "间距",
|
||||||
|
subTitle: "space",
|
||||||
|
path: "/zh-CN/components/space",
|
||||||
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -427,26 +433,6 @@ const menus = [
|
|||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
{
|
|
||||||
id: 1,
|
|
||||||
title: "新特性",
|
|
||||||
children: [
|
|
||||||
{
|
|
||||||
id: 101,
|
|
||||||
title: "标签",
|
|
||||||
flag: "new",
|
|
||||||
subTitle: "modal",
|
|
||||||
path: "/zh-CN/components/tag",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 102,
|
|
||||||
title: "标签输入框",
|
|
||||||
flag: "new",
|
|
||||||
subTitle: "load",
|
|
||||||
path: "/zh-CN/components/tagInput",
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
];
|
];
|
||||||
|
|
||||||
export default menus;
|
export default menus;
|
||||||
|
1265
pnpm-lock.yaml
generated
1265
pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
Loading…
x
Reference in New Issue
Block a user