Prop 的大小写
组件里可以写驼峰命名法的名字,但是因为HTML是大小写不敏感的所以我们需要通过连接符来解决这个问题即,postTitle
属性在标签上要写为post-title
Vue.component('blog-post', {
// 在 JavaScript 中是 camelCase 的
props: ['postTitle'],
template: '<h3>{{ postTitle }}</h3>'
})
<!-- 在 HTML 中是 kebab-case 的 -->
<blog-post post-title="hello!"></blog-post>
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
}
Props动态传值和静态传值
- 字符串类型
//静态传入title属性
<blog-post title="My journey with Vue"></blog-post>
//动态传入
<!-- 动态赋予一个变量的值 -->
<blog-post v-bind:title="post.title"></blog-post>
- 数字类型
//likes是属性名字
<!-- 即便 `42` 是静态的,我们仍然需要 `v-bind` 来告诉 Vue -->
<!-- 这是一个 JavaScript 表达式而不是一个字符串。-->
<blog-post v-bind:likes="42"></blog-post>
<!-- 用一个变量进行动态赋值。-->
<blog-post v-bind:likes="post.likes"></blog-post>
- 布尔值类型
<!-- 包含该 prop 没有值的情况在内,都意味着 `true`。-->
<blog-post is-published></blog-post>
<!-- 这是一个 JavaScript 表达式而不是一个字符串。-->
<blog-post v-bind:is-published="false"></blog-post>
<!-- 用一个变量进行动态赋值。-->
<blog-post v-bind:is-published="post.isPublished"></blog-post>
- 数组类型
<!-- 这是一个 JavaScript 表达式而不是一个字符串。-->
<blog-post v-bind:comment-ids="[234, 266, 273]"></blog-post>
<!-- 用一个变量进行动态赋值。-->
<blog-post v-bind:comment-ids="post.commentIds"></blog-post>
- 对象类型
<blog-post
v-bind:author="{
name: 'Veronica',
company: 'Veridian Dynamics'
}"
></blog-post>
<!-- 用一个变量进行动态赋值。-->
<blog-post v-bind:author="post.author"></blog-post>
- 一个对象所有属性传入
//post只有俩个属性一个是id一个是title
<blog-post v-bind="post"></blog-post>
//等价于
<blog-post
v-bind:id="post.id"
v-bind:title="post.title"
></blog-post>
单向数据流
单向数据流的意思就是说,所有的 prop 都使得其父子 prop 之间形成了一个单向下行绑定:父级 prop 的更新会向下流动到子组件中,但是反过来则不行。
要注意的是,组件中使用props中的数据时,不要尝试修改它
- 如果在组件中,你想使用props中的属性作为原始的值,请转为本地属性使用
props: ['initialCounter'],
data: function () {
return {
counter: this.initialCounter
}
}
- props中的属性只是原始值,你需要对它进行转换后使用
props: ['size'],
computed: {
normalizedSize: function () {
return this.size.trim().toLowerCase()
}
}
对象和数组是引用值类型,如果你把它们传入组件并修改会影响到父组件的状态
Props验证
就是我们,可以给props的属性指定一个或多个类型,对它进行限制
基础的类型检查 (null
和 undefined
会通过任何类型验证)
type的范围:String
、Number
、Boolean
、 Array
、 Object
、Date
、Function
、Symbol
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
}
}
}
})
暂时没理解这段话:
prop 会在一个组件实例创建之前进行验证,所以实例的属性 (如 data、computed 等) 在 default 或 validator 函数中是不可用的。
使用属性和已有构造函数组成键值对,用来检测属性是否是该构造函数构造出来的
Vue.component('blog-post', {
props: {
author: Person
}
})`
非 Prop 的 Attribute
这个的意思就是说,我要向一个组件传递一个属性,但是这个属性并没有在prop中定义。
大概意思就是你在组件引用标签上写一些属性定义,这些属性定义就相当于写到组件的根标签上了
替换/合并已有的 Attribute
对于绝大多数 attribute 来说,从外部提供给组件的值会替换掉组件内部设置好的值。所以如果传入 type=“text” 就会替换掉 type=“date” 并把它破坏!,class 和 style attribute 会稍微智能一些,即两边的值会被合并起来,从而得到最终的结果。
禁用 Attribute 继承
俩个关键词inheritAttrs: false
和 v-bind="$attrs"
- inheritAttrs的作用是禁止组件内部继承非prop属性(不包括style和class)。
- v-bind="$attrs" 它的作用是把非prop属性拉到组件的内部某个子标签上去。例子如下
在组件的选项中设置 inheritAttrs: false。例如:
--------------------------组件调用部分
<base-input
label="姓名"
class="username-input"
placeholder="Enter your username"
data-date-picker="activated"
></base-input>
-------------组件写法--------
Vue.component("base-input", {
inheritAttrs: false, //此处设置禁用继承特性
props: ["label"],
template: `
<label>
{{ label }}
<input
v-bind="$attrs"
>
</label>`
});
----------------------
HTML结果
<label class="username-input">姓名
<input placeholder="Enter your username" data-date-picker="activated">
</label>
也就是说 v-bind="$attrs"
会把调用标签上的非prop属性(不包括class和style)复制一份放到组件中出现 v-bind="$attrs"
的标签上去。inheritAttrs: false
作用就是禁止继承(同样不包括class和style)