Prop
字符串数组形式列出的 prop:
props: ['title', 'likes', 'isPublished', 'commentIds', 'author']
prop 各自的名称和类型
props: {
title: String,
likes: Number,
isPublished: Boolean,
commentIds: Array,
author: Object,
callback: Function,
contactsPromise: Promise // or any other constructor
}
传递静态或动态 Prop
给 prop 传入一个静态的值
<blog-post title="My journey with Vue"></blog-post>
prop 可以通过 v-bind
动态赋值
<!-- 动态赋予一个变量的值 -->
<blog-post v-bind:title="post.title"></blog-post>
<!-- 动态赋予一个复杂表达式的值 -->
<blog-post
v-bind:title="post.title + ' by ' + post.author.name"
></blog-post>
需要 v-bind
来告诉 Vue 这是一个 JavaScript 表达式而不是一个字符串。
- 传入数字
- 传入布尔值
- 传入数组
- 传入对象
单向数据流
所有的 prop 都使得其父子 prop 之间形成了一个单向下行绑定:父级 prop 的更新会向下流动到子组件中,但是反过来则不行,这样会防止从子组件意外变更父级组件的状态,从而导致你的应用的数据流向难以理解。
每次父级组件发生变更时,子组件中所有的 prop 都将会刷新为最新的值。这意味着你不应该在一个子组件内部改变 prop
注意在 JavaScript 中对象和数组是通过引用传入的,所以对于一个数组或对象类型的 prop 来说,在子组件中改变变更这个对象或数组本身将会影响到父组件的状态。
Prop 验证
例如你知道的这些类型。如果有一个需求没有被满足,则 Vue 会在浏览器控制台中警告你
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
}
}
}
})
替换/合并已有的 Attribute]
class
和 style
attribute 值会被合并起来
禁用 Attribute 继承
如果你不希望组件的根元素继承 attribute,你可以在组件的选项中设置 inheritAttrs: false
。例如:
Vue.component('my-component', {
inheritAttrs: false,
// ...
})
自定义事件
事件名不存在自动大小写转换,在v-on
事件监听器DOM模板中会自动转化为小写
自定义组件v-model
一个组件上的 v-model
默认会利用名为 value
的 prop 和名为 input
的事件
但是像单选框、复选框等类型的输入控件可能会将 value
attribute 用于不同的目的
Vue.component('base-checkbox', {
model: {
prop: 'checked',
event: 'change'
},
props: {
checked: Boolean
},
template: `
<input
type="checkbox"
v-bind:checked="checked"
v-on:change="$emit('change', $event.target.checked)"
>
`
})
将原生事件绑定到组件
想要在一个组件的根元素上直接监听一个原生事件。这时,你可以使用 v-on
的 .native
修饰符:
但元素实际上是一个 <label>
元素的时候监听不到:
包含了父作用域中不作为 prop 被识别 (且获取) 的特性绑定
$attrs可以接受上级传递过来的属性
<label>
{{ label }}
<input
v-bind="$attrs"
v-bind:value="value"
v-on:input="$emit('input', $event.target.value)"
>
</label>
Vue 提供了一个 $listeners
property,它是一个对象,里面包含了作用在这个组件上的所有监听器
{
focus: function (event) { /* ... */ }
input: function (value) { /* ... */ },
}
就可以配合 v-on="$listeners"
将所有的事件监听器指向这个组件的某个特定的子元素
.sync
修饰符
真正的双向绑定会带来维护上的问题,因为子组件可以变更父组件,且在父组件和子组件两侧都没有明显的变更来源
带有 .sync
修饰符的 v-bind
不能和表达式一起使用
例如 v-bind:title.sync=”doc.title + ‘!’”
是无效的
简写双向绑定的语法糖
父
<child :title.sync="title"> </child>
子
<input :value="title" @input="abc" type="text">
props: {
title: {
type: String,
required: true
}
},
methods: {
abc(e) {
console.log(e.target.value);
this.$emit('update:title', e.target.value);
}
}