Vue的组件、动画

目录

组件

        简介:

        全局组件

        局部组件

        props传递参数

        监听子组件发出的事件

            

        组件的插槽

        具名插槽

        作用域插槽

        弹框组件

动画transition

        动画

        动画-过渡class

        动画-使用关键帧动画

        动画-引入第三方

        动画模式

        列表过渡


组件

        简介:

                通常一个应用会以一棵嵌套的组件树的形式来组织:

        全局组件

                
    directives指令
    组件:一个小的功能分区
    意义:复杂项目拆分简单的组件
    让团队开发更高效
    组件是可以重复使用的模块
    
    理解:组件其实就是小的Vue,具有data,methods watch computed
    组件的定义:
        const strper = {template:`<span>...</span>`}
        
    组件注册:
        componentd:{steper}
        
    组件的参数传递:
        父传子 props
            <strper :value="5">
            strper内部
                props:{type:nuber,default}
            steper内部使用 (只读,不修改)
                this.value
        子传父
            在steper内部
                this.$emit("numchange",this.num)
                numchange事件名称 this,num 事件值
            父组件
                <steper @numchange="w1=$event">
                $event就是子组件通过numchange传递过来的值this.num

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
		<script src="./js/vue.js" type="text/javascript" charset="utf-8"></script>
	</head>
	<body>
		<div id="app">
			<steper :value="w1" @numchange="w1=$event"></steper><br>
			<steper :value="w2" @numchange="w2=$event"></steper><br>
			<p :style="{'width':w1+'px','height':w1+'px',borderRadius:w1+'px',border:'1px solid red'}"></p>
			<p :style="{'width':w2+'px','height':w2+'px',borderRadius:w2+'px',border:'1px solid green'}"></p>
		</div>
		<script>
		//定义组件
		//组件父传子 props(props是只读的)
			const steper={
				template:`<span>
				<button @click="num--">-</button>
				<input v-model.number="num" />
				<button @click="num++">+</button>
				</span>`,
				data(){
					return{num:this.value}
				},
				props:{
					value:{
						type:Number,	//value的类型是数字
						default:1		//默认值
					}
				},
				watch:{
					"num":{
						handler:function(nval,oval){
							this.$emit("numchange",this.num)
						},
						deep:true
					}
				}
			}
			Vue.createApp({
				components:{steper},
				data(){
					return{
						w1:30,
						w2:20
					}
				}
			}).mount("#app")
		</script>
	</body>
</html>

        局部组件

定义组件
const step = {
	template:`<div><button @click="n--">-</button>{{n}}<button @click="n++">+</button></div>`,
	data(){return {n:1}}
}

        注册组件 

const app = Vue.createApp({	
	components:{step}
})

        使用组件

<step></step>
<step></step>

        props传递参数

        对象与数组的默认值必须是函数的返回值

        传递

<step :num="10"></step>
<step :num="5"></step>

        接收

props:{
    "num":{type:Number,default:1}
},

        使用

data(){return {n:this.num}}

        监听子组件发出的事件

                通常你希望每个 prop 都有指定的值类型。这时,你可以以对象形式列出 prop

                String

                Number

                Boolean

                Array

                Object

                Date

                Function

                symbol

            

        组件的插槽

                和 HTML 元素一样,我们经常需要向一个组件传递内容

                我们使用 <slot> 作为我们想要插入内容的占位符

<step>
     你好,我是嵌套内容
</step>
 template:`<div><h1>组件的标题</h1><slot></slot></div>`

        具名插槽

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title>命名插槽</title>
		<script src="./js/vue.js" type="text/javascript" charset="utf-8"></script>
	</head>
	<body>
		<div id="app">
			<price>
				<template v-slot:pre>
					¥
				</template>
				<template v-slot:next>
					元
				</template>
			</price><br>
			<price>
				<template v-slot:pre>
					$
				</template>
				<template v-slot:next>
					刀
				</template>
			</price>
		</div>
		<script>
			const price = {
				template:`<span><slot name="pre"></slot>100<slot name="next"></slot></span>`
			}
			Vue.createApp({
				components:{
					price
				},
				data(){
					
				}
			}).mount("#app")
		</script>
	</body>
</html>
<!-- 
	插槽
		<step>
			嵌套内容
		</step>
		
		可以通过<slot></slot>获取组件的嵌套内容
	命名插槽
		<step>
			<template>
				pre插槽内容
			<template>
		<step>
		<slot name="pre">
	插槽的作用域
		子
			<slot item="item">
		父
			<step>
				<template v-slot:default="scope">
					{{scope.item}}
				</template>
			</step>
	
	directives指令
		自定义指令,访问到dom节点
		directives:{
			"focus":{
				mounted(el,binding){
					el当前指令所在的dom
					binding指令相关信息
					binding.value指令的值
				}
			}
		}
		钩子函数
			created:创建
			beforeMount:父组件挂载前
			mounted:挂在后
			before
	计算computed
		从现有数据,计算出新的数据(只读)
		computed:{
			"rmsg":function(){
				return this.msg.splice("").reverse().join("")
			}
		}
 -->

        作用域插槽

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title>命名插槽</title>
		<script src="./js/vue.js" type="text/javascript" charset="utf-8"></script>
	</head>
	<body>
		<div id="app">
			<ls>
				<template v-slot:default="scope">
					<span>{{scope.index+1}}列表{{scope.item}}</span>
				</template>
			</ls>
		</div>
		<script>
			const ls = {
				template:`<div>
					<p v-for="(item,index) in list">
						<slot :item="item" :index="index"></slot>
					</p>
				</div>`,
				data(){
					return{
						list:["list","react","angular"]
					}
				}
			}
			Vue.createApp({
				components:{
					ls
				},
				data(){
					
				}
			}).mount("#app")
		</script>
	</body>
</html>

        弹框组件

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
		<link rel="stylesheet" type="text/css" href="./modal/index.css"/>
		<script src="./js/vue.js" type="text/javascript" charset="utf-8"></script>
	</head>
	<body>
		<div id="app">
			<button @click="isShowModal=true">弹框</button>
			<button @click="showModal=true">弹框2</button>
			<modal :visible="isShowModal" @update:visible="isShowModal=$event"></modal>
			<modal :visible="showModal" @update:visible="showModal=$event">
				<p>乌拉</p>
			</modal>
		</div>
		<script src="./modal/index.js" type="text/javascript" charset="utf-8"></script>
		<script>
			Vue.createApp({
				components:{
					modal
				},
				data(){
					return{
						isShowModal:false,
						showModal:false
					}
				}
			}).mount("#app")
		</script>
	</body>
</html>

css 

*{
	margin: 0;padding: 0;
	}
.modal{
	width: 100vw;
	height: 100vh;
	position: relative;
	background-color: rgba(0,0,0,.7);
}
	.modal-content{
	width: 30%;
	min-height: 400px;
	height: 40%;
	position: absolute;
	left: 0;
	top: 0;
	bottom: 0;
	right: 0;
	margin: auto;
	background-color: #fff;
}
.modal-title{
	line-height: 44px;
	display: flex;
	justify-content: space-between;
}
.modal-body{
	padding: 10px;	
}

js 

const modal={
	template:`
	<div class="modal" v-if="visible">
		<div class="modal-content">
			<div class="modal-title"><span>我是标题</span>
			<span 
			@click="$emit('update:visible',false)">×</span></div>
			<div class="modal-body">
			<slot></slot>
			</div>
		</div>
	</div>
	`,
	props:{
		"visible":{type:Boolean,default:false}
	}
}

动画transition

        动画

                Vue 提供了内置的过渡封装组件,该组件用于包裹要实现过渡效果的组件。组件进入和离开 DOM 的钩子 使用内置的 <transition> 组件

<button @click="flag=!flag">切换</button> <br>
<transition name="fade">
	<img src="./images/sun.jpeg" alt="" width="120" v-if="flag">
</transition>

        动画-过渡class

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
		<script src="./js/vue.js" type="text/javascript" charset="utf-8"></script>
		<style type="text/css">
			.fade-enter-active,
			.fade-leave-active{
				/* 整个进入的过程
				 整个离开的过程都拥有这两个类*/
				transition: all ease 1s;
			}
			/* 进入状态的class */
			.fade-enter-from{
				opacity: 0;
			}
			/* 进入结束的class */
			.fade-enter-to{
				opacity: 1;
			}
			/* 离开开始状态 */
			.fade-leave-from{
				opacity: 1;
			}
			/* 离开结束状态 */
			.fade-leave-to{
				opacity: 0;
			}
		</style>
	</head>
	<body>
		<div id="app">
			<button @click="flag=!flag">切换</button><br>
			<transition name="fade">
				<img src="img/sun.jpeg"  v-if="flag">
			</transition>
		</div>
		<script>
		// 1 Vue动画是通过组件,transition实现的
		// 2 在显示离开产生动画 v-if v-show v-else v-else-if
			Vue.createApp({
				data(){
					return{flag:true}
				}
			}).mount("#app")
		</script>
		<!-- 
		动画<transition></transition>
			自动对显示与隐藏的元素添加类名
			v-enter-active进入整个过程
				.v-enter-from进入开始状态
				.v-enter-to进入结束状态
			.v-leave-active离开的过程
				.v-leave-from离开开始状态
				.v-leave-to离开结束状态 
				
		transition 
			mode模式 
				in-out
				out-in
			name名称
			enter-active-class
			自定义进入class名称
			leave-active-class
			自定义离开class名称
		transition-group
			tag包裹标签名
			.v-move
			正在移动的元素
		-->
	</body>
</html>

        动画-使用关键帧动画

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
		<script src="./js/vue.js" type="text/javascript" charset="utf-8"></script>
		<style type="text/css">
			@keyframes fadeIn{
				0%{opacity: 0;transform: rotate(-180deg);}
				100%o{opacity: 1;transform: rotate(0);}
			}
			@keyframes fadeOut{
				0%{opacity: 1;transform: rotate(0);}
				100%{opacity: 0;transform: rotate(180deg);}
			}
			.fade-enter-active{
				animation: fadeIn ease 1s;
			}
			.fade-leave-active{
				animation: fadeOut ease 1s;
			}
		</style>
	</head>
	<body>
		<div id="app">
			<button @click="flag=!flag">切换</button><br>
			<transition name="fade">
				<img src="img/sun.jpeg"  v-if="flag">
			</transition>
		</div>
		<script>
		// 1 Vue动画是通过组件,transition实现的
		// 2 在显示离开产生动画 v-if v-show v-else v-else-if
			Vue.createApp({
				data(){
					return{flag:true}
				}
			}).mount("#app")
		</script>
		<!-- 
		动画<transition></transition>
			自动对显示与隐藏的元素添加类名
			v-enter-active进入整个过程
				.v-enter-from进入开始状态
				.v-enter-to进入结束状态
			.v-leave-active离开的过程
				.v-leave-from离开开始状态
				.v-leave-to离开结束状态 
		-->
	</body>
</html>

        动画-引入第三方

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
		<script src="./js/vue.js" type="text/javascript" charset="utf-8"></script>
		<link rel="stylesheet" type="text/css" href="./css/animate.css"/>
	</head>
	<body>
		<div id="app">
			<button @click="flag=!flag">切换</button><br>
			<transition name="fade" enter-active-class="flipInY animated" leave-active-class="hinge animated">
				<img src="img/sun.jpeg"  v-if="flag">
			</transition>
		</div>
		<script>
		// 1 Vue动画是通过组件,transition实现的
		// 2 在显示离开产生动画 v-if v-show v-else v-else-if
			Vue.createApp({
				data(){
					return{flag:true}
				}
			}).mount("#app")
		</script>
		<!-- 
		动画<transition></transition>
			自动对显示与隐藏的元素添加类名
			v-enter-active进入整个过程
				.v-enter-from进入开始状态
				.v-enter-to进入结束状态
			.v-leave-active离开的过程
				.v-leave-from离开开始状态
				.v-leave-to离开结束状态 
		-->
	</body>
</html>

        动画模式

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
		<script src="./js/vue.js" type="text/javascript" charset="utf-8"></script>
		<link rel="stylesheet" type="text/css" href="./css/animate.css"/>
		<style type="text/css">
			body{
				padding: 50px;
			}
			p button{
				position: absolute;
				left: 0;
				animation-duration: .3s !important;
			}
		</style>
	</head>
	<body>
		<div id="app">
			<button @click="flag=!flag">切换</button><br>
			<p style="position: relative;">
										<!-- out-in先出后进  in-out先进后出 -->
				<transition name="fade" mode="in-out" enter-active-class="slideInRight animated" leave-active-class="slideOutLeft animated">
					<button v-if="flag">进</button>
					<button v-else>出</button>
				</transition>
			</p>
		</div>
		<script>
		// 1 Vue动画是通过组件,transition实现的
		// 2 在显示离开产生动画 v-if v-show v-else v-else-if
			Vue.createApp({
				data(){
					return{flag:true}
				}
			}).mount("#app")
		</script>
		<!-- 
		动画<transition></transition>
			自动对显示与隐藏的元素添加类名
			v-enter-active进入整个过程
				.v-enter-from进入开始状态
				.v-enter-to进入结束状态
			.v-leave-active离开的过程
				.v-leave-from离开开始状态
				.v-leave-to离开结束状态 
		-->
	</body>
</html>

        列表过渡

                我们会使用 <transition-group> 组件实现列表过渡                

<transition-group tag="div" name="slide"  >
     <div class="item" v-for="item in undoList" :key="item.name">
.....
</transition-group>

.slide-leave-active{
    animation: slideOut ease 1s;
    position: absolute;
}
/* transition-group 正在移动中的类名 */
/* 移动中的元素 */
.slide-move{
    transition: all ease 1s;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值