Prop
This page assumes that you have read Component Basics. If you don’t know much about components yet, I recommend you read it first.
Directory
#Prop case (camelCase vs kebab-case)
Attribute names in HTML are case-insensitive, so the browser will interpret all uppercase characters as lowercase characters. This means that when you use a template in the DOM, the camelCase prop name needs to use its equivalent kebab-case (dash separated naming) name:Vue.component('blog-post', { // 在 JavaScript 中是 camelCase 的 props: ['postTitle'], template: '<h3>{{ postTitle }}</h3>' })
<!-- 在 HTML 中是 kebab-case 的 --> <blog-post post-title="hello!"></blog-post>
Once again, if If you use string templates, this limitation does not exist.
Prop type
So far, we have only seen the string array form Listed props:props: ['title', 'likes', 'isPublished', 'commentIds', 'author']
However, usually you want each prop to have a specified value type. At this point, you can list the props in object form. The names and values of these properties are the respective names and types of the props:
props: { title: String, likes: Number, isPublished: Boolean, commentIds: Array, author: Object, callback: Function, contactsPromise: Promise // or any other constructor }
This not only provides documentation for your components, but also provides documentation when they encounter The wrong type is prompted when the user is prompted from the browser's JavaScript console. You'll see
type checking and other prop validationin the remainder of this page.
Pass static or dynamic Prop
Like this, you already know that you can pass a static value to prop like this:
<blog-post title="My journey with Vue"></blog-post>
You also know that prop can be dynamically assigned through v-bind
, for example:
<!-- 动态赋予一个变量的值 --> <blog-post v-bind:title="post.title"></blog-post> <!-- 动态赋予一个复杂表达式的值 --> <blog-post v-bind:title="post.title + ' by ' + post.author.name" ></blog-post>
In the above two examples, the values we pass in are all string types. , but in fact any type of value can be passed to a prop.
Pass in a number
<!-- 即便 `42` 是静态的,我们仍然需要 `v-bind` 来告诉 Vue --> <!-- 这是一个 JavaScript 表达式而不是一个字符串。--> <blog-post v-bind:likes="42"></blog-post> <!-- 用一个变量进行动态赋值。--> <blog-post v-bind:likes="post.likes"></blog-post>
Pass in a Boolean value
<!-- 包含该 prop 没有值的情况在内,都意味着 `true`。--> <blog-post is-published></blog-post> <!-- 即便 `false` 是静态的,我们仍然需要 `v-bind` 来告诉 Vue --> <!-- 这是一个 JavaScript 表达式而不是一个字符串。--> <blog-post v-bind:is-published="false"></blog-post> <!-- 用一个变量进行动态赋值。--> <blog-post v-bind:is-published="post.isPublished"></blog-post>
##Pass in an array
<!-- 即便数组是静态的,我们仍然需要 `v-bind` 来告诉 Vue --> <!-- 这是一个 JavaScript 表达式而不是一个字符串。--> <blog-post v-bind:comment-ids="[234, 266, 273]"></blog-post> <!-- 用一个变量进行动态赋值。--> <blog-post v-bind:comment-ids="post.commentIds"></blog-post>
Pass in an object
<!-- 即便对象是静态的,我们仍然需要 `v-bind` 来告诉 Vue --> <!-- 这是一个 JavaScript 表达式而不是一个字符串。--> <blog-post v-bind:author="{ name: 'Veronica', company: 'Veridian Dynamics' }" ></blog-post> <!-- 用一个变量进行动态赋值。--> <blog-post v-bind:author="post.author"></blog-post>
## Pass in all the properties of an objectIf you want to pass in all the properties of an object as props, you can use
v-bind## without parameters # (replacesv-bind:prop-name). For example, for a given object
post:
post: { id: 1, title: 'My Journey with Vue' }
the following template:
<blog-post v-bind="post"></blog-post>is equivalent to:
<blog-post v-bind:id="post.id" v-bind:title="post.title" ></blog-post>
All props form a
One-way downward binding between their parent and child props: Updates to parent props will flow downward to child components, but not vice versa. This will prevent the child component from accidentally changing the state of the parent component, making the data flow of your application difficult to understand.
In addition, every time the parent component is updated, all props in the child component will be refreshed to the latest values. This means that you should not
change props inside a child component. If you do this, Vue will issue a warning in the browser's console.There are two common situations where you try to change a prop:
1.This prop is used to pass an initial value; the subcomponent then wants to use it as a local prop data to use.
In this case, it is best to define a local data attribute and use this prop as its initial value:props: ['initialCounter'], data: function () { return { counter: this.initialCounter } }2. This prop is passed in as a primitive value and Conversion is required. In this case, it is best to use the value of this prop to define a computed property:
props: ['size'], computed: { normalizedSize: function () { return this.size.trim().toLowerCase() } }Note that in JavaScript objects and arrays are passed in by reference, so for an array Or object type prop, changing the object or array itself in the child component will affect the state of the parent component.
Prop Validation
We can specify validation requirements for component props, such as the types you know. If a requirement is not met, Vue will warn you in the browser console. This is especially helpful when developing a component that will be used by others.
To customize how props are validated, you can provide an object with validation requirements for the value in
props
instead of a string array. For example: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 } } } })When prop verification fails, Vue (development environment build version) will generate a console warning.
Note that those props will be verified before a component instance is created , so the properties of the instance (such as
data
,computed
, etc. ) is not available indefault
orvalidator
functions.Type check
type
can be in the following native constructor A:can also be a custom constructor, and checked through
String
##Number
- ##Boolean
- Array
##Object
- Date
- Function
- Symbol
- type
In addition,
instanceof
. For example, given the following ready-made constructor:
function Person (firstName, lastName) { this.firstName = firstName this.lastName = lastName }you can use:
Vue.component('blog-post', { props: { author: Person } })to verify that the value of theauthor
prop is passednew Person
Created.
Non-Prop attributes
A non-prop attribute is passed to a component , but the component does not have the characteristics defined by the corresponding prop.
Because explicitly defined props are suitable for passing information to a subcomponent, however, the author of the component library cannot always foresee what scenarios the component will be used for. This is why components can accept arbitrary attributes, and these attributes will be added to the root element of the component. For example, imagine that you use a third-party<bootstrap-date-input>
component through a Bootstrap plug-in that requires a third-party<input>
uses a
data-date-pickerfeature. We can add this attribute to your component instance:
<bootstrap-date-input data-date-picker="activated"></bootstrap-date-input>Then this
data-date-picker="activated" attribute will be automatically added to<bootstrap- On the root element of date-input>
.
Replace/merge existing features
Imagine<bootstrap-date -input>
The template is like this:<input type="date" class="form-control">In order to customize a theme for our date picker plugin, we may need to add a special class name like this:
<bootstrap-date-input data-date-picker="activated" class="date-picker-theme-dark" ></bootstrap-date-input>In this case, we define two different ## The value of #class
:
For most features, it is provided externally to The value of the component will replace the value set internally in the component. So if
form-control
, which is set in the template of the component
date-picker-theme-dark
, which is passed in from the parent of the component
type="text"
is passed in,
type="date"will be replaced and destroyed! Fortunately, the
classand
styleattributes are a little smarter, i.e. the values on both sides are combined to get the final value:
form-control date-picker- theme-dark.
Disable attribute inheritance
If youdon't want the root element of the component To inherit attributes, you can set inheritAttrs: false
in the component's options. For example:
Vue.component('my-component', { inheritAttrs: false, // ... })This is especially suitable for use with the instance's$attrs
attribute, which contains the attribute name and attribute value passed to a component, for example:
{ required: true, placeholder: 'Enter your username' }has WithinheritAttrs: false
and
$attrs, you can manually decide which element these attributes will be assigned to. It is often used when writing
basic components:Vue.component('base-input', { inheritAttrs: false, props: ['label', 'value'], template: ` <label> {{ label }} <input v-bind="$attrs" v-bind:value="value" v-on:input="$emit('input', $event.target.value)" > </label> ` })Note:inheritAttrs: false
This mode allows you to use base components more like raw HTML elements without worrying about which element is the real root element:The option
will not affect # Binding of ##style andclass
.<base-input v-model="username" required placeholder="Enter your username" ></base-input>