feat: demo of motion plugin (#5550)

添加Motion的用法例子
This commit is contained in:
Netfan
2025-02-17 15:25:45 +08:00
committed by GitHub
parent e0eb57d38d
commit 9f82052c71
11 changed files with 338 additions and 0 deletions

View File

@@ -111,3 +111,9 @@ export const requestClient = createRequestClient(apiURL, {
});
export const baseRequestClient = new RequestClient({ baseURL: apiURL });
export interface PageFetchParams {
[key: string]: any;
pageNo?: number;
pageSize?: number;
}

View File

@@ -2,6 +2,7 @@ import { createApp, watchEffect } from 'vue';
import { registerAccessDirective } from '@vben/access';
import { initTippy } from '@vben/common-ui';
import { MotionPlugin } from '@vben/plugins/motion';
import { preferences } from '@vben/preferences';
import { initStores } from '@vben/stores';
import '@vben/styles';
@@ -49,6 +50,9 @@ async function bootstrap(namespace: string) {
// 配置@tanstack/vue-query
app.use(VueQueryPlugin);
// 配置Motion插件
app.use(MotionPlugin);
// 动态更新标题
watchEffect(() => {
if (preferences.app.dynamicTitle) {

View File

@@ -0,0 +1,213 @@
<script lang="ts" setup>
import { reactive } from 'vue';
import { Page } from '@vben/common-ui';
import { Motion, MotionGroup, MotionPresets } from '@vben/plugins/motion';
import { refAutoReset, watchDebounced } from '@vueuse/core';
import {
Button,
Card,
Col,
Form,
FormItem,
InputNumber,
Row,
Select,
} from 'ant-design-vue';
// 本例子用不到visible类型的动画。带有VisibleOnce和Visible的类型会在组件进入视口被显示时执行动画
const presets = MotionPresets.filter((v) => !v.includes('Visible'));
const showCard1 = refAutoReset(true, 100);
const showCard2 = refAutoReset(true, 100);
const showCard3 = refAutoReset(true, 100);
const motionProps = reactive({
delay: 0,
duration: 300,
enter: { scale: 1 },
hovered: { scale: 1.1, transition: { delay: 0, duration: 50 } },
preset: 'fade',
tapped: { scale: 0.9, transition: { delay: 0, duration: 50 } },
});
const motionGroupProps = reactive({
delay: 0,
duration: 300,
enter: { scale: 1 },
hovered: { scale: 1.1, transition: { delay: 0, duration: 50 } },
preset: 'fade',
tapped: { scale: 0.9, transition: { delay: 0, duration: 50 } },
});
watchDebounced(
motionProps,
() => {
showCard2.value = false;
},
{ debounce: 200, deep: true },
);
watchDebounced(
motionGroupProps,
() => {
showCard3.value = false;
},
{ debounce: 200, deep: true },
);
function openDocPage() {
window.open('https://motion.vueuse.org/', '_blank');
}
</script>
<template>
<Page title="Motion">
<template #description>
<span>一个易于使用的为其它组件赋予动画效果的组件</span>
<Button type="link" @click="openDocPage">查看文档</Button>
</template>
<Card title="使用指令" :body-style="{ minHeight: '5rem' }">
<template #extra>
<Button type="primary" @click="showCard1 = false">重载</Button>
</template>
<div>
<div class="relative flex gap-2 overflow-hidden" v-if="showCard1">
<Button v-motion-fade-visible>fade</Button>
<Button v-motion-pop-visible :duration="500">pop</Button>
<Button v-motion-slide-left>slide-left</Button>
<Button v-motion-slide-right>slide-right</Button>
<Button v-motion-slide-bottom>slide-bottom</Button>
<Button v-motion-slide-top>slide-top</Button>
</div>
</div>
</Card>
<Card
class="mt-2"
title="使用组件(将内部作为一个整体添加动画)"
:body-style="{ padding: 0 }"
>
<div
class="relative flex min-h-32 items-center justify-center gap-2 overflow-hidden"
>
<Motion
v-bind="motionProps"
v-if="showCard2"
class="flex items-center gap-2"
>
<Button size="large">这个按钮在显示时会有动画效果</Button>
<span>附属组件会作为整体处理动画</span>
</Motion>
</div>
<div
class="relative flex min-h-32 items-center justify-center gap-2 overflow-hidden"
>
<div v-if="showCard2" class="flex items-center gap-2">
<span>顺序延迟</span>
<Motion
v-bind="{
...motionProps,
delay: motionProps.delay + 100 * i,
}"
v-for="i in 5"
:key="i"
>
<Button size="large">按钮{{ i }}</Button>
</Motion>
</div>
</div>
<div>
<Form :model="motionProps" :label-col="{ span: 10 }">
<Row>
<Col :span="8">
<FormItem prop="preset" label="动画效果">
<Select v-model:value="motionProps.preset">
<Select.Option
:value="preset"
v-for="preset in presets"
:key="preset"
>
{{ preset }}
</Select.Option>
</Select>
</FormItem>
</Col>
<Col :span="8">
<FormItem prop="duration" label="持续时间">
<InputNumber v-model:value="motionProps.duration" />
</FormItem>
</Col>
<Col :span="8">
<FormItem prop="delay" label="延迟动画">
<InputNumber v-model:value="motionProps.delay" />
</FormItem>
</Col>
<Col :span="8">
<FormItem prop="hovered.scale" label="Hover缩放">
<InputNumber v-model:value="motionProps.hovered.scale" />
</FormItem>
</Col>
<Col :span="8">
<FormItem prop="hovered.tapped" label="按下时缩放">
<InputNumber v-model:value="motionProps.tapped.scale" />
</FormItem>
</Col>
</Row>
</Form>
</div>
</Card>
<Card
class="mt-2"
title="分组动画(每个子元素都会应用相同的独立动画)"
:body-style="{ padding: 0 }"
>
<div
class="relative flex min-h-32 items-center justify-center gap-2 overflow-hidden"
>
<MotionGroup v-bind="motionGroupProps" v-if="showCard3">
<Button size="large">按钮1</Button>
<Button size="large">按钮2</Button>
<Button size="large">按钮3</Button>
<Button size="large">按钮4</Button>
<Button size="large">按钮5</Button>
</MotionGroup>
</div>
<div>
<Form :model="motionGroupProps" :label-col="{ span: 10 }">
<Row>
<Col :span="8">
<FormItem prop="preset" label="动画效果">
<Select v-model:value="motionGroupProps.preset">
<Select.Option
:value="preset"
v-for="preset in presets"
:key="preset"
>
{{ preset }}
</Select.Option>
</Select>
</FormItem>
</Col>
<Col :span="8">
<FormItem prop="duration" label="持续时间">
<InputNumber v-model:value="motionGroupProps.duration" />
</FormItem>
</Col>
<Col :span="8">
<FormItem prop="delay" label="延迟动画">
<InputNumber v-model:value="motionGroupProps.delay" />
</FormItem>
</Col>
<Col :span="8">
<FormItem prop="hovered.scale" label="Hover缩放">
<InputNumber v-model:value="motionGroupProps.hovered.scale" />
</FormItem>
</Col>
<Col :span="8">
<FormItem prop="hovered.tapped" label="按下时缩放">
<InputNumber v-model:value="motionGroupProps.tapped.scale" />
</FormItem>
</Col>
</Row>
</Form>
</div>
</Card>
</Page>
</template>