✨ 1.新增 circular 属性,使用圆形图标;
💄 2.修改为 flex 布局; 🎨 3.优化代码结构 📖 4.更新文档
This commit is contained in:
parent
545d8ac48a
commit
092fe7af69
@ -1,6 +1,6 @@
|
|||||||
::: title 基础使用
|
::: title 基础使用
|
||||||
|
|
||||||
###### 回到顶部组件的默认样式,通过滑动来查看页面右下角的按钮。
|
###### 回到顶部组件的默认样式,通过滑动来查看页面右下角的正方形按钮。
|
||||||
|
|
||||||
:::
|
:::
|
||||||
::: demo
|
::: demo
|
||||||
@ -9,18 +9,6 @@
|
|||||||
<lay-backtop target=".layui-body"></lay-backtop>
|
<lay-backtop target=".layui-body"></lay-backtop>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
|
||||||
import { ref } from 'vue'
|
|
||||||
|
|
||||||
export default {
|
|
||||||
setup() {
|
|
||||||
|
|
||||||
return {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
:::
|
:::
|
||||||
|
|
||||||
:::title 自定义
|
:::title 自定义
|
||||||
@ -29,19 +17,19 @@ export default {
|
|||||||
|
|
||||||
::: demo
|
::: demo
|
||||||
|
|
||||||
<!-- 使用默认插槽自定义组件内容,也可以使用组件提供的样式属性快速定义常用样式 -->
|
<!-- 使用默认插槽自定义组件内容,也可以使用组件提供的样式属性快速定义常用样式,样式属性能满足大多数场景,lay-backtop组件可搭配 lay-tooltip 组件使用-->
|
||||||
<template>
|
<template>
|
||||||
<lay-backtop target=".layui-body" :showHeight="0" :bottom="100" @click="handlerClick" bgcolor="#FFFFFF" disabled >
|
<!-- 使用默认插槽自定义 -->
|
||||||
<div style="
|
<lay-tooltip content="插槽自定义 backtop " position="left">
|
||||||
width:50px;
|
<lay-backtop target=".layui-body" :showHeight="0" :bottom="160" bgcolor="#5FB878" circular disabled>
|
||||||
height:50px;
|
<lay-icon type="layui-icon-dialogue" size="30px"></lay-icon>
|
||||||
background-color: #5FB878;
|
|
||||||
color: #FFFFFF;
|
|
||||||
text-align: center;
|
|
||||||
border-radius:50%">
|
|
||||||
<i class="layui-icon layui-icon-dialogue" style="font-size:30px"></i>
|
|
||||||
</div>
|
|
||||||
</lay-backtop>
|
</lay-backtop>
|
||||||
|
</lay-tooltip>
|
||||||
|
<!-- 使用样式属性自定义 -->
|
||||||
|
<lay-tooltip content="属性自定义 backtop " position="left">
|
||||||
|
<lay-backtop target=".layui-body" :bottom="100" bgcolor="#5FB878" icon="layui-icon-up" circular>
|
||||||
|
</lay-backtop>
|
||||||
|
</lay-tooltip>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
@ -50,14 +38,11 @@ import { layer } from "../../../../src/index.ts"
|
|||||||
|
|
||||||
export default {
|
export default {
|
||||||
setup() {
|
setup() {
|
||||||
let count = 0;
|
|
||||||
const handlerClick = () => {
|
const handlerClick = () => {
|
||||||
count++;
|
layer.msg("layui-vue", { time: 1000 });
|
||||||
layer.msg(count, { time: 1000 })
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
count,
|
|
||||||
handlerClick,
|
handlerClick,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -74,8 +59,8 @@ export default {
|
|||||||
::: demo
|
::: demo
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<!-- 需要用一个 div 包裹滚动目标和 lay-backtop 组件 -->
|
<!-- 需要用一个 div 包裹触发滚动事件的目标元素和 lay-backtop 组件 -->
|
||||||
<div class="scrollContainer">
|
<div class="scrollContainer" style="width:700px; height:300px;">
|
||||||
<div id="scrollContent" style="overflow-y:auto; overflow-x:auto; width:700px; height:300px;">
|
<div id="scrollContent" style="overflow-y:auto; overflow-x:auto; width:700px; height:300px;">
|
||||||
<p v-for="(n,index) in 50" :key="n" style="height:32px;border-bottom:0.5px solid #5FB878;margin-bottom:10px;line-height:35px">
|
<p v-for="(n,index) in 50" :key="n" style="height:32px;border-bottom:0.5px solid #5FB878;margin-bottom:10px;line-height:35px">
|
||||||
{{index + ". layui-vue , 基 于 vue 3.0 的 桌 面 端 组 件 库 , layui 的 另 一 种 呈 现 方 式"}}
|
{{index + ". layui-vue , 基 于 vue 3.0 的 桌 面 端 组 件 库 , layui 的 另 一 种 呈 现 方 式"}}
|
||||||
@ -86,63 +71,7 @@ export default {
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { ref } from 'vue'
|
|
||||||
|
|
||||||
export default {
|
|
||||||
setup() {
|
|
||||||
|
|
||||||
return {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
</script>
|
||||||
<style>
|
|
||||||
.scrollContainer{
|
|
||||||
width:700px;
|
|
||||||
height:300px;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
||||||
:::
|
|
||||||
|
|
||||||
::: title 结合 tooltip 组件使用
|
|
||||||
|
|
||||||
###### 可以和 lay-tooltip 组件搭配使用
|
|
||||||
|
|
||||||
:::
|
|
||||||
::: demo
|
|
||||||
|
|
||||||
<template>
|
|
||||||
<!-- 需要用一个 div 包裹滚动容器和 Lay-backtop 组件 -->
|
|
||||||
<div class="scrollContainer">
|
|
||||||
<div id="scrollContent2" style="overflow-y:auto; overflow-x:auto; width:700px; height:300px;">
|
|
||||||
<p v-for="(n,index) in 50" :key="n" style="height:40px;border-bottom:0.5px solid #5FB878;margin-bottom:10px;line-height:40px">
|
|
||||||
{{index + ". layui-vue , 基 于 vue 3.0 的 桌 面 端 组 件 库 , layui 的 另 一 种 呈 现 方 式"}}
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
<lay-tooltip content="backtop" position="left">
|
|
||||||
<lay-backtop target="#scrollContent2" :showHeight="100" :bottom="30" position="absolute" border-radius="50%" bgcolor="#5FB878"></lay-backtop>
|
|
||||||
</lay-tooltip>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import { ref } from 'vue'
|
|
||||||
|
|
||||||
export default {
|
|
||||||
setup() {
|
|
||||||
|
|
||||||
return {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
<style>
|
|
||||||
.scrollContainer{
|
|
||||||
width:700px;
|
|
||||||
height:300px;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
||||||
:::
|
:::
|
||||||
|
|
||||||
@ -165,7 +94,7 @@ export default {
|
|||||||
| opacity | 可选,不透明度 | number | 0.0-1.0 |
|
| opacity | 可选,不透明度 | number | 0.0-1.0 |
|
||||||
| color | 可选,前景颜色 | string | #FFFFFF |
|
| color | 可选,前景颜色 | string | #FFFFFF |
|
||||||
| borderRadius | 可选,添加圆角 | string | 2px(默认) |
|
| borderRadius | 可选,添加圆角 | string | 2px(默认) |
|
||||||
|
|
| circular | 可选, 使用圆形按钮 | boolean | true \| false(默认)
|
||||||
| <strong>图标样式</strong> |
|
| <strong>图标样式</strong> |
|
||||||
| icon | 可选,图标类型 | string | layui-icon-top(默认) |
|
| icon | 可选,图标类型 | string | layui-icon-top(默认) |
|
||||||
| iconSize | 可选,图标大小 | number | 30 |
|
| iconSize | 可选,图标大小 | number | 30 |
|
||||||
|
@ -1,20 +1,20 @@
|
|||||||
/** backtop **/
|
/** backtop **/
|
||||||
.lay-backtop {
|
.layui-backtop {
|
||||||
position: fixed;
|
position: fixed;
|
||||||
right: 15px;
|
right: 30px;
|
||||||
bottom: 15px;
|
bottom: 40px;
|
||||||
z-index: 999999;
|
|
||||||
width: 50px;
|
width: 50px;
|
||||||
height: 50px;
|
height: 50px;
|
||||||
line-height: 50px;
|
display: flex;
|
||||||
margin-bottom: 1px;
|
align-items: center;
|
||||||
text-align: center;
|
justify-content: center;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
font-size: 40px;
|
font-size: 40px;
|
||||||
background-color: #9f9f9f;
|
background-color: #9f9f9f;
|
||||||
color: #fff;
|
color: #ffffff;
|
||||||
border-radius: 2px;
|
border-radius: 2px;
|
||||||
opacity: 0.95;
|
opacity: 0.95;
|
||||||
|
z-index: 999999;
|
||||||
:hover {
|
:hover {
|
||||||
opacity: 0.85;
|
opacity: 0.85;
|
||||||
}
|
}
|
||||||
|
@ -1,29 +1,20 @@
|
|||||||
<template>
|
<template>
|
||||||
<!-- FIXME style为临时方案 -->
|
|
||||||
<div
|
<div
|
||||||
v-show="visible"
|
v-show="visible"
|
||||||
ref="backtopRef"
|
ref="backtopRef"
|
||||||
class="lay-backtop"
|
class="layui-backtop"
|
||||||
:style="{
|
:style="{ ...styleBacktop }"
|
||||||
right: `${props.right}px`,
|
|
||||||
bottom: `${props.bottom}px`,
|
|
||||||
backgroundColor: `${props.bgcolor}`,
|
|
||||||
opacity:`${props.opacity}`,
|
|
||||||
color: `${props.color}`,
|
|
||||||
borderRadius:`${props.borderRadius}`,
|
|
||||||
}"
|
|
||||||
@click.stop="handleClick"
|
@click.stop="handleClick"
|
||||||
@mousedown="backtopRef.style.opacity = 1"
|
@mousedown="handlerMousedown"
|
||||||
@mouseup="backtopRef.style.opacity = 0.95"
|
@mouseup="handlerMouseup"
|
||||||
>
|
>
|
||||||
<!-- <i v-if="!$slots.default" :class="`layui-icon ${props.icon}`" style="font-size: 30px;"></i> -->
|
|
||||||
<slot>
|
<slot>
|
||||||
<lay-icon
|
<lay-icon
|
||||||
:type="`layui-icon ${props.icon}`"
|
:type="props.icon"
|
||||||
:size="`${props.iconSize}px`"
|
:size="`${props.iconSize}px`"
|
||||||
:prefix="`${props.iconPrefix}`"
|
:prefix="props.iconPrefix"
|
||||||
:color="`${props.iconColor}`">
|
:color="props.iconColor"
|
||||||
</lay-icon>
|
></lay-icon>
|
||||||
</slot>
|
</slot>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@ -36,29 +27,28 @@ export default {
|
|||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { defineProps, defineEmits, ref, shallowRef, withDefaults, computed, onMounted, } from 'vue';
|
import { defineProps, defineEmits, ref, shallowRef, withDefaults, computed, onMounted, } from 'vue';
|
||||||
import layIcon from '../icon/index';
|
import LayIcon from '../icon/index';
|
||||||
import './index.less';
|
import './index.less';
|
||||||
|
|
||||||
export interface LayBacktopProps {
|
export interface LayBacktopProps {
|
||||||
// 通用
|
/**通用*/
|
||||||
target?: string; // 触发滚动的对象
|
target?: string;
|
||||||
showHeight?: number;
|
showHeight?: number;
|
||||||
disabled?: boolean; // 禁用返回顶部
|
disabled?: boolean;
|
||||||
// 组件样式
|
/**组件样式*/
|
||||||
position?: 'fixed' | 'absolute'; // 定位方式,显示在特定容器内部需要设置为 absolute
|
position?: 'fixed' | 'absolute';
|
||||||
right?: number;
|
right?: number;
|
||||||
bottom?: number;
|
bottom?: number;
|
||||||
bgcolor?: string; // 背景颜色
|
bgcolor?: string;
|
||||||
opacity?: number; // 不透明度0.01~1.00
|
opacity?: number;
|
||||||
color?: string; // 前景颜色
|
color?: string;
|
||||||
borderRadius?: string
|
borderRadius?: number | string;
|
||||||
// shape?: 'square' | 'circular';
|
circular?: boolean;
|
||||||
// 图标样式
|
/**图标样式*/
|
||||||
icon?: string;
|
icon?: string;
|
||||||
iconSize?: number;
|
iconSize?: number;
|
||||||
iconPrefix?: string;
|
iconPrefix?: string;
|
||||||
iconColor?: string;
|
iconColor?: string;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const props = withDefaults(defineProps<LayBacktopProps>(), {
|
const props = withDefaults(defineProps<LayBacktopProps>(), {
|
||||||
@ -68,25 +58,38 @@ const props = withDefaults(defineProps<LayBacktopProps>(), {
|
|||||||
bottom: 40,
|
bottom: 40,
|
||||||
icon: 'layui-icon-top',
|
icon: 'layui-icon-top',
|
||||||
iconSize: 30,
|
iconSize: 30,
|
||||||
|
iconPrefix: 'layui-icon',
|
||||||
disabled: false,
|
disabled: false,
|
||||||
|
circular: false,
|
||||||
});
|
});
|
||||||
|
|
||||||
const emit = defineEmits(['click']);
|
const emit = defineEmits(['click']);
|
||||||
|
|
||||||
let visible = ref(props.showHeight === 0);
|
|
||||||
const backtopRef = ref<HTMLElement | null>(null);
|
const backtopRef = ref<HTMLElement | null>(null);
|
||||||
const scrollTarget = shallowRef<Window | HTMLElement | undefined>(undefined);
|
const scrollTarget = shallowRef<Window | HTMLElement | undefined>(undefined);
|
||||||
|
let visible = ref(props.showHeight === 0);
|
||||||
|
const borderRadius = computed(() => {
|
||||||
|
if (props.circular) return "50%";
|
||||||
|
return typeof props.borderRadius === 'number' ? `${props.borderRadius}px` : props.borderRadius;
|
||||||
|
});
|
||||||
|
const styleBacktop = computed(() => {
|
||||||
|
return {
|
||||||
|
position: props.position,
|
||||||
|
right: `${props.right}px`,
|
||||||
|
bottom: `${props.bottom}px`,
|
||||||
|
backgroundColor: props.bgcolor,
|
||||||
|
opacity: props.opacity,
|
||||||
|
color: props.color,
|
||||||
|
borderRadius: borderRadius.value,
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// TODO 临时动画方案
|
||||||
const scrollToTop = () => {
|
const scrollToTop = () => {
|
||||||
if (!scrollTarget.value) return;
|
if (!scrollTarget.value) return;
|
||||||
if (scrollTarget.value instanceof Window) {
|
if (scrollTarget.value instanceof Window) {
|
||||||
window.scrollTo({
|
window.scrollTo({ top: 0, left: 0, behavior: 'smooth' }); // smooth | instant(default)
|
||||||
top: 0,
|
|
||||||
left: 0,
|
|
||||||
behavior: 'smooth' //smooth(平滑滚动),instant(瞬间滚动),默认instant
|
|
||||||
});
|
|
||||||
} else {
|
} else {
|
||||||
// FIXME 临时动画方案待改进
|
|
||||||
let step = scrollTarget.value.scrollTop / 4;
|
let step = scrollTarget.value.scrollTop / 4;
|
||||||
if (scrollTarget.value.scrollTop > 0) {
|
if (scrollTarget.value.scrollTop > 0) {
|
||||||
scrollTarget.value.scrollTop -= Math.max(step, 10);
|
scrollTarget.value.scrollTop -= Math.max(step, 10);
|
||||||
@ -110,6 +113,14 @@ const handleClick = (event: MouseEvent) => {
|
|||||||
emit('click', event);
|
emit('click', event);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const handlerMousedown = () => {
|
||||||
|
backtopRef.value!.style.opacity = '1';
|
||||||
|
}
|
||||||
|
|
||||||
|
const handlerMouseup = () => {
|
||||||
|
backtopRef.value!.style.opacity = '0.95';
|
||||||
|
}
|
||||||
|
|
||||||
// 获取滚动目标元素
|
// 获取滚动目标元素
|
||||||
const getScrollTarget = () => {
|
const getScrollTarget = () => {
|
||||||
if (props.target === 'window') {
|
if (props.target === 'window') {
|
||||||
@ -121,8 +132,7 @@ const getScrollTarget = () => {
|
|||||||
if (props.position === 'absolute') {
|
if (props.position === 'absolute') {
|
||||||
if (!targetElement.parentElement) throw new Error(`target parent element is not existed: ${props.target}`);
|
if (!targetElement.parentElement) throw new Error(`target parent element is not existed: ${props.target}`);
|
||||||
targetElement.parentElement.style.position = 'relative';
|
targetElement.parentElement.style.position = 'relative';
|
||||||
if (!backtopRef.value) throw new Error(`backtop component ref is null: ${props.target}`);
|
// backtopRef.value!.style.position = props.position;
|
||||||
backtopRef.value.style.position = props.position;
|
|
||||||
}
|
}
|
||||||
return targetElement;
|
return targetElement;
|
||||||
}
|
}
|
||||||
@ -131,7 +141,7 @@ const getScrollTarget = () => {
|
|||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
let timer: any = undefined;
|
let timer: any = undefined;
|
||||||
scrollTarget.value = getScrollTarget();
|
scrollTarget.value = getScrollTarget();
|
||||||
// FIXME 节流待改进
|
// TODO 节流待改进
|
||||||
scrollTarget.value.addEventListener('scroll', () => {
|
scrollTarget.value.addEventListener('scroll', () => {
|
||||||
clearTimeout(timer);
|
clearTimeout(timer);
|
||||||
timer = setTimeout(() => {
|
timer = setTimeout(() => {
|
||||||
|
Loading…
Reference in New Issue
Block a user