Vue中的动画
为什么要有动画:动画能够提高用户的体验,帮助用户更好的理解页面中的功能;
使用过渡类名
<template> <div class="home"> <!-- 点击 切换显示隐藏 PS:不使用动画--> <input type="button" value="toggle" @click="flag = !flag" /> <h3 v-if="flag">何以致契阔,绕腕双跳脱</h3> </div> </template> <script> export default { data() { return { flag: false } } } </script>
<template> <div class="home"> <!-- 点击 切换显示隐藏 PS:不使用动画--> <input type="button" value="toggle" @click="flag = !flag" /> <!-- 使用transtition元素,把需要被动画控制的元素包裹起来 --> <transition> <!-- <h3 v-if="flag">何以致契阔,绕腕双跳脱</h3> --> <div style="height:200px,350px"> <img v-if="flag" src="../assets/wallhaven-lm2762.webp" style="100%,height:100%" /> </div> </transition> </div> </template> <script> export default { data() { return { flag: false } } } </script> <style scoped> /*自定义两组样式控制trantition内部的实现动画*/ /*v-enter [这是一个时间点]是进入前元素的起始状态,此时元素还没开始进入*/ /*v-leave-to [这是一个时间点]是动画离开之后离开的终止状态,此时元素动画已经结束了*/ .v-enter, .v-leave-to { opacity: 0; transform: translateY(80px); } /*一个是入场动画时间段,一个是离场动画时间段*/ .v-enter-active, .v-leave-active { transition: all 0.8s ease; } div img { max-width: 100%; height: auto; } </style>
使用了第三方css动画库,animate.css
安装及使用方式参考animate官方文档
自定义不以v-开头
<template> <div class="home"> <!-- 点击 切换显示隐藏 PS:不使用动画--> <input type="button" value="双跳脱" @click="flag = !flag" style="background-color:#94d1b4" /> <!-- 使用transtition元素,把需要被动画控制的元素包裹起来 --> <transition> <h3 v-if="flag">何以致契阔,绕腕双跳脱</h3> <!-- <div style="height:200px,350px"> <img v-if="flag" src="../assets/wallhaven-lm2762.webp" style="100%,height:100%" /> </div> --> </transition> <hr /> <input type="button" value="石榴裙" @click="flag2 = !flag2" style="background-color:#db7171" /> <transition name="my"> <h6 v-if="flag2">开箱验取石榴裙</h6> </transition> </div> </template> <script> export default { data() { return { flag: false, flag2: false } } } </script> <style scoped> /*自定义两组样式控制trantition内部的实现动画*/ /*v-enter [这是一个时间点]是进入前元素的起始状态,此时元素还没开始进入*/ /*v-leave-to [这是一个时间点]是动画离开之后离开的终止状态,此时元素动画已经结束了*/ .v-enter, .v-leave-to { opacity: 0; transform: translateY(80px); } /*一个是入场动画时间段,一个是离场动画时间段*/ .v-enter-active, .v-leave-active { transition: all 0.8s ease; } div img { max-width: 100%; height: auto; } .my-enter, .my-leave-to { opacity: 0; transform: translateX(100px); /* transform: translateY(80px); */ } /*一个是入场动画时间段,一个是离场动画时间段*/ .my-enter-active, .my-leave-active { transition: all 1s ease; } </style>
<template> <div class="home"> <!-- 点击 切换显示隐藏 PS:不使用动画--> <input type="button" value="toggle" @click="flag = !flag" /> <!-- 使用transtition元素,把需要被动画控制的元素包裹起来 --> <transition leave-active-class="animate__bounceOut" enter-active-class="animate__bounceIn" :duration="{ enter: 400, leave: 600 }" > <h3 v-if="flag">何以致契阔,绕腕双跳脱</h3> </transition> </div> </template> <script> export default { data() { return { flag: false } } } </script> <style scoped> /*自定义两组样式控制trantition内部的实现动画*/ /*v-enter [这是一个时间点]是进入前元素的起始状态,此时元素还没开始进入*/ /*v-leave-to [这是一个时间点]是动画离开之后离开的终止状态,此时元素动画已经结束了*/ .v-enter, .v-leave-to { opacity: 0; transform: translateY(80px); } /* .v-enter-active { animation: animate__bounceIn; } .v-leave-active { animation: bounceOut;; } */ /*一个是入场动画时间段,一个是离场动画时间段*/ </style>
<transition-group>
组件还有一个特殊之处。不仅可以进入和离开动画,还可以改变定位。要使用这个新功能只需了解新增的 v-move
特性,它会在元素的改变定位的过程中应用。
v-move
和 v-leave-active
结合使用,能够让列表的过渡更加平缓柔和
<template> <div> <div> <label> Id: <input type="text" v-model="id" /> </label> <label> Name: <input type="text" v-model="name" /> </label> <input type="button" value="收录" @click="add" /> </div> <!-- 在实现列表动画过渡不能使用transition包裹,应该使用transitionGroup --> <transition-group appear tag="ul"> <li v-for="(item, i) in list" :key="item.id" @click="del(i)"> {{ item.id }}------------------{{ item.name }} </li> </transition-group> </div> </template> <script> export default { data() { return { id: '', name: '', list: [ { id: 1, name: '香妃链' }, { id: 2, name: '水苍玉' }, { id: 3, name: '延圭墨' }, { id: 4, name: '留青梳' }, { id: 5, name: '铜权衡' } ] } }, methods: { add() { this.list.push({ id: this.id, name: this.name }) this.id = this.name = ' ' }, del(i) { this.list.splice(i, 1) } } } </script> <style scoped> li { width: 100%; border: 1px dashed #376f4a; margin: 5px; line-height: 35px; padding-left: 5px; font-size: 14px; list-style-type: none; } li:hover { background-color: rgb(38, 141, 236); transition: all 1s ease; } .v-enter, .v-leave-to { opacity: 0; transform: translateY(80px); } .v-enter-active, .v-leave-active { transition: all 1s ease; } .v-move { transition: all 1s ease; } .v-leave-active { position: absolute; } </style>
组件
使用flag标识符结合v-if和v-else切换组件
使用:is属性来切换不同的子组件并添加动画
<template> <div> <!-- <a @click.prevent="flag = true">登录</a> <a @click.prevent="flag = false">注册</a> <dlu v-if="flag"></dlu> <z v-else></z> --> <!-- Vue提供了 component 来展示对应名称的组件--> <!-- component是一个占位符,:is属性可以用来指定要展示的组件名称 --> <a @click="comName = 'dlu'">双跳脱</a> <hr /> <a @click="comName = 'z'">大红袍</a> <component :is="comName"></component> </div> </template> <script> import dlu from '@/components/deng' import z from '@/components/zhu' export default { data() { return { //flag: false comName: '' } }, components: { dlu, z } } </script> <style scoped></style>
<template> <div> <a @click="comName = 'dlu'">双跳脱</a> <hr /> <a @click="comName = 'z'">大红袍</a> <transition mode="out-in"> <component :is="comName"></component> </transition> </div> </template> <script> import dlu from '@/components/deng' import z from '@/components/zhu' export default { data() { return { //flag: false comName: '' } }, components: { dlu, z } } </script> <style scoped> .v-enter, .v-leave-to { opacity: 0; transform: translateX(150px); } .v-enter-active, .v-leave-active { transition: all 0.5s ease; } </style>
子组件与父组件
father.vue
<template> <!-- 父组件可以引用子组件的时候通过绑定v-bind的形式 把需要传递给子组件的数据以属性绑定的形式传到子组件内部供子组件使用--> <!-- 父组件向子组件传递方法用的是事件绑定机制 v-on 等同于@ ,当我们自定义一个事件属性后子组件就能调用--> <son v-bind:fathermsg="msg" @func="show"></son> </template> <script> import son from '@/components/son' export default { name: 'father', components: { son }, data() { return { msg: '双跳脱', datamsgFromson: null } }, methods: { // show(data, data2) { // console.log('曲有误,周郎顾' + data + data2) // } show(data) { //console.log(data)//获取对象 this.datamsgFromson = data } } } </script> <style scoped></style>
son.vue
<template> <div> <h1>何以致契阔,绕腕双跳脱 ---- {{ fathermsg }}</h1> <input type="button" value="留青梳" @click="myclick" /> </div> </template> <script> export default { name: 'son', data() { return { sonmsg: { name: '赤龙服', age: 2000 } } }, methods: { myclick() { //emit译文:触发调用 this.$emit('func', this.sonmsg) //子组件调用父组件方法并向父组件传参 } }, props: ['fathermsg'] //props中的数据都是只读,此处记住props与methods是平级,放进去会报错 } </script> <style scoped></style>
评论列表案例
练习父子组件传值
<template> <div> <ul> <li v-for="item in list" :key="item.id"> <span>评论人:{{ item.user }}</span> {{ item.content }} </li> </ul> <pson @func="loadComment"></pson> </div> </template> <script> import pson from '@/components/pingls' export default { components: { pson }, data() { return { list: [ { id: Date.now(), user: 'viivn', content: 'safe and sound' }, { id: Date.now(), user: 'echo', content: 'safe and sound' }, { id: Date.now(), user: 'Aurora', content: 'safe and sound' } ] } }, created() { this.loadComment() }, methods: { loadComment() { //加载评论 let list = JSON.parse(localStorage.getItem('cmts') || '[]') this.list = list } } } </script>
<template> <div> <div> <label>评论人</label> <input type="text" v-model="user" /> </div> <div> <label>评论内容</label> <textarea v-model="content"></textarea> </div> <div> <input type="button" value="发表评论" @click="postComment" /> </div> </div> </template> <script> export default { name: 'pson', data() { return { user: '', content: '' } }, methods: { postComment() { //发表评论 let comment = { id: Date.now(), user: this.user, content: this.content } //从localStorage中获取所有评论 let list = JSON.parse(localStorage.getItem('cmts') || '[]') list.unshift(comment) localStorage.setItem('cmts', JSON.stringify(list)) this.user = this.comment = '' this.$emit('func') //this.loadComment() } } } </script>
使用this,$refs来获取元素和组件
<template> <div> <input type="button" value="收录" @click="getElement" ref="mybtn" /> <h3 id="myh3" ref="myh3">何以致契阔,绕腕双跳脱</h3> <hr /> <login ref="mylogin"></login> </div> </template> <script> import login from '@/components/login' export default { data() { return {} }, components: { login }, methods: { getElement() { //console.log(document.getElementById('myh3').innerText) // ref 是英文单词reference 值类型和引用类型referenceError //console.log(this.$refs.myh3.innerText) this.$refs.mylogin.show() } } } </script> <style scoped></style>
<template> <h1>双跳脱</h1> </template> <script> export default { name: 'login', data() { return { msg: 'son msg' } }, methods: { show() { console.log('调用了子组件的方法') } } } </script>
今天先更这么多.......
(miss......)