Skip to content

Commit 76410d5

Browse files
committed
list transitions
1 parent fe58596 commit 76410d5

16 files changed

+702
-206
lines changed

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
"dependencies": {
88
"@vue/repl": "^0.4.7",
99
"@vue/theme": "^0.1.23",
10+
"gsap": "^3.9.0",
1011
"vitepress": "^0.20.9",
1112
"vue": "^3.2.25"
1213
},

pnpm-lock.yaml

Lines changed: 6 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/.vitepress/config.ts

Lines changed: 68 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -555,14 +555,25 @@ export default defineConfig({
555555
},
556556
build: {
557557
minify: 'terser',
558-
chunkSizeWarningLimit: Infinity
558+
chunkSizeWarningLimit: Infinity,
559+
rollupOptions: {
560+
output: {
561+
manualChunks(id, ctx) {
562+
if (id.includes('gsap')) {
563+
return 'gsap'
564+
}
565+
return moveToVendor(id, ctx)
566+
}
567+
}
568+
}
559569
},
560570
json: {
561571
stringify: true
562572
}
563573
},
564574

565575
vue: {
576+
reactivityTransform: true,
566577
template: {
567578
compilerOptions: {
568579
directiveTransforms: {
@@ -572,3 +583,59 @@ export default defineConfig({
572583
}
573584
}
574585
})
586+
587+
const cache = new Map<string, boolean>()
588+
589+
/**
590+
* This is temporarily copied from Vite - which should be exported in a
591+
* future release.
592+
*
593+
* @TODO when this is exported by Vite, VitePress should ship a better
594+
* manual chunk strategy to split chunks for deps that are imported by
595+
* multiple pages but not all.
596+
*/
597+
function moveToVendor(id: string, { getModuleInfo }: any) {
598+
if (
599+
id.includes('node_modules') &&
600+
!/\.css($|\\?)/.test(id) &&
601+
staticImportedByEntry(id, getModuleInfo, cache)
602+
) {
603+
return 'vendor'
604+
}
605+
}
606+
607+
function staticImportedByEntry(
608+
id: string,
609+
getModuleInfo: any,
610+
cache: Map<string, boolean>,
611+
importStack: string[] = []
612+
): boolean {
613+
if (cache.has(id)) {
614+
return cache.get(id) as boolean
615+
}
616+
if (importStack.includes(id)) {
617+
// circular deps!
618+
cache.set(id, false)
619+
return false
620+
}
621+
const mod = getModuleInfo(id)
622+
if (!mod) {
623+
cache.set(id, false)
624+
return false
625+
}
626+
627+
if (mod.isEntry) {
628+
cache.set(id, true)
629+
return true
630+
}
631+
const someImporterIs = mod.importers.some((importer: string) =>
632+
staticImportedByEntry(
633+
importer,
634+
getModuleInfo,
635+
cache,
636+
importStack.concat(id)
637+
)
638+
)
639+
cache.set(id, someImporterIs)
640+
return someImporterIs
641+
}

src/guide/built-ins/keep-alive.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
11
# KeepAlive
22

3+
## Basic Usage
4+
5+
:::tip
6+
When used in [DOM templates](/guide/essentials/component-basics.html#dom-template-parsing-caveats), it should be referenced as `<keep-alive>`.
7+
:::
8+
39
Earlier, we used the `is` attribute to switch between components in a tabbed interface:
410

511
```vue-html
@@ -28,3 +34,7 @@ Check out the result below:
2834
Now the _Posts_ tab maintains its state (the selected post) even when it's not rendered.
2935

3036
Check out more details on `<keep-alive>` in the [API reference](/api/built-in-components.html#keep-alive).
37+
38+
## Include / Exclude
39+
40+
## Max Cached Instances
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
<script setup>
2+
let show = $ref(true)
3+
</script>
4+
5+
<template>
6+
<div class="demo">
7+
<button @click="show = !show">Toggle Fade</button>
8+
<Transition name="fade">
9+
<p style="margin-top: 20px" v-if="show">hello</p>
10+
</Transition>
11+
</div>
12+
</template>
13+
14+
<style>
15+
.fade-enter-active,
16+
.fade-leave-active {
17+
transition: opacity 0.5s ease;
18+
}
19+
20+
.fade-enter-from,
21+
.fade-leave-to {
22+
opacity: 0;
23+
}
24+
</style>
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
<script setup>
2+
import { h } from 'vue'
3+
4+
const CompA = () => h('div', 'Component A')
5+
const CompB = () => h('div', 'Component B')
6+
7+
let activeComponent = $ref(CompA)
8+
</script>
9+
10+
<template>
11+
<div class="demo">
12+
<label>
13+
<input type="radio" v-model="activeComponent" :value="CompA" /> A
14+
</label>
15+
<label>
16+
<input type="radio" v-model="activeComponent" :value="CompB" /> B
17+
</label>
18+
<Transition name="fade" mode="out-in">
19+
<component :is="activeComponent"></component>
20+
</Transition>
21+
</div>
22+
</template>
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
<script setup>
2+
const { mode } = defineProps(['mode'])
3+
4+
let docState = $ref('saved')
5+
</script>
6+
7+
<template>
8+
<div class="demo transition-demo">
9+
<span style="margin-right: 20px">Click to cycle through states:</span>
10+
<div class="btn-container">
11+
<Transition name="slide-up" :mode="mode">
12+
<button v-if="docState === 'saved'" @click="docState = 'edited'">
13+
Edit
14+
</button>
15+
<button v-else-if="docState === 'edited'" @click="docState = 'editing'">
16+
Save
17+
</button>
18+
<button v-else-if="docState === 'editing'" @click="docState = 'saved'">
19+
Cancel
20+
</button>
21+
</Transition>
22+
</div>
23+
</div>
24+
</template>
25+
26+
<style>
27+
.transition-demo {
28+
display: flex;
29+
align-items: center;
30+
}
31+
32+
.transition-demo .btn-container {
33+
display: inline-block;
34+
position: relative;
35+
height: 36px;
36+
}
37+
38+
.transition-demo button {
39+
position: absolute;
40+
}
41+
42+
.transition-demo button + button {
43+
margin: 0;
44+
}
45+
46+
.transition-demo .slide-up-enter-active,
47+
.transition-demo .slide-up-leave-active {
48+
transition: all 0.25s ease-out;
49+
}
50+
51+
.slide-up-enter-from {
52+
opacity: 0;
53+
transform: translateY(30px);
54+
}
55+
56+
.slide-up-leave-to {
57+
opacity: 0;
58+
transform: translateY(-30px);
59+
}
60+
</style>
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
<script setup>
2+
let show = $ref(true)
3+
</script>
4+
5+
<template>
6+
<div class="demo">
7+
<button @click="show = !show">Toggle</button>
8+
<Transition name="bounce">
9+
<p v-if="show" style="margin-top: 20px; text-align: center;">
10+
Hello here is some bouncy text!
11+
</p>
12+
</Transition>
13+
</div>
14+
</template>
15+
16+
<style>
17+
.bounce-enter-active {
18+
animation: bounce-in 0.5s;
19+
}
20+
.bounce-leave-active {
21+
animation: bounce-in 0.5s reverse;
22+
}
23+
@keyframes bounce-in {
24+
0% {
25+
transform: scale(0);
26+
}
27+
50% {
28+
transform: scale(1.25);
29+
}
30+
100% {
31+
transform: scale(1);
32+
}
33+
}
34+
</style>
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
<script setup>
2+
import gsap from 'gsap'
3+
4+
let show = $ref(true)
5+
6+
function onBeforeEnter(el) {
7+
gsap.set(el, {
8+
scaleX: 0.25,
9+
scaleY: 0.25,
10+
opacity: 1
11+
})
12+
}
13+
14+
function onEnter(el, done) {
15+
gsap.to(el, {
16+
duration: 1,
17+
scaleX: 1,
18+
scaleY: 1,
19+
ease: 'elastic.inOut(2.5, 1)',
20+
onComplete: done
21+
})
22+
}
23+
24+
function onLeave(el, done) {
25+
gsap.to(el, {
26+
duration: 0.7,
27+
scaleX: 1,
28+
scaleY: 1,
29+
x: 300,
30+
ease: 'elastic.inOut(2.5, 1)'
31+
})
32+
gsap.to(el, {
33+
duration: 0.2,
34+
delay: 0.5,
35+
opacity: 0,
36+
onComplete: done
37+
})
38+
}
39+
</script>
40+
41+
<template>
42+
<div class="demo">
43+
<button @click="show = !show">Toggle</button>
44+
45+
<Transition
46+
@before-enter="onBeforeEnter"
47+
@enter="onEnter"
48+
@leave="onLeave"
49+
:css="false"
50+
>
51+
<div class="gsap-box" v-if="show"></div>
52+
</Transition>
53+
</div>
54+
</template>
55+
56+
<style>
57+
.gsap-box {
58+
background: var(--vt-c-green);
59+
margin-top: 20px;
60+
width: 30px;
61+
height: 30px;
62+
border-radius: 50%;
63+
}
64+
</style>
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
<script setup>
2+
import { reactive } from 'vue'
3+
4+
const items = reactive([1, 2, 3, 4, 5])
5+
let nextNum = items.length + 1
6+
7+
function add() {
8+
items.splice(randomIndex(), 0, nextNum++)
9+
}
10+
11+
function remove() {
12+
items.splice(randomIndex(), 1)
13+
}
14+
15+
function randomIndex() {
16+
return Math.floor(Math.random() * items.length)
17+
}
18+
</script>
19+
20+
<template>
21+
<div class="demo">
22+
<button @click="add">Add at random index</button>
23+
<button @click="remove">Remove at random index</button>
24+
<TransitionGroup name="list" tag="ul" style="margin-top: 20px">
25+
<li v-for="item in items" :key="item">
26+
{{ item }}
27+
</li>
28+
</TransitionGroup>
29+
</div>
30+
</template>
31+
32+
<style>
33+
.list-enter-active,
34+
.list-leave-active {
35+
transition: all 0.5s ease;
36+
}
37+
.list-enter-from,
38+
.list-leave-to {
39+
opacity: 0;
40+
transform: translateX(30px);
41+
}
42+
</style>

0 commit comments

Comments
 (0)