Vue学习记录(二)

本文详细介绍了Vue.js中的过渡动画,包括使用transition和transition-group实现元素的进入离开动画,并通过自定义类名实现更复杂的动画效果。此外,还深入探讨了Vue组件化的概念、步骤和简化方式,以及动态组件、父子组件间的通信和数据传递。文章还提到了插槽的使用,包括匿名插槽、具名插槽和作用域插槽,展示了如何在组件间灵活地传递内容和数据。
摘要由CSDN通过智能技术生成

过渡动画

1.通过transition双标签嵌套想要执行动画的部分
2.通过v-enter(进入前),v-enter-to(进入后),v-enter-active(进入过程)和
v-leave(离开前),v-leave-to(离开后),v-leave-active(离开过程)的类名方式在css中添加样式,就可以实现动态的动画

实操代码:

<!DOCTYPE html>
<html>
	<head>
		<style type="text/css">
			* {
				margin: 0px;
				padding: 0px;
			}

			.pic {
				width: 300px;
				height: 300px;
				background-color: red;
			}
			.v-enter {
				opacity: 0;
			}
			.v-enter-to {
				opacity: 1;
			}
			.v-enter-active {
				transition: all 3s;
			}
			.v-leave {
				opacity: 1;
			}
			.v-leave-to {
				opacity: 0;
			}
			.v-leave-active {
				transition: all 3s;
			}
		</style>
		<meta charset="utf-8">
		<title></title>
	</head>
	<body>

		<div id="demo">
			<button type="button" @click="toggle">
				演示
			</button>
			<transition>
				<div id="" class="pic" v-show="isShow">

				</div>
			</transition>

		</div>
		<script src="js/vue.js" type="text/javascript" charset="utf-8"></script>
		<script type="text/javascript">
			var app = new Vue({
				el: "#demo",
				data: {
					isShow: false
				},
				methods: {
					toggle() {
						this.isShow = !this.isShow;
					}
				},
				directives: {

				}
			})
		</script>
	</body>
</html>

过渡动画注意点:
1.一对transition标签只能嵌套一个元素的过渡动画,如果想要控制多个元素的动画效果,则需要通过多个transition标签来嵌套
2.如果想要元素进入页面就有过渡动画的效果,则需要给transition标签添加一个appear属性
3.如果想要多个元素执行不同的动画效果,则需要给transition添加一个name属性,再将name的属性值替换前缀v,演示代码如下:

<!DOCTYPE html>
<html>
	<head>
		<style type="text/css">
			* {
				margin: 0px;
				padding: 0px;
			}

			.pic {
				width: 300px;
				height: 300px;
				background-color: red;
			}
			.one-enter {
				opacity: 0;
			}
			.one-enter-to {
				margin-left: 500px;
				opacity: 1;
			}
			.one-enter-active {
				transition: all 3s;
			}
			.one-leave {
				opacity: 1;
			}
			.one-leave-to {
				opacity: 0;
			}
			.one-leave-active {
				transition: all 3s;
			}
			.two-enter {
				opacity: 0;
			}
			.two-enter-to {
				margin-top: 1000px;
				opacity: 1;
			}
			.two-enter-active {
				transition: all 3s;
			}
			.two-leave {
				opacity: 1;
			}
			.two-leave-to {
				opacity: 0;
			}
			.two-leave-active {
				transition: all 3s;
			}
		</style>
		<meta charset="utf-8">
		<title></title>
	</head>
	<body>

		<div id="demo">
			<button type="button" @click="toggle">
				演示
			</button>
			<transition appear name="one">
				<div id="" class="pic" v-show="isShow">

				</div>
			</transition>
			<transition  appear name="two">
				<div id="" class="pic" v-show="isShow">
			
				</div>
			</transition>

		</div>
		<script src="js/vue.js" type="text/javascript" charset="utf-8"></script>
		<script type="text/javascript">
			var app = new Vue({
				el: "#demo",
				data: {
					isShow: false
				},
				methods: {
					toggle() {
						this.isShow = !this.isShow;
					}
				},
				directives: {

				}
			})
		</script>
	</body>
</html>

自定义类名

enter-from-class                             //动画执行之前
enter-active-class                           //动画执行过程
enter-to-class                               //动画执行之后
leave-from-class							 //离开动画之前
leave-active-class							 //离开动画过程
leave-to-class								 //离开动画动画之后

通过给transition标签绑定以上属性名,属性值自定义类名后,在css中添加样式

animate css动画框架

1.先引用
2.在enter-active-class属性中添加属性值animated 加动画样式名
附上animate.css官网:http://www.animate.net.cn/

transition-group

可以替代transition嵌套多个元素的动画效果

transition-group的属性

1.tag:属性值设置标签,可以将transition中的元素全部嵌套在tag指定的标签之中

Vue组件

定义:将大界面拆分为小界面就是组件化
好处提高代码的复用性

Vue组件化步骤

1.创建组件构造器
2.注册已经创建好的组件
3.使用组件

<body>
		<div id="demo">
			<!-- 使用组件 -->
			<abc></abc>
		</div>
		<script src="js/vue.js" type="text/javascript" charset="utf-8"></script>
		<script type="text/javascript">
			//创建一个组件
			let Profile = Vue.extend({
				template: `
				<div>
				<h1>这是一个标题</h1>
				<p>这是我的第一个组件</p>
				</div>`
				


			});
			//注册组件
			Vue.component("abc", Profile);
			var app = new Vue({
				el: "#demo",
				data: {

				},
				methods: {

				},
				directives: {

				}
			})
		</script>
	</body>

注意:
1.template中不要使用单引号,否则换行会报错,如果想换行,则使用感叹号旁边的``。
2.template中不能包含多个主元素

Vue组件化简化方式

以上代码可以有简化方式且可以让我们输入html代码时有提示,提升开发效率,如下:
js部分

Vue.component("abc", {
				template: "#tem1"
			});

html部分:

<div id="demo">
			<!-- 使用组件 -->
			<abc></abc>
		</div>
		<template id="tem1">
			<div>
				<h1>这是一个标题</h1>
				<p>这是我的第一个组件</p>
			</div>
</template>

Vue组件化(局部组件)

var app = new Vue({
				el: "#demo",
				data: {

				},
				methods: {

				},
				directives: {

				},
				components:{
					"abc": {
						template:"#tem1"
					}
				}
			})

组件中的data和methods

注意:
1.组件中的methods所用函数必须是已经被定义好的
2.组件中的data必须是一个函数,在函数中可以使用return返回一个对象,对象中也必须要使用已经被定义好的key(对象中的key,value中的key)
问题:data为什么必须是一个函数
回答:因为如果多次调用组件,如果data是一个对象,里面的数据将会受到多个组件的共用,容易发生数据混乱。而如果是一个函数,则每个组件所对应的data都是独立的,就避免了数据混乱

动态组件

动态组件通过

<component v-bind:is="name"></component>
//name
可以是已注册组件的名字
或一个组件的选项对象

通过动态组件可以保存一些状态(如input中type属性check的选择状态)

html代码

		<div id="demo">
			<button type="button" @click="toggle">切换</button>
			<!-- 使用组件 -->
			<!-- <abc1 v-if="isShow"></abc1>
			<abc2 v-else></abc2> -->
			<keep-alive>
				<component v-bind:is="name"></component>
			</keep-alive>
		</div>
		<template id="tem1">
			<div>
				<h1>这是一个标题</h1>
				<p>这是我的第一个组件</p>
				<input type="checkbox" name="" id="" value="" />
			</div>
		</template>
		<template id="tem2">
			<div>
				<h1>这是二个标题</h1>
				<p>这是我的第二个组件</p>
			</div>
		</template>

Vue代码:

			Vue.component("abc1", {
				template: "#tem1"
			});
			Vue.component("abc2", {
				template: "#tem2"
			});
			var app = new Vue({
				el: "#demo",
				data: {
					isShow:true,
					name:"abc1"
				},
				methods: {
					toggle(){
						// this.isShow = !this.isShow;
						// console.log(this.name === "abc1");
						this.name = this.name === "abc1"? "abc2": "abc1";
					}
				},
				directives: {

				},
				components:{
					
				}
			})

组件动画

使用方法参照过渡动画
注意点:
过渡模式:
in-out:新元素先进行过渡,完成之后当前元素过渡离开。

out-in:当前元素先进行过渡,完成之后新元素过渡进入。

<component v-bind:is="name" mode="in-out"></component>

父子组件

定义:在一个组件中又定义了其他的组件,我们称之为父子组件

基础的父子组件

	<body>
		<div id="demo">
			<father>
				<!-- <son></son>并不是定义在这个地方 不然不会报错的同时子组件也不会渲染-->
			</father>
		</div>
		<template id="father">
			<div id="">
				<p>我是父组件</p>
				<son></son><!-- <son></son>定义在此处 -->
			</div>
		</template>
		<template id="son">
			<div id="">
				<p>我是子组件</p>
			</div>
		</template>
		<script src="js/vue.js" type="text/javascript" charset="utf-8"></script>
		<script type="text/javascript">
			var app = new Vue({
				el: "#demo",
				//MVVM中的model
				data: {

				},
				//专门用于存储监听事件中的回调函数
				methods: {

				},
				//计算属性
				directives: {

				},
				//组件
				components: {
					"father": {
						template:"#father",
						//注意1:此时下面的components所处位置,这里刚学习时容易出错
						components: {
							"son":{
								template:"#son"
							}
						}
					},
					
				}
			})
		</script>
	</body>
父子组件方法和数据传递

Vue中子组件是不能访问到父组件中的数据的,如果想要访问到父组件中的数据,则需要父子组件传递。
使用步骤:
1.使用中父组件当中的子组件中通过v-bind定义向子组件传递数据
2.在Vue子组件中使用props接收父组件传递过来的一个数据
3.在子组件中使用
具体实操代码如下:

html代码:

		<div id="demo">
			<father>

			</father>
		</div>
		<template id="father">
			<div id="">
				<p>我是父组件</p>
				<p>{{name}}</p>
				<button type="button" @click="say">父组件</button>
				<!-- 这里将父组件中的数据和方法传递给子组件 -->
				<son :parentname="name" @parentsay="say">

				</son>
			</div>
		</template>
		<template id="son">
			<div id="">
				<!-- 使用子组件中接收到的父组件方法 -->
				<button type="button" @click="parentsay">子组件</button>
				<p>我是子组件</p>
				<!-- 这里接收了父组件传递过来的data -->
				<p>{{parentname}}</p>
			</div>
		</template>

Vue代码:

			Vue.component("father", {
				template: "#father",
				components: {
					"son": {
						template: "#son",
						//这里子组件接收父组件传过来的数据parentname,这里的parentname可以任意命名,自命名然后在子组件中使用
						props: ["parentname"],
						methods:{
							//子组件对父组件传递过来的方法进行一个定义
							parentsay(){
								this.$emit("parentsay")
							}
						}
					}
				},

子组件向父组件中传递数据,只需要在子组件接收方法后加上需要传递的数据,再在父组件方法中接收参数就可以了

			Vue.component("father", {
				template: "#father",
				components: {
					"son": {
						template: "#son",
						//这里子组件接收父组件传过来的数据parentname,这里的parentname可以任意命名,自命名然后在子组件中使用
						props: ["parentname"],
						methods:{
							//子组件对父组件传递过来的方法进行一个定义
							parentsay(data){
								//$emit方法中第二个参数是给父组件传递的数据
								this.$emit("parentsay","传递子组件数据")
							}
						}
					}
				},
				//组件中的data传递数据只能通过函数reutrn一个对象
				data() {
					return {
						"name": "yxy"
					}
				},
				methods:{
					//父组件接收子组件传递过来的数据data
					"say"(data){
						alert("父组件");
						console.log(data)
					}
				}
			})

命名注意点:
1.组件构造时如果使用了驼峰命名(fnSay),则使用的时候就需要使用短横线命名(fn-say)
2.父子组件传递数据的时候,如果用的是驼峰命名,则子组件在接收的时候也需要使用短横线命名
3.父子组件传递方法的时候,是不能使用驼峰式命名的

多级传递

如果想要多级传递,则需要一层一层的往下传递

匿名插槽

如果想在子组件中动态的添加一些标签,则需要在子组件独立部分添加slot标签,此时的slot就属于一个插槽
1.如果在父组件中,没有给子组件动态的添加标签,则插槽中的内容会替换掉子组件中动态添加的数据
2.如果在父组件中,给子组件添加标签和内容了,则插槽中的内容就会被替换
总结,父组件中的子组件添加的标签 > 子组件插槽中的内容

具名插槽

在子组件中的插槽slot中添加一个name属性,属性值再添加给父组件中需要添加的标签元素slot属性中
具名插槽存在的意义,可以有效解决子组件中添加了多个插槽,导致父组件中动态添加的标签产生复制的问题
具体代码如下:

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
	</head>
	<body>
		<div id="demo">
			<father>
				
			</father>
		</div>
		<template id="father">
			<div id="">
				<p>我是父组件</p>
				<son>
					<div id="" slot="one">
						我是父组件中调用的插槽1
					</div>
					<div id="" slot="one">
						我是父组件中调用的插槽11
					</div>
					<div id="" slot="two">
						我是父组件中调用的插槽2
					</div>
					<div id="" slot="two">
						我是父组件中调用的插槽22
					</div>
				</son>
			</div>
		</template>
		<template id="son">
			<div id="">
				<slot name="one">我是默认插槽</slot>
				<slot name="two">我是默认插槽</slot>
				<p>我是子组件</p>
			</div>
		</template>
	</body>
	<script src="js/vue.js" type="text/javascript" charset="utf-8"></script>
	<script type="text/javascript">
		Vue.component("father", {
			template:"#father",
			components:{
				"son":{
					template:"#son"
				}
			}
		})
	   var app = new Vue({
				el:"#demo",
				//MVVM中的model
				data:{
					
				},
				//专门用于存储监听事件中的回调函数
				methods:{
					
				},
				//计算属性
				directives:{
					
				},
				//组件
				components:{
					
				}
			})
	</script>
</html>

v-slot指令(简写#)(具名插槽的改进)

可以给父元素中需要动态创建在子元素中的标签用template标签包裹起来,再给template加上一个v-slot属性,指定需要添加的插槽name属性值,则可以达到和具名插槽一样的效果,
代码如下:

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
	</head>
	<body>
		<div id="demo">
			<father></father>
		</div>
		<template id="father">
			<div id="">
				<p>我是父组件</p>
				<son>
					<template #one>
						<p>我是添加的v-slot</p>
						<p>我是添加的v-slot2</p>
					</template>
				</son>
			</div>
		</template>
		<template id="son">
			<div id="">
				<slot name="one">我是默认的插槽</slot>
				<p>我是子组件</p>
			</div>
		</template>
		<script src="js/vue.js" type="text/javascript" charset="utf-8"></script>
		<script type="text/javascript">
			Vue.component("father", {
				template:"#father",
				components:{
					"son":{
						template:"#son"
					}
				}
			})
			var app = new Vue({
				el:"#demo",
				//MVVM中的model
				data:{
					
				},
				//专门用于存储监听事件中的回调函数
				methods:{
					
				},
				//计算属性
				directives:{
					
				},
				//组件
				components:{
					
				}
			})
		</script>
	</body>
</html>

作用域插槽

父组件插槽中能够使用子组件的数据
作用域插槽应用场景:子组件提供数据,父组件决定如何渲染
步骤:
1.先用v-bind指令在子组件中的插槽slot中提取出子组件中的数据
2.在父组件套用子组件中在template中添加属性slot-scope将子组件传递过来的数据接收
3.数据渲染
具体代码如下:

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
	</head>
	<body>
		<div id="demo">
			<father>
				
			</father>
		</div>
		<template id="father">
			<div id="">
				<p>我是父组件</p>
				<son>
					<!-- 此时的 slot-scope="abc"就是接收子组件插槽中传递过来的数据,并命名为abc-->
					<template slot-scope="abc">
						<!-- 使用v-for将数组数据渲染出来 -->
						<li v-for="(name, value) in abc.names">{{name}}</li>
					</template>
				</son>
			</div>
		</template>
		<template id="son">
			<div id="">
				<p>我是子组件</p>
				<!-- :names="names"是将子组件中的数据提取出来并命名为names -->
				<slot :names="names">我是默认的插槽</slot>
			</div>
		</template>
	</body>
	<script src="js/vue.js" type="text/javascript" charset="utf-8"></script>
	<script type="text/javascript">
		Vue.component("father", {
			template:"#father",
			components:{
				"son":{
					template:"#son",
					data:function(){
						return {
							names :["zs", "ls", "ww", "zl"]
						}
					}
				}
			}
		})
		var app = new Vue({
			el:"#demo",
			//MVVM中的model
			data:{
				
			},
			//专门用于存储监听事件中的回调函数
			methods:{
				
			},
			//计算属性
			directives:{
				
			},
			//组件
			components:{
				
			}
		})
	</script>
</html>

slot属性扩充部分(替代slot-scope)

slot属性除了可以替代具名插槽以外,还可以替代slot-scope接收子组件传递过来的数据
替换步骤如下:
将上一板块中slot-scope中的slot-scope属性

<template slot-scope="abc">
		<!-- 使用v-for将数组数据渲染出来 -->
		<li v-for="(name, value) in abc.names">{{name}}</li>
</template>

替换成

<template #slo="abc">
		<!-- 使用v-for将数组数据渲染出来 -->
		<li v-for="(name, value) in abc.names">{{name}}</li>
</template>

这里的slo是才插槽中设置的name属性

<slot :names="names" name="slo">我是默认的插槽</slot>

如果没有设置name属性,则默认为#default

注:该篇博客为自己视频学习时记录下的笔记,学习步骤来源于学习视频

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

牛仔不当马仔

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值