## 一:Prop大小写
```
Vue.component('blog-post', {
// 在 JavaScript 中是 camelCase 的
props: ['postTitle'],
template: '<h3>{{ postTitle }}</h3>'
})
```
注册组件时props是postTitle,但在组件中使用时是post-title
```
<!-- 在 HTML 中是 kebab-case 的 -->
<blog-post post-title="hello!"></blog-post>
```
## 二:Prop的类型
1.数组
```
props: ['title', 'likes', 'isPublished', 'commentIds', 'author']
```
2.对象
>[info] 当props使用对象的形式时可以使用类型检查,这也是推荐使用的方式
```
props: {
title: String,
likes: Number,
isPublished: Boolean,
commentIds: Array,
author: Object,
callback: Function,
contactsPromise: Promise // or any other constructor
}
```
## 三:单向数据流
所有的prop都是父组件流向子组件,而反过来则不行,这样会防止从子组件意外改变父级组件的状态,从而导致你的应用的数据流向难以理解。
这里有两种常见的试图改变一个 prop 的情形:
1.**这个 prop 用来传递一个初始值;这个子组件接下来希望将其作为一个本地的 prop 数据来使用**。在这种情况下,最好定义一个本地的 data 属性并将这个 prop 用作其初始值:
```
props: ['initialCounter'],
data: function () {
return {
counter: this.initialCounter
}
}
```
2.**这个 prop 以一种原始的值传入且需要进行转换**。在这种情况下,最好使用这个 prop 的值来定义一个计算属性:
```
props: ['size'],
computed: {
normalizedSize: function () {
return this.size.trim().toLowerCase()
}
}
```
>[danger] 注意在 JavaScript 中对象和数组是通过引用传入的,所以对于一个数组或对象类型的 prop 来说,在子组件中改变这个对象或数组本身**将会**影响到父组件的状态。
## 四:非Prop的特征
**非 prop 特性是指传向一个组件,但是该组件并没有定义相对应的prop。**
```
Vue.component('bootstrap-date-input',{
template:`<input type="date" class="form-control">`
})
//组件并没有定义data-date-picker的porp,此时会把data-date-picker添加到组件的根元素中
<bootstrap-date-input data-date-picker="activated"></bootstrap-date-input>
```
```
<input type="date" data-date-picker="activated" class="form-control">
```
**默认会把特征继承作用于组件根元素,但往往我们需要灵活设置作用的元素。**
1.禁用特征继承
禁用根组件的特征继承需要在组件的选项中设置`inheritAttrs: false`,这样就不会默认作用于跟组件
```
Vue.component('bootstrap-date-input',{
inheritAttrs: false,
template:`<label>
{{ label }}
<input
v-bind="$attrs"
v-bind:value="value"
v-on:input="$emit('input', $event.target.value)"
>
</label>`
})
```
2.设置特征继承作用的元素
在需要设置的元素上使用`$attrs`属性即可作用到设置的元素中。
```
Vue.component('base-input', {
inheritAttrs: false,
props: ['label', 'value'],
template: `
<label>
{{ label }}
<input
v-bind="$attrs" //设置$attrs,则特征会作用于input元素
v-bind:value="value"
v-on:input="$emit('input', $event.target.value)"
>
</label>
`
})
```
>[danger] 注意`inheritAttrs: false`选项**不会**影响`style`和`class`的绑定。
这个模式允许你在使用基础组件的时候更像是使用原始的 HTML 元素,而不会担心哪个元素是真正的根元素:
~~~
<base-input
v-model="username"
required
placeholder="Enter your username"
></base-input>
~~~