Vue.js 学习笔记九:组件化开发之组件数据存放一

本文介绍了Vue.js中组件的数据存放、props的基本用法和数据验证,以及子组件如何通过props和自定义事件向父组件传递数据。强调了在组件间通信中props的重要性,同时展示了如何设置props的默认值、类型验证和自定义验证函数。此外,还讲解了子组件通过$emit触发自定义事件向父组件传递信息的流程。
摘要由CSDN通过智能技术生成

目录

组件数据存放一

props 基本用法

props 数据验证

子级向父级传递


组件数据存放一

组件对象也有一个 data 属性(也可以有 methods 等属性),只是这个 data 属性必须是一个函数而且这个函数返回一个对象,对象内部保存着数据:

		<div id="app" >
			<my-component></my-component>
		</div>		
		<script type="text/javascript">
			 Vue.component('my-component', {
				template: `<div>{{ msg }}</div>`,
				data() {
					return {
					    msg : 'hello vue',
					}
				}
			}) 
			const app = new Vue({
				el: '#app'
			})
		</script>

为什么是一个函数呢?

首先,如果不是一个函数,Vue 直接就会报错。

其次,原因是在于 Vue 让每个组件对象都返回一个新的对象,因为如果是同一个对象的,组件在多次使用后会相互影响。

如何进行父子组件间的通信呢?Vue 官方提到,通过 props 向子组件传递数据,可以通过事件向父组件发送消息。

真实的开发中,Vue 实例和子组件的通信和父组件和子组件的通信过程是一样的。

 

props 基本用法

在组件中,使用选项 props 来声明需要从父级接收到的数据。

props 的值有两种方式:

字符串数组:数组中的字符串就是传递时的名称。

对象:对象可以设置传递时的类型,也可以设置默认值等。

		<div id="app">
			<my-component :msg="msg"></my-component>
		</div>		
		<script type="text/javascript">
			const app = new Vue({
				el: '#app',
				data:{
					msg:'hello vue',
				},
				components:{				
					'my-component': {
						props: ['msg'],
						template:`<div>												
									<p>{{ msg }}</p>
								  </div>`											
					}
				}
			})
		</script>

HTML 中的 attribute 名是大小写不敏感的,所以浏览器会把所有大写字符解释为小写字符。这意味着当你使用 DOM 中的模板时,camelCase (驼峰命名法) 的 prop 名需要使用其等价的 kebab-case (短横线分隔命名) 命名:

		<div id="app">
			<my-component :my-msg="msg"></my-component>
		</div>
		<script type="text/javascript">
			const app = new Vue({
				el: '#app',
				data:{
					msg:'hello vue',
				},
				components:{				
					'my-component': {
						props: ['myMsg'],
						template:`<div>												
									<p>{{ myMsg }}</p>
								  </div>`											
					}
				}
			})
		</script>

 

props 数据验证

props可以是简单的数组,或者使用对象作为替代,对象允许配置高级选项,如类型检测、自定义验证和设置默认值等等。

props高级选项

props高级选项作用说明
type会检查该 prop 是否是给定的类型,否则抛出警告可以是下列原生构造函数中的一种:StringNumberBooleanArrayObjectDateFunctionSymbol、任何自定义构造函数、或上述内容组成的数组
default为该 prop 指定一个默认值如果该 prop 没有被传入,则换做用这个值,对象或数组的默认值必须从一个工厂函数返回
required定义该 prop 是否是必填项,默认为false在非生产环境中,如果这个值为true且该prop没有被传入的,则一个控制台警告将会被抛出
validator自定义验证函数会将该 prop 的值作为唯一的参数代入在非生产环境下,如果该函数返回一个false的值 (也就是验证失败),一个控制台警告将会被抛出

我们来直接看看代码更直观:

		Vue.component('my-component', {
			  props: {
			    // 基础的类型检查 (`null` 和 `undefined` 会通过任何类型验证)
			    propA: Number,
			    // 多个可能的类型
			    propB: [String, Number],
			    // 必填的字符串
			    propC: {
			      type: String,
			      required: true
			    },
			    // 带有默认值的数字
			    propD: {
			      type: Number,
			      default: 100
			    },
			    // 带有默认值的对象
			    propE: {
			      type: Object,
			      // 对象或数组默认值必须从一个工厂函数获取
			      default() {
			        return { message: 'hello vue' }
			      }
			    },
			    // 自定义验证函数
			    propF: {
			      validator(value) {
			        // 这个值必须匹配下列字符串中的一个
			        return ['success', 'warning', 'danger'].indexOf(value) !== -1
			      }
			    }
			  }
			})

当 prop 验证失败的时候,(开发环境构建版本的) Vue 将会产生一个控制台的警告。

额外的,type 还可以是一个自定义的构造函数,并且通过 instanceof 来进行检查确认。例如,给定下列现成的构造函数:

function Person (firstName, lastName) {
  this.firstName = firstName
  this.lastName = lastName
}

你可以使用:

Vue.component('my-component', {
  props: {
    author: Person
  }
})

来验证 author prop 的值是否是通过 new Person 创建的。

 

子级向父级传递

props 用于父组件向子组件传递数据,还有一种比较常见的是子组件传递数据或事件到父组件中。

我们需要使用自定义事件来完成。

什么时候需要自定义事件呢?

当子组件需要向父组件传递数据时,就要用到自定义事件了。

我们之前学习的 v-on不仅仅可以用于监听 DOM 事件,也可以用于组件间的自定义事件。

自定义事件的流程:

在子组件中,通过 $emit() 来触发事件。

在父组件中,通过v-on来监听子组件事件。

我们来看一个简单的例子:

我们之前做过一个两个按钮+1-1,点击后修改 count

我们整个操作的过程还是在子组件中完成,但是之后的展示交给父组件。

这样,我们就需要将子组件中的 count,传给父组件的某个属性,比如 currentCount

		<div id="app">
			<my-button @increment="showCurrentCount" @decrement="showCurrentCount"></my-button>
			<p>当前值:{{ currentCount }}</p>
		</div>
		<template id="my-button">
			<div>
				<button type ="button" @click="decrement">-</button>
				<button type ="button" @click="increment">+</button>
			</div>
		</template>
		<script type="text/javascript">

			const app = new Vue({
				el: '#app',
				data:{
					currentCount: 0
				},
				methods:{
					showCurrentCount(count) {
						this.currentCount = count
					}
				},
				components:{
					'my-button': {		 
						template: '#my-button',					
						methods:{
							increment() {
								this.count++
								this.$emit('increment', this.count)
							},
							decrement() {
								this.count--
								this.$emit('decrement', this.count)
							}
						},
						data() {
							return {
								count:0
							}
						}
					}
				}
			})
		</script>

不同于组件和 prop,事件名不会被用作一个 JS 变量名或 property 名,所以就没有理由使用 camelCase 或 PascalCase 了。并且 v-on 事件监听器在 DOM 模板中会被自动转换为全小写 (因为 HTML 是大小写不敏感的),所以 v-on:myEvent 将会变成 v-on:myevent,导致 myEvent 不可能被监听到。

因此,推荐你始终使用 kebab-case 的事件名

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

stary1993

你的鼓励是我创作的动力

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

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

打赏作者

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

抵扣说明:

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

余额充值