# Prop
# Prop大小写
HTML中元素的特性(属性)是大小写不敏感的,浏览器会把所有大写字符都转为小写。需要注意将驼峰命名转为短横线分隔命名
<!-- 在 HTML 中是 kebab-case 的,如果使用字符串模板,就没有该限制 -->
<blog-post post-title="hello!"></blog-post>
<script>
Vue.component('blog-post', {
// 在 JavaScript 中是 camelCase 的
props: ['postTitle'],
template: '<h3>{{ postTitle }}</h3>'
})
</script>
# Prop类型
props除了可以是数组外,还可以是对象,用来指定每个prop的数据类型
// 数组
props: ['title', 'likes', 'isPublished', 'commentIds', 'author']
// 对象
props: {
title: String,
likes: Number,
isPublished: Boolean,
commentIds: Array,
author: Object,
callback: Function,
contactsPromise: Promise // or any other constructor
}
# Prop可以传入静态或动态的值
传入的变量,这个变量可以是各种数据类型的。下面主要介绍内嵌的写法:
- 当内嵌写法,且传入布尔属性true时,可以直接省略赋值
- 当以内嵌写法传入false、数组、对象时,需要使用v-bind,告知这时一个js表达式而不是一个字符串。
<!-- 1. 传一个布尔值 -->
<!-- 包含该 prop 没有值的情况在内,都意味着 `true`。-->
<blog-post is-published></blog-post>
<!-- 即便 `false` 是静态的,我们仍然需要 `v-bind` 来告诉 Vue -->
<!-- 这是一个 JavaScript 表达式而不是一个字符串。-->
<blog-post v-bind:is-published="false"></blog-post>
<!-- 2.传入一个数组 -->
<!-- 即便数组是静态的,我们仍然需要 `v-bind` 来告诉 Vue -->
<!-- 这是一个 JavaScript 表达式而不是一个字符串。-->
<blog-post v-bind:comment-ids="[234, 266, 273]"></blog-post>
<!-- 3.传入一个对象-->
<!-- 这是一个 JavaScript 表达式而不是一个字符串。-->
<!-- 即便对象是静态的,我们仍然需要 `v-bind` 来告诉 Vue -->
<blog-post
v-bind:author="{
name: 'Veronica',
company: 'Veridian Dynamics'
}"
></blog-post>
# 单向数据流
父组件prop值的更新会传到子组件,而子组件的prop值更新不会传到父组件,用来防止从子组件意外改变父级组件的状态,从而导致你的应用的数据流向难以理解。
注意也有例外:由于在 JS 中对象和数组是通过引用传入的,所以对于一个数组或对象类型的 prop 来说,在子组件中改变这个对象或数组本身将会影响到父组件的状态。
子组件内部不应该改变prop的值
# Prop验证
子组件接收传值时,可以对传值进行校验,比如数据类型、是否必须传入,主要用于开发可能会被别人用到的组件时会很有帮助
注意那些 prop 会在一个组件实例创建之前进行验证,所以实例的属性 (如 data、computed 等) 在 default 或 validator 函数中是不可用的。
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: function () {
return { message: 'hello' }
}
},
// 自定义验证函数
propF: {
validator: function (value) {
// 这个值必须匹配下列字符串中的一个
return ['success', 'warning', 'danger'].indexOf(value) !== -1
}
}
}
})
# type数据类型检查
除了下面的type之外,还支持自定义的构造函数,如定义了Person对象,检查type也可以是Person
- String
- Number
- Boolean
- Array
- Object
- Date
- Function
- Symbol
# 非props里面的特性(属性)
如果自定义组件元素的特性,不在子组件的props声明里。默认情况下,style、class属性会和子组件属性合并。其他属性会被替代
<!-- <div ma-ma="dd" class="k2 k1"> ... </div> -->
<div id="app">
<test-com sec="test" ma-ma="dd" class="k1"></test-com>
</div>
<script>
Vue.component('test-com', {
// inheritAttrs: false,
props: ['sec'],
/**
* 注意template里面,只会渲染第一个元素
* 如果<span>1</spapn><span>2</span> 只会渲染第一个。
* 内容尽量用一个元素包裹,如div或section
* inheritAttrs: false 会禁用继承,渲染如下:
* <div ma-ma="123" class="k2 k1"> ... </div>
*/
template: `
<div class="k2" ma-ma="123">
<span>str1</span>
<div>
<span>str2</span>
str3
</div>
<span>{{ sec }}</span>
</div>
`
})
var app = new Vue({
el: '#app',
data: {
}
})
</script>
# 禁用继承,$attrs
- inheritAttrs: false 会禁用继承
- $attrs 包含了父作用域中不作为 prop 被识别 (且获取) 的特性绑定 (class 和 style 除外)。通过 v-bind="$attrs" 传入内部组件——在创建高级别的组件时非常有用。