目录
组件数据存放一
props 基本用法
props 数据验证
子级向父级传递
组件对象也有一个 data 属性(也可以有 methods 等属性),只是这个 data 属性必须是一个函数而且这个函数返回一个对象,对象内部保存着数据:
为什么是一个函数呢?
首先,如果不是一个函数,Vue 直接就会报错。
其次,原因是在于 Vue 让每个组件对象都返回一个新的对象,因为如果是同一个对象的,组件在多次使用后会相互影响。
如何进行父子组件间的通信呢?Vue 官方提到,通过 props
向子组件传递数据,可以通过事件向父组件发送消息。
真实的开发中,Vue 实例和子组件的通信和父组件和子组件的通信过程是一样的。
props
基本用法在组件中,使用选项 props 来声明需要从父级接收到的数据。
props 的值有两种方式:
字符串数组:数组中的字符串就是传递时的名称。
对象:对象可以设置传递时的类型,也可以设置默认值等。
HTML 中的 attribute 名是大小写不敏感的,所以浏览器会把所有大写字符解释为小写字符。这意味着当你使用 DOM 中的模板时,camelCase (驼峰命名法) 的 prop 名需要使用其等价的 kebab-case (短横线分隔命名) 命名:
props
数据验证props
可以是简单的数组,或者使用对象作为替代,对象允许配置高级选项,如类型检测、自定义验证和设置默认值等等。
props
高级选项
props 高级选项 |
作用 | 说明 |
---|---|---|
type |
会检查该 prop 是否是给定的类型,否则抛出警告 | 可以是下列原生构造函数中的一种:String 、Number 、Boolean 、Array 、Object 、Date 、Function 、Symbol 、任何自定义构造函数、或上述内容组成的数组 |
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
。
当前值:{
{ currentCount }}
不同于组件和 prop,事件名不会被用作一个 JS 变量名或 property 名,所以就没有理由使用 camelCase 或 PascalCase 了。并且 v-on
事件监听器在 DOM 模板中会被自动转换为全小写 (因为 HTML 是大小写不敏感的),所以 v-on:myEvent
将会变成 v-on:myevent,
导致 myEvent
不可能被监听到。
因此,推荐你始终使用 kebab-case 的事件名。