HTML 中的 attribute
名是大小写不敏感的,所以浏览器会把所有大写字符解释为小写字符。这意味着当你使用 DOM 中的模板时,camelCase(驼峰命名法)的 prop 名需要使用其等价的 kebab-case(短横线分隔命名)。如果使用字符串模板,这个限制就不存在了。
我们常见的 prop 是以字符串数组形式列出的 prop
props: ['title', 'likes', 'isActived']
但是,通常你也希望每个 prop 都有指定的值类型,这个时候,可以使用 对象形式 列出 prop,这些 property 的名称和值分别是 prop 各自的名称和类型。
props: {
title: String,
likes: Number,
isActived: Boolean
}
所有 prop 都使得其父子 prop 之间形成了一个单向下行绑定:父级 prop 的更新会向下流动到子组件中,但是反过来不行。这样会防止子组件意外变更父组件的状态,从而导致你的应用的数据流向难以理解。
每次父级组件发生变更时,子组件中所有的 prop 都将会刷新为最新的值。如果你在一个子组件内部改变 prop,Vue 会在浏览器的控制台中发出警告
点击按钮子组件会修改父组件传递过来的 prop,浏览器会报错
父组件
<template>
<div>father
<son-comp :fatherMsg="fatherMsg"></son-comp>
</div>
</template>
<script>
import sonComp from './sonComponent'
export default {
name: 'fatherComponent',
data() {
return {
fatherMsg: 'fatherMe'
}
},
components: {
sonComp
}
}
</script>
子组件
<template>
<div>son
{{ fatherMsg }}
<button @click="change">改变</button>
</div>
</template>
<script>
export default {
name: 'sonComponent',
props: ['fatherMsg'],
methods: {
change() {
this.fatherMsg = 'haha'
}
}
}
</script>
以上这种改变子组件中的prop 是不可取的
两种常见的试图变更一个 prop 的情形
1. 这个 prop 用来传递一个初始值,这个子组件接下来希望将其作为一个本地的 prop 数组来使用
在这种情况下,最好定义一个本地的 data property 并将这个 prop 用作其初始值
props: ['fatherMsg'],
data() {
return {
sonMsg: this.fatherMsg
}
},
2. 这个 prop 以一种原始的值传入且需要进行转换
在这种情况下,最好使用这个 prop 的值来定义一个计算属性
props: ['fatherMsg'],
computed: {
sonData() {
return this.fatherMsg.toUpperCase()
}
}
我们可以为组件的 prop 指定验证要求,例如你知道的这些类型,如果有一个需求没有被满足,则 Vue 会在浏览器控制台中警告你。
为了定制 prop 的验证方式,你可以为 prop 中的值提供一个带有验证需求的对象,而不是一个字符串数组。
props: {
// 基础的类型检查(null 和 undefined 会通过任何类型验证)
propA: Number,
// 多个可能的类型
propB: [String, Number],
// 必填的字符串
propC: {
type: String,
required: true
},
// 带有默认值的数字
propD: {
type: Number,
default: 100
},
// 带有默认值的对象
propE: {
type: Object,
// 对象或数组默认值必须从一个工厂函数获取
default: function () {
return { message: 'hello' }
}
},
// 自定义验证函数
propF: {
// 这个值必须匹配下列字符串中的一个
validator: function(value) {
return ['success', 'warning', 'danger'].indexOf(value) !== -1
}
}
}
子组件会对父组件传递过来的值进行类型校验,当 prop 验证失败的时候,开发环境构建版本的 Vue 将会产生一个控制台的警告
注意那些 prop 会在一个组件实例创建之前进行验证,所以实例的 property (如data、computed
等)在default
或validator
函数中是不可用的
type
可以是下列原生构造函数中的一个
想象一下
的模板是这样的
<input type="date" class="form-control">
为了给我们的日期选择器插件定制一个主题,我们可能需要向这样添加一个特别的类名
<bootstrap-date-input
data-date-picker="activated"
class="date-picker-theme-dark"></bootstrap-date-input>
以上这种情况,我们定义了两个不同的 class
的值:
form-control
:这是在组件的模板内设置好的date-picker-theme-dark
:这是从组件的父级传入的attribute
来说,从外部提供给组件的值会替换掉组件内部设置好的值。所以如果传入 type="text"
就会替换掉 type="date"
并把它破坏。class
和 style
attribute 会稍微智能一些,即两边的值会被合并起来,从而得到最终的值: form-control date-picker-theme-dark
dataInput.vue
<input type="date" class="form-control">
fatherAttribute.vue
<template>
<div>fatherAttribute
<data-input class="date-picker-theme-dark"></data-input>
</div>
</template>
<script>
import dataInput from './dataInput'
export default {
name: 'fatherAttribute',
components: {
dataInput
}
}
结果
如果给 fatherAttribute.vue
的组件中添加 type="text"
<div>fatherAttribute
<data-input type="text" class="date-picker-theme-dark"></data-input>
</div>