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

Posted new nm个对象

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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数据传递到父

以上是关于VUE学习笔记:10.组件化之:组件中数据的传递的主要内容,如果未能解决你的问题,请参考以下文章

vue.js学习笔记(Vuejs——组件——props数据传递)

Vue3 组件通信学习笔记

Vue学习笔记入门篇——组件的通讯

VUE学习笔记:11.组件化之:父子组件的访问方式

vue 3 学习笔记 ——provide 和 inject 用法及原理

VUE学习笔记:12.组件化之:slot组件插槽讲解