一、Vue 基础之过渡动画、单元素组件的过渡动画、组件及元素切换动画、列表动画和状态动画
- 过渡和动画,如下所示:
const app = Vue.createApp({
data() {
return {
styleObj: {
background: 'blue'
}
}
},
methods: {
handleClick() {
if (this.styleObj.background === 'blue') {
this.styleObj.background = 'green';
} else {
this.styleObj.background = 'blue'
}
}
},
template: `
<div>
<div class="transition" :style="styleObj">hello world</div>
<button @click="handleClick">切换</button>
</div>
`
});
const vm = app.mount('#root');
@keyframs leftToRight {
0% {
transform: translateX(-100px);
}
50% {
transform: translateX(-50px);
}
0% {
transform: translateX(0px);
}
}
.animation {
animation: leftToRight 3s;
}
.transition {
transition: 3s background-color ease;
}
.blue {
background: blue;
}
.green {
background: green;
}
- 单元素、单组件的入场出场动画,如下所示:
const app = Vue.createApp({
data() {
return {
show: false
}
},
methods: {
handleClick() {
this.show = !this.show;
}
},
template: `
<div>
<transition
// enter-active-class="hello"
// leave-active-class="bye"
:duration="{enter: 1000, leave: 3000}"
>
<div v-if="show">hello world</div>
</transition>
<button @click="handleClick">切换</button>
</div>
`
});
const vm = app.mount('#root');
@keyframs shake {
0% {
transform: translateX(-100px);
}
50% {
transform: translateX(-50px);
}
100% {
transform: translateX(50px);
}
}
.v-enter-from {
color: red;
}
.v-enter-active {
animation: shake 3s;
transition: color 3s ease-in;
}
.v-leave-from {
color: back;
}
.v-leave-active {
animation: shake 3s;
transition: color 3s ease-in;
}
- 组件
JS 实现入场出场动画,before-enter 可以接收 el,enter 可以接收 el 和 done,after-enter 可以接收 el,before-leave 可以接收 el,leave 可以接收 el 和 done,leave-after 可以接收 el,如下所示:
const app = Vue.createApp({
data() {
return {
show: false
}
},
methods: {
handleClick() {
this.show = !this.show;
},
handleBeforeEnter(el) {
el.style.color = 'red';
},
handleEnterActive(el, done) {
const animation = setInterval(() => {
const color = el.style.color;
if (color === 'red') {
el.style.color = 'green';
} else {
el.style.color = 'red';
}
}, 1000)
setTimeout(() => {
clearInterval(animation)
}, 3000)
},
handleEnterEnd(el) {
alert('123');
}
},
template: `
<div>
<transition
:css="false"
@before-enter="handleBeforeEnter"
@enter="handleEnterActive"
@after-enter="handleEnterEnd"
@before-leave="handleBeforeLeave"
@leave="handleLeave"
@leave-after="handleLeaveAfter"
>
<div v-if="show">hello world</div>
</transition>
<button @click="handleClick">切换</button>
</div>
`
});
const vm = app.mount('#root');
- 多个单元素标签之间的切换,多个单组件之间的切换,如下所示:
const ComponentA = {
template: `<div>hello world</div>`
};
const ComponentB = {
template: `<div>hello world</div>`
};
const app = Vue.createApp({
data() {
return { component: 'component-a' }
},
methods: {
handleClick() {
if (this.component === 'component-a') {
this.component === 'component-b';
} else {
this.component === 'component-a';
}
},
},
components: {
'component-a': ComponentA,
'component-b': ComponentB,
},
template: `
<div>
<transition mode="out-in" appear>
<component :is="component" />
</transition>
<button @click="handleClick">切换</button>
</div>
`
});
const vm = app.mount('#root');
.v-leave-to {
opacity: 0;
}
.v-enter-from {
opacity: 0;
}
.v-enter-active, .v-leave-active {
transition: opacity 1s ease-in;
}
.v-leave-from, .v-enter-to {
opacity: 1;
}
- 列表动画,如下所示:
const app = Vue.createApp({
data() {
return { list: [1, 2, 3] }
},
methods: {
handleClick() {
this.list.unshift(this.list.length + 1);
},
},
template: `
<div>
<transition-group>
<span class="list-item" v-for="item in list" :key="item">{{item}}</span>
</transition-group>
<button @click="handleClick">增加</button>
</div>
`
});
const vm = app.mount('#root');
.v-enter-from {
opacity: 0;
transform: translateY(30px);
}
.v-enter-active {
transition: all .5s ease-in;
}
.v-enter-to {
opacity: 1;
transform: translateY(0);
}
.v-move {
transition: all .5s ease-in;
}
.list-item {
display: inline-block;
margin-right: 10px;
}
- 状态动画,通过数据控制内容的展示,不断通过改变数据的动画,如下所示:
const app = Vue.createApp({
data() {
return {
number: 1,
animateNumber: 1
}
},
methods: {
handleClick() {
this.number = 10;
if (this.animateNumber < this.number) {
const animation = setInterval(() => {
this.animateNumber += 1;
if (this.animateNumber === 10) {
clearInterval(animation);
}
}, 100);
}
},
},
template: `
<div>
<div>{{animateNumber}}</div>
<button @click="handleClick">增加</button>
</div>
`
});