Vue--列表过渡和动画封装

900 阅读3分钟

列表过渡

在vue中使用列表时我们往往也需要设置一个过渡效果

代码准备

首先我们需要写一个简单的通过点击可以增加列表项的代码

<div id="root">
	<div v-for="(item,index) of list" :key="item.id">
		{{item.title}}
	</div>
	<button @click="handleBtnClick">冲冲冲</button>
</div>

<script type="text/javascript">
	var count = 0;

	var vm = new Vue({
		el:'#root',
		data:{
			list:[]
		},
		methods:{
			handleBtnClick:function(){
				this.list.push({
					id:count++,
					title:'hello world'
				})
			}
		}
	})
</script>

这段代码我们通过v-for完成了一个列表项目

注意: 使用v-for时要尽量避免使用index作为key值

添加包裹标签

之前我们的过渡动画效果都使用了<transition>标签包裹,对于列表项一样,使用<transition-group>标签包裹

<transition-group name="fade">
	<div v-for="(item,index) of list" :key="item.id">
		{{item.title}}
	</div>
</transition-group>

我们通过添加列表项之后的页面为

<div></div>
<div></div>
<div></div>
...

而添加了该标签后相当于变成了

<transition>
    <div></div>
</transition>
<transition>
    <div></div>
</transition>
<transition>
    <div></div>
</transition>
...

添加动画效果CSS样式

与之前各种内容的过渡动画样式相同

<style type="text/css">
	.fade-enter,.fade-leave-to{
		opacity: 0
	}
	.fade-enter-active, .fade-leave-active{
		transition:opacity 1s;
	}
</style>

使用CSS动画封装

代码准备

<body>
	<div id="root">
		<transition >
			<div v-if="show">pretty girl</div>
		</transition>
		<button @click="handleclick">o baby</button>
	</div>

	<script type="text/javascript">
		var vm = new Vue({
			el:"#root",
			data:{
				show:true
			},
			methods:{
				handleclick:function(){
					this.show=!this.show
				}
			}
		})
	</script>
</body>
<style type="text/css">
	.v-enter,.v-leave-to{
		opacity: 0
	}
	.v-enter-active,.v-leave-active{
		transition: opacity 1s
	}
</style>

对动画进行封装

  • 首先我们定义一个名叫fade的组件
  • 组件的模板内容为之前的<transition >标签
  • 我们在<transition >标签内放一个插槽,代表标签内的DOM元素是由外部传入的
  • 我们还要声明一个show变量,也是由外部传入的,他来决定插槽的内容是否显示
Vue.component('fade',{
	props:['show'],
	template:`
		<transition >
			<slot v-if="show"></slot>
		</transition>
	`
})

修改添加动画的代码

  • 我们使用子组件fade来包裹待加标签的内容
  • 并传入向子组件传入一个show的参数,决定是否显示div内容
<div id="root">
	<fade :show="show">
		<div>pretty girl</div>
	</fade>
	<button @click="handleclick">o baby</button>
</div>

使用js动画封装

我们在CSS封装的基础上进行js封装的改动

删除CSS样式

改动子组件模板

与js动画效果的代码编写一样,我们需要给钩子绑定对应的函数

template:`
	<transition @before-enter="handleBeforeEnter" @enter = "handleEnter">
		<slot v-if="show"></slot>
	</transition>
`,

定义动画钩子函数

同样的我们也可以使用velocity.js库

methods:{
	handleBeforeEnter:function(el){
		el.style.color = 'red'
	},
	handleEnter:function(el,done){
		setTimeout(()=>{
			el.style.color='green'
			done()
		},2000)
	}
}

JS动画封装好处

使用JS动画封装时,有关于这个动画的所有相关代码都被编写在子组件的内容当中,不需要在全局去编写style样式

完整代码

<body>
	<div id="root">
		<fade :show="show">
			<div>pretty girl</div>
		</fade>
		<button @click="handleclick">o baby</button>
	</div>

	<script type="text/javascript">
		Vue.component('fade',{
			props:['show'],
			template:`
				<transition @before-enter="handleBeforeEnter" @enter = "handleEnter">
					<slot v-if="show"></slot>
				</transition>
			`,
			methods:{
				handleBeforeEnter:function(el){
					el.style.color = 'red'
				},
				handleEnter:function(el,done){
					setTimeout(()=>{
						el.style.color='green'
						done()
					},2000)
				}
			}
		})

		var vm = new Vue({
			el:"#root",
			data:{
				show:true
			},
			methods:{
				handleclick:function(){
					this.show=!this.show
				}
			}
		})
	</script>
</body>