VUE学习笔记:10.组件化之:组件中数据的传递

1.组件中的数据存放

在这里插入图片描述
在这里插入图片描述
案例:

<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title></title>
</head>
<body>
<div id="app1">
	<!--使用组件-->
	<mycpnc></mycpnc>
</div>

<!--使用template标签抽离组件模板-->
<template id="script_template">
	<div>
		<h3>{{message}}</h3>
	</div>
</template>

<!--引入本地的vue.js文件-->
<script src="../vue.js"></script>

<script>
    let app1 = new Vue({
        el: '#app1', // 讲这个vue实例与id为app1的标签关联起来
        data: {},
		//使用语法糖方式注册局部组件
		components: {
			'mycpnc':{
				template: '#script_template',
				data:function(){
					return {message: '我是组件中的数据'}
				}
			}
		}
    })	
</script>
</body>
</html>

运行效果如下:
在这里插入图片描述
总结:

  • 组件中无法使用vue实例中的数据。
  • 组件中使用data属性来存放组件自己的数据。
  • 组件中的data属性是一个函数,且必须返回一个对象,在对象中存放数据。

2.组件中的data属性为什么是函数?

vue讲组件中的data属性设置为一个函数,主要原因是为了防止引用多个组件实例时产生数据冲突。

3.父子组件之间的通信

在这里插入图片描述

(1)父组件传递数据给子组件-props

拓展:vue实例也可以看成一个组件,注册在vue实例中的组件就是其子组件。

在这里插入图片描述

(1.1)父组件传递数据给子组件的步骤:

子组件中

  1. 子组件中使用props声明变量用于接受父组件的数据。

    方式1:使用数组形式声明变量

    let app = new Vue({
        el: '#app1', // 讲这个vue实例与id为app1的标签关联起来
        data: {
    		message: '哈哈哈',
    		number: 10
    	},
    	//使用语法糖方式注册局部组件
    	components: {
    		'mycpnc':{
    			template: '#script_template',
    			//声明变量用于接受父组件的数据
    			//使用props声明后cmessage和cnumber就相当于子组件中的属性变量
    			//父组件使用时可以使用v-bind的方式将数据传递给cmessage和cnumber
    			props:['cmessage','cnumber'] 
    		}
    	}
    })
    

    方式2:使用对象的方式声明变量(常用)

    let app = new Vue({
        el: '#app1', // 讲这个vue实例与id为app1的标签关联起来
        data: {
    		message: '哈哈哈',
    		number: 10
    	},
    	//使用语法糖方式注册局部组件
    	components: {
    		'mycpnc':{
    			template: '#script_template',
    			
    			
    			//声明变量用于接受父组件的数据
    			//使用props声明后cmessage和cnumber就相当于子组件中的属性变量
    			//父组件使用时可以使用v-bind的方式将数据传递给cmessage和cnumber
    			props:{
    				cmessage:{
    					type:String, //指定父组件需要传递数据的类型
    					default:'嘿嘿嘿', //指定父组件需要传递数据的默认值
    					required:true //指定父组件使用子组件时,必须传递该数据
    				},
    				cnumber:{
    					type:Number,
    					default:55,
    					required:false
    				}
    			}
    		}
    	}
    })
    
  2. 子组件的模板中使用数据

    <!--使用template标签抽离组件模板-->
    <!--在子组件的模板中直接使用经过props声明的变量-->
    <template id="script_template">
    	<div>
    		<h3>{{cmessage}}</h3>
    		<h3>{{cnumber}}</h3>
    	</div>
    </template>
    

父组件中

  1. 父组件中使用子组件时,需要使用v-bind的方式将数据传递给子组件声明好的变量

    <div id="app1">
    	<!--使用组件-->
    	<mycpnc :cmessage="message"  :cnumber="number"></mycpnc>
    </div>
    

(1.2)案例

<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title></title>
</head>
<body>
<div id="app1">
	<!--使用组件-->
	<mycpnc :cmessage="message"  :cnumber="number"></mycpnc>
</div>

<!--使用template标签抽离组件模板-->
<template id="script_template">
	<div>
		<h3>{{cmessage}}</h3>
		<h3>{{cnumber}}</h3>
	</div>
</template>

<!--引入本地的vue.js文件-->
<script src="../vue.js"></script>

<script>
    let app = new Vue({
        el: '#app1', // 讲这个vue实例与id为app1的标签关联起来
        data: {
			message: '哈哈哈',
			number: 10
		},
		//使用语法糖方式注册局部组件
		components: {
			'mycpnc':{
				template: '#script_template',
				
				
				//声明变量用于接受父组件的数据
				//使用props声明后cmessage和cnumber就相当于子组件中的属性变量
				//父组件使用时可以使用v-bind的方式将数据传递给cmessage和cnumber
				props:{
					cmessage:{
						type:String, //指定父组件需要传递数据的类型
						default:'嘿嘿嘿', //指定父组件需要传递数据的默认值
						required:true //指定父组件使用子组件时,必须传递该数据
					},
					cnumber:{
						type:Number,
						default:55,
						required:false
					}
				}
			}
		}
    })
</script>
</body>
</html>

效果如下:
在这里插入图片描述

(1.3)父组件传递数据给子组件的过程图解

因为组件之间数据的传递比较繁杂,这里使用图解的方式表示一下。
在这里插入图片描述

(1.4)子组件中使用驼峰标识及没有跟标签的坑

子组件中使用驼峰标识变量的坑

子组件中使用驼峰标识的变量来接受父组件传递过来的数据时,会导致父组件传递数据失败。

<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title></title>
</head>
<body>
<div id="app1">
	<!--使用组件-->
	<mycpnc :cMessage="message"></mycpnc>
</div>

<!--使用template标签抽离组件模板-->
<template id="script_template">
	<div>
		<h3>{{cMessage}}</h3>
	</div>
</template>

<!--引入本地的vue.js文件-->
<script src="../vue.js"></script>

<script>
    let app = new Vue({
        el: '#app1', // 讲这个vue实例与id为app1的标签关联起来
        data: {
			message: '哈哈哈',
			number: 10
		},
		//使用语法糖方式注册局部组件
		components: {
			'mycpnc':{
				template: '#script_template',
				
				props:{
					cMessage:{
						type:String, //指定父组件需要传递数据的类型
						default:'我是默认值', //指定父组件需要传递数据的默认值
						required:true //指定父组件使用子组件时,必须传递该数据
					},
				}
			}
		}
    })
</script>
</body>
</html>

效果如下:
在这里插入图片描述
所有我们在定义子组件用于接受数据的变量时,应该避免使用驼峰标识。如果一定要使用驼峰标识,那么中父组件给子组件传递数据时,应将子组件的属性使用’-'连接来代替驼峰标识。

<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title></title>
</head>
<body>
<div id="app1">
	<!--使用组件-->
	<mycpnc :c-message="message"></mycpnc>
</div>

<!--使用template标签抽离组件模板-->
<template id="script_template">
	<div>
		<h3>{{cMessage}}</h3>
	</div>
</template>

<!--引入本地的vue.js文件-->
<script src="../vue.js"></script>

<script>
    let app = new Vue({
        el: '#app1', // 讲这个vue实例与id为app1的标签关联起来
        data: {
			message: '哈哈哈',
			number: 10
		},
		//使用语法糖方式注册局部组件
		components: {
			'mycpnc':{
				template: '#script_template',
				
				props:{
					cMessage:{
						type:String, //指定父组件需要传递数据的类型
						default:'我是默认值', //指定父组件需要传递数据的默认值
						required:true //指定父组件使用子组件时,必须传递该数据
					},
				}
			}
		}
    })
</script>
</body>
</html>

运行效果如下:
在这里插入图片描述

子组件模板中不使用跟标签的坑

当在我们子组件模板使用了多个变量来渲染内容时,如果子组件的模板中未使用跟标签,会导致只有一个变量的数据能渲染成功,其他变量数据不会被渲染。

<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title></title>
</head>
<body>
<div id="app1">
	<!--使用组件-->
	<mycpnc :c-message="message" :c-number="number"></mycpnc>
</div>

<!--使用template标签抽离组件模板-->
<template id="script_template">
		<h3>{{cMessage}}</h3>
		<h3>{{cNumber}}</h3>
</template>

<!--引入本地的vue.js文件-->
<script src="../vue.js"></script>

<script>
    let app = new Vue({
        el: '#app1', // 讲这个vue实例与id为app1的标签关联起来
        data: {
			message: '哈哈哈',
			number: 10
		},
		//使用语法糖方式注册局部组件
		components: {
			'mycpnc':{
				template: '#script_template',
				
				props:{
					cMessage:{
						type:String, //指定父组件需要传递数据的类型
						default:'我是默认值', //指定父组件需要传递数据的默认值
						required:true //指定父组件使用子组件时,必须传递该数据
					},
					cNumber:{
						type:Number,
					}
				}
			}
		}
    })
</script>
</body>
</html>

效果如下:
在这里插入图片描述
所有我们在定义子组件的模板时,最好加上一个跟标签div

<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title></title>
</head>
<body>
<div id="app1">
	<!--使用组件-->
	<mycpnc :c-message="message" :c-number="number"></mycpnc>
</div>

<!--使用template标签抽离组件模板-->
<template id="script_template">
	<div>
		<h3>{{cMessage}}</h3>
		<h3>{{cNumber}}</h3>
	</div>
</template>

<!--引入本地的vue.js文件-->
<script src="../vue.js"></script>

<script>
    let app = new Vue({
        el: '#app1', // 讲这个vue实例与id为app1的标签关联起来
        data: {
			message: '哈哈哈',
			number: 10
		},
		//使用语法糖方式注册局部组件
		components: {
			'mycpnc':{
				template: '#script_template',
				
				props:{
					cMessage:{
						type:String, //指定父组件需要传递数据的类型
						default:'我是默认值', //指定父组件需要传递数据的默认值
						required:true //指定父组件使用子组件时,必须传递该数据
					},
					cNumber:{
						type:Number,
					}
				}
			}
		}
    })
</script>
</body>
</html>

效果如下:
在这里插入图片描述

(2)子组件传递数据给父组件-通过自定义事件

在这里插入图片描述
子组件传递数据给父组件流程:

  • 子组件使用$emit()来发送自定义事件。
    this.$emit('自定义事件的名称','需要传递的数据')
    
  • 父组件中使用v-on监听子组件中发送的自定义事件

案例:在子组件中定义数据count,并创建两个按钮+-。实现点击按钮后count加或者减1。并将子组件中的count数据传递到父组件的fcount中,进行展示。

<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title></title>
</head>
<body>
<!--父组件模板-->
<div id="app1">
	<!--使用组件-->
	<!--父组件中使用v-on来监听子组件的自定义参数,注意这里不需要传入实参。因为子组件自定义事件时的第二个参数this.count,会作为默认参数传进来-->
	<mycpnc @cclick="faccpet"></mycpnc>
	<h3>{{fcount}}</h3>
</div>

<!--使用template标签抽离组件模板-->
<template id="script_template">
	<div>
		<button type="button" @click="addclick">+</button>
		<button type="button" @click="reduceclick">-</button>
	</div>
</template>

<!--引入本地的vue.js文件-->
<script src="../vue.js"></script>

<script>
    let app = new Vue({
        el: '#app1', // 讲这个vue实例与id为app1的标签关联起来
        data: {fcount:0},
		methods: {
			//子组件自定义事件的监听方法,注意这里必须要有形参item。
			faccpet: function(item){
				this.fcount = item;
			}
		},
		//使用语法糖方式注册局部组件
		components: {
			'mycpnc':{
				template: '#script_template',
				data: function(){
					return {count:0}
				},
				methods:{
					addclick: function(){
						this.count++;
						//发送自定义事件,第一个参数为自定义事件的名称,第二个参数为需要传递的数据
						this.$emit('cclick',this.count);
					},
					reduceclick: function(){
						this.count--;
						this.$emit('cclick',this.count);
					}
				}
			}
		}
    })
</script>
</body>
</html>

效果如下:
在这里插入图片描述

4.子组件中改变父组件传递过来的数据

前面我们讲了父组件传递给子组件的数据是保存在props中,当我们需要使用该数据时,直接使用props中的变量即可。但是当我们需要改变父组件传递过来的数据时,可以直接改变props中变量的值吗?

<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title></title>
</head>
<body>
<div id="app1">
	<!--使用组件-->
	<mycpnc :cmessage="message"></mycpnc>
</div>

<!--使用template标签抽离组件模板-->
<template id="script_template">
	<div>
		<button type="button" @click="cmessage++">+</button>
		<button type="button" @click="cmessage--">-</button>
		<h3>{{cmessage}}</h3>
	</div>
</template>

<!--引入本地的vue.js文件-->
<script src="../vue.js"></script>

<script>
    let app = new Vue({
        el: '#app1', // 讲这个vue实例与id为app1的标签关联起来
        data: {message:0},
		//使用语法糖方式注册局部组件
		components: {
			'mycpnc':{
				template: '#script_template',
				props:['cmessage']
			}
		}
    })
</script>
</body>
</html>

结果如下:
在这里插入图片描述
那么如何解决这个问题呢?答案就是将父组件传递过来的数据存放到子组件的data属性中,如何改变data中的值。

<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title></title>
</head>
<body>
<div id="app1">
	<!--使用组件-->
	<mycpnc :cmessage="message"></mycpnc>
</div>

<!--使用template标签抽离组件模板-->
<template id="script_template">
	<div>
		<button type="button" @click="dmessage++">+</button>
		<button type="button" @click="dmessage--">-</button>
		<h3>{{dmessage}}</h3>
	</div>
</template>

<!--引入本地的vue.js文件-->
<script src="../vue.js"></script>

<script>
    let app = new Vue({
        el: '#app1', // 讲这个vue实例与id为app1的标签关联起来
        data: {message:0},
		//使用语法糖方式注册局部组件
		components: {
			'mycpnc':{
				template: '#script_template',
				props:['cmessage'],
				data:function(){
					return {
						dmessage:this.cmessage //将props中的cmessage值保存到data中的dmessage中
					}
				}
			}
		}
    })
</script>
</body>
</html>

结果如下:
在这里插入图片描述
总结:

父组件传递数据给子组件,子组件中需要在props中设置变量来接受数据。当我们需要展示数据时,直接使用props中的变量即可。但是当我们需要改变数据时,可以直接改变props中的变量,但是代码会有警告所有不推荐这种方式。推荐将props中的变量赋值给data中的一个变量,如何通过改变data中的变量,来改变数据的值。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值