@morev/vue-transitions
可重複使用的介面轉場效果,適用於 Vue 2
和 Vue 3
,無需 CSS ❤️
✔️ 透過 props 高度客製化;
✔️ 在 group
模式下,可正確搭配網格/彈性佈局運作;
✔️ 考量動畫元素的初始樣式,例如 transform
或 opacity
;
✔️ 使用通用的 Nuxt 2
和 Nuxt 3
模組更加易於使用。
目錄
安裝
❗ 需求
- Node 版本:
>= 18.0.0
- Nuxt 版本(如果使用):
>= 2.17.0 || >= 3.5.0
如果您使用的 Node 或 Nuxt 版本低於指定的版本,則此外掛程式將無法運作。
使用 yarn
yarn add @morev/vue-transitions
使用 npm
npm install @morev/vue-transitions
使用 pnpm
pnpm add @morev/vue-transitions
使用 bun
bun add @morev/vue-transitions
❗ 給 Bun
使用者的重要注意事項
此套件依賴 postinstall
鉤子來確定 Vue 版本並提供適當的元件。
預設情況下,Bun 不會執行生命週期鉤子,因此為了讓它正常運作,您需要在安裝後手動將此套件新增至 trustedDependencies
,並再次執行 bun install
。
{
"trustedDependencies": ["@morev/vue-transitions"]
}
用法
如果您打算將此函式庫與 Nuxt 一起使用,則可以跳過以下段落。
跳至「搭配 Nuxt 使用」章節.
此套件匯出兩個版本的元件
- 適用於
Vue2
的版本可透過具名匯出/vue2
取得 - 適用於
Vue3
的版本可透過具名匯出/vue3
取得
但是,也有預設匯出會對應到正在使用的本機 Vue 版本。
實際上,它會使用 postinstall npm 鉤子。
安裝此套件後,指令碼會開始檢查已安裝的 Vue 版本,並根據本機 Vue 版本重新導向匯出。
這感覺相當穩健,但如果您擔心,最好根據您使用的版本選擇明確的具名導入。
順便一提,您可以在安裝後變更預設匯出:只需執行指令
vue-transitions-version-switch <版本>
- 使用
yarn
的範例:yarn vue-transitions-version-switch 2
- 使用
npx
的範例:npx vue-transitions-version-switch 3
全域註冊
使用 Vue3
import { createApp } from 'vue';
import { plugin as vueTransitionsPlugin } from '@morev/vue-transitions';
import '@morev/vue-transitions/styles';
const app = createApp(App);
app.use(vueTransitionsPlugin({
// Plugin options (optional, described below)
}));
使用 Vue2
import Vue from 'vue';
import { plugin as vueTransitionsPlugin } from '@morev/vue-transitions';
import '@morev/vue-transitions/styles';
Vue.use(vueTransitionsPlugin, {
// Plugin options (optional, described below)
});
😥 我收到錯誤「找不到此相依性」
對於無法解析 exports
欄位的環境(例如 Nuxt 2),只需將樣式導入替換為檔案的直接路徑即可
- import '@morev/vue-transitions/styles';
+ import '@morev/vue-transitions/dist/index.css';
自訂選項
建議在設定自訂選項時使用具名匯出
plugin
,而不是預設匯出,以取得正確的類型資訊。
自訂選項可讓您變更預設屬性值。
若要變更預設值,請將 defaultProps
鍵傳遞至外掛程式設定,列出所需 props 的鍵值對。
您也可以變更每個元件的預設 props,為此只需將 componentDefaultProps
鍵傳遞至外掛程式設定。
重要:這些 props 不會經過驗證,因此請確保您使用正確的值定義它們。
import { createApp } from 'vue';
import { plugin as vueTransitionsPlugin } from '@morev/vue-transitions';
import '@morev/vue-transitions/styles';
const app = createApp(App);
app.use(vueTransitionsPlugin({
// Default duration for all transitions now is `200`
defaultProps: {
duration: 200,
},
// But for `<transition-expand>` default duration is `500`
componentDefaultProps: {
TransitionExpand: {
duration: 500,
}
}
}));
直接導入元件
<template>
<transition-fade>
<div v-if="isVisible" class="box">
Fade transition
</div>
</transition-fade>
</template>
<script>
import { TransitionFade } from '@morev/vue-transitions';
export default {
components: { TransitionFade },
};
</script>
搭配 Nuxt 使用
此函式庫透過具名匯出 /nuxt
為 Nuxt 2 和 3 匯出一個可直接使用的通用模組。
使用 Nuxt 時,建議使用此模組而不是手動安裝,因為
- Nuxt 可讓您依需求自動導入元件,而不是全域註冊,這是一種效能更高的選項。
- 這樣做也比較快 :)
若要使用,請將 @morev/vue-transitions/nuxt
新增至 nuxt.config.ts
/ nuxt.config.js
的 modules
區段
export default defineNuxtConfig({
modules: [
'@morev/vue-transitions/nuxt',
],
vueTransitions: {
// The same options as in the plugin itself.
// You will get an autocomplete using Nuxt 3.
}
});
盡情享用您的轉場元件吧!🎉
IntelliSense
使用 Nuxt 模組時,您可以跳過此章節 - 它會為您完成。
此章節僅適用於 VSCode 設定和元件的全域註冊。
搭配 Vue 2
將 Vue 2 與已安裝的 Vetur 擴充功能搭配使用時,所有元件都應提供提示,無需執行任何動作
搭配 Vue 3
將 Vue 3 與已安裝的 Volar 擴充功能搭配使用時,所有元件都應提供提示,無需執行任何動作
轉場效果列表
TransitionFade
基本轉場效果,會變更元素的 opacity
。非常簡單。
顯示程式碼
<template>
<transition-fade>
<div v-if="isVisible">...</div>
</transition-fade>
</template>
<script>
import { TransitionFade } from '@morev/vue-transitions';
export default {
components: { TransitionFade },
};
</script>
TransitionExpand
會操作實際元素大小的轉場效果。
如果您夠老,您可能會知道此轉場效果為 jQuery slideUp/slideDown
。
它也可以使用 X
軸,如 slideLeft
和 slideRight
(雖然我很難想到真正需要它的情況)。
具有獨特 prop:axis
TransitionSlide
透過 transform: translate()
操作元素位置的轉場效果。
它需要 offset
prop 來計算所需的元素位置,並且可以使用百分比值。
如何使用 offset
prop 的範例
<template>
<!--
Element will fade in and fade out to top.
Initial transform is `transform: translate(0, -16px)`
-->
<transition-slide :offset="[0, -16]"></transition-slide>
<!--
Element will fade in and fade out to bottom left side.
Initial transform is `transform: translate(-16px, 16px)`
-->
<transition-slide :offset="[-16, 16]"></transition-slide>
<!--
Element will fade in and fade out to right,
and the offset will be relative to the element width itself.
Initial transform is `transform: translate(100%, 0)`
-->
<transition-slide :offset="['100%', 0]"></transition-slide>
<!--
Element will fade in from top and fade out to bottom,
and the offset will be relative to the element height itself.
Transform before element appears: `transform: translate(0, -100%)`
Transform when element disappears: `transform: translate(0, 100%)`
-->
<transition-slide
:offset="{
enter: [0, '-100%'],
leave: [0, '100%']
}"
></transition-slide>
</template>
它會採用透過 CSS 應用於元素本身的 transform,並將其與定義的 offset 合併。
例如,當您嘗試製作置中下拉式選單時,這非常有用。
👀 顯示 `transform` 合併的範例
<template>
<div class="block">
<!--
In this case, given the CSS styles,
initial transform will be calculated to `translate(-50%, -16px)`
-->
<transition-slide :offset="[0, -16]">
<div class="block__dropdown" v-if="isVisible">
...
</div>
</transition-slide>
</div>
</template>
<style>
.block {
position: relative;
}
.block__dropdown {
position: absolute;
top: 100%;
left: 50%;
transform: translateX(-50%);
}
</style>
具有獨特 prop:offset
TransitionScale
透過 transform: scale()
操作元素 transform: scale()
的轉場效果。
預設情況下,它會將元素從 scale(1)
縮放至 scale(0)
,但此行為可透過 :scale
prop 自訂。
它會透過 axis prop 與不同軸搭配使用。
具有獨特 props:scale
、axis
、origin
顯示程式碼範例
<template>
<!--
This element appears in `x` axis and disappears in `y`
-->
<transition-scale :axis="{ enter: 'x', leave: 'y' }"></transition-scale>
<!--
This element behaves like the `transition-expand`,
but touches only `transform` property
-->
<transition-scale transform-origin="50% 0%"></transition-scale>
<!--
This element scales just a little when fading in/out.
-->
<transition-scale :scale=".8"></transition-scale>
</template>
Props
通用 props
這些屬性與每個轉場效果相關
group
此元件是否應為 transition-group
元件。
export type TransitionGroup = boolean; // Default: false
範例
<template>
<div>
<!--
To animate a list of items, use `group` prop.
⚠️ Don't forget you should pass the `:key` to each item in this case.
-->
<transition-fade group>
<div v-for="item in items" :key="item.id">...</div>
</transition-fade>
</div>
</template>
tag
轉場標籤,用於使用 transition-group
元件的情況。
export type TransitionTag = string; // Default: 'span'
範例
<template>
<div>
<!--
Passing the tag renders transition component with it.
It's suitable, for example, for rendering semantic lists:
-->
<transition-fade group tag="ul">
<li v-for="item in items" :key="item.id">...</li>
</transition-fade>
<!-- ✨ Rendered HTML: -->
<ul>
<li>...</li>
<li>...</li>
</ul>
</div>
</template>
appear
是否要在節點的初始呈現時套用轉場效果。其作用與原始 Vue 轉場 appear prop 完全相同
export type TransitionAppear = boolean; // Default: undefined
範例
<template>
<div>
<!--
This element appears when mounted if `isVisible` is `true` by default.
-->
<transition-fade appear>
<div v-if="isVisible">...</div>
</transition-fade>
</div>
</template>
mode
轉場模式.
export type TransitionMode = 'in-out' | 'out-in' | undefined; // Default: undefined
範例
<template>
<div>
<!--
Current element transitions out first, then when complete,
the new element transitions in.
-->
<transition-slide mode="out-in">
<component :is="currentComponent">...</component>
</transition-slide>
</div>
</template>
duration
轉場動畫持續時間,毫秒。
如果給定物件,則 enter
和 leave
值將分別用於進入和離開轉場。
// Default: 300
export type TransitionDuration = number | { enter: number, leave: number }
範例
<template>
<div>
<!--
If single value provided, the passed amount of milliseconds
applied to enter and leave animations both.
This element will appear and disappear within 500ms:
-->
<transition-fade :duration="500">
<div v-if="isVisible">...</div>
</transition-fade>
<!--
If an object given, it SHOULD have `enter` and `leave` keys.
This element appears in 200ms and disappears within 500ms:
-->
<transition-fade :duration="{ enter: 200, leave: 500 }">
<div v-if="isVisible">...</div>
</transition-fade>
</div>
</template>
move-duration
在使用 transition-group
的情況下,元素位置變更動畫的持續時間。
雖然 Vue 沒有透過 props 設定移動動畫持續時間的原生方式,但可以使用 CSS 自訂屬性來完成此作業。
👀 顯示說明
<!-- This way it can be set dynamically -->
<div style="--move-duration: 300ms;">
<div class="scale-move"></div>
<div class="scale-move"></div>
</div>
```
```css
.scale-move {
transition-duration: var(--move-duration, 300ms);
}
```
</details>
```ts
// Default: 300
export type TransitionMoveDuration = number;
delay
轉場動畫延遲時間,毫秒。
如果給定物件,則 enter
和 leave
值將分別用於進入和離開轉場。
// Default: 300
export type TransitionDelay = number | { enter: number, leave: number };
範例
<template>
<div>
<!--
If single value provided, then enter and leave animations will wait
for given amount of milliseconds before run.
This element will appear and disappear 100ms after
`isVisible` property changes:
-->
<transition-fade :delay="100">
<div v-if="isVisible">...</div>
</transition-fade>
<!--
If an object given, it SHOULD have `enter` and `leave` keys.
This element appears immediately and disappears 200ms after
`isVisible` property changes:
-->
<transition-fade :duration="{ enter: 0, leave: 300 }">
<div v-if="isVisible">...</div>
</transition-fade>
</div>
</template>
easing
轉場動畫 easing。應為有效的 CSS 轉場時間函式。
如果給定物件,則 enter
和 leave
值將分別用於進入和離開轉場。
export type TransitionEasing = string; // Default: 'cubic-bezier(.25, .8, .5, 1)'
範例
<template>
<div>
<!--
If single value provided, then enter and leave animations will use it:
-->
<transition-fade easing="ease-out">
<div v-if="isVisible">...</div>
</transition-fade>
<!--
If an object given, it SHOULD have `enter` and `leave` keys.
This element uses custom animation known as `bounce-in` for entering
and simple `ease-out` curve for leaving:
-->
<transition-fade
:easing="{
enter: 'cubic-bezier(0.6, 0, 0.4, 2)',
leave: 'ease-out'
}"
>
<div v-if="isVisible">...</div>
</transition-fade>
</div>
</template>
no-opacity
是否不要為元素 opacity
設定動畫。
預設情況下,每個轉場效果除了主要屬性之外,還會操作 opacity
。
但是,有時不需要這樣做 - 例如,當實作從螢幕邊緣顯示的模式面板時。
此 prop 顯然不適用於
transition-fade
元件。
export type TransitionNoOpacity = boolean; // Default: false
範例
<template>
<div>
<!--
This panel appears from the right edge of the screen,
while its transparency remains unchanged.
-->
<transition-slide :offset="['100%', 0]" no-opacity>
<div class="panel" v-if="isVisible">...</div>
</transition-slide>
</div>
</template>
<style>
.panel {
position: fixed;
top: 0;
right: 0;
bottom: 0;
background: #ffffff;
width: 400px;
}
</style>
no-move
在使用 transition-group
的情況下,是否不要為元素位置變更設定動畫。
預設情況下,當使用 group
模式時,當移除元素時,其餘元素會平滑地變更其位置。
它們被賦予絕對定位並脫離流程,因此父容器的高度會崩潰。
通常這不是問題,但有時 - 例如,當使用 transition-expand
且連續將元素放置在彼此下方時,看起來會很粗糙。
使用此選項,您可以在此情況下實現更令人愉悅的元素行為。
export type TransitionNoMove = boolean; // Default: false
範例
<template>
<div>
<!--
In this case, the height of the parent element (`ul`) changes smoothly.
-->
<transition-expand group no-move tag="ul">
<li v-for="item in items" :key="item.id">...</li>
</transition-expand>
</div>
</template>
TransitionExpand
的獨特 props
axis
元素應展開的軸。
如果給定物件,則 enter
和 leave
值將分別用於進入和離開轉場。
type ExpandAxisValue = 'x' | 'y'; // Default: 'y'
export type TransitionExpandAxis = ExpandAxisValue | { enter: ExpandAxisValue, leave: ExpandAxisValue }
TransitionSlide
的獨特 props
offset
轉場效果之前/之後,元素在 x
和 y
軸上的偏移。
應為整數或百分比值的字串表示法(例如 '100%'
)。
數值會被視為 px
偏移,以 %
符號結尾的字串值會被視為 元素寬度/高度的百分比
。
範例和說明
如果給定物件,則 enter
和 leave
值將分別用於進入和離開轉場。
type SlideOffsetValue = [number | string, number | string];
// Default: [0, -16]
export type TransitionSlideOffset = SlideOffsetValue | { enter: SlideOffsetValue, leave: SlideOffsetValue }
TransitionScale
的獨特 props
axis
要設定動畫的縮放軸。
* `both` (uses `transform: scale()`)
* `x` (uses `transform: scaleX()`)
* `y` (uses `transform: scaleY()`)
如果給定物件,則 enter
和 leave
值將分別用於進入和離開轉場。
type ScaleAxisValue = 'x' | 'y' | 'both';
// Default: 'both'
export type TransitionScaleAxis = ScaleAxisValue | { enter: ScaleAxisValue, leave: ScaleAxisValue }
origin
套用至元素的 transform-origin
CSS 屬性。\
如果給定物件,則 enter
和 leave
值將分別用於進入和離開轉場。
如果給定物件,則 enter
和 leave
值將分別用於進入和離開轉場。
// Default: '50% 50%'
export type TransitionScaleAxis = string | { enter: string, leave: string }
scale
轉場效果之前/之後的元素縮放值。應為介於 0
和 1
之間的數字。
如果給定物件,則 enter
和 leave
值將分別用於進入和離開轉場。
如果給定物件,則 enter
和 leave
值將分別用於進入和離開轉場。
// Default: 0
export type TransitionScaleScale = number | { enter: number, leave: number }
事件
元件不提供任何特殊事件,但會觸發所有標準轉場事件
before-enter
enter
after-enter
enter-cancelled
before-leave
leave
after-leave
enter-leave