Component systems are another important concept for Vue because it is an abstraction that allows us to build large applications from small, independent, and often reusable components. If you think about it, almost any type of application interface can be abstracted as a component tree:
Vue.component('todo-item', {// Todo-item components now accept a // "prop", similar to a custom attribute. // This prop is named todo. props: ['todo'], template: '<li>{{ todo.text }}</li>' })Copy the code
The sub-unit is well decoupled from the parent unit through the PROP interface.
Vue components provide some important functionality that pure custom elements
do not, most notably cross-component data flow, custom event communication, and build tool integration.
First, basic components
- Components are reusable Vue instances with a name that receive the same options as new Vue, such as Data, computed, Watch, Methods, and lifecycle hooks. The only exceptions are root instance-specific options like EL.
- Because every time you use a component, a new instance of it is created.
- A component’s data option must be a function
- Component registration types: global and local
Two, local components
A locally registered component is not available in its children
Suitable for business components
Copy the code
Global components
-
use
Vue.component('my-component-name', { // ... Options... })Copy the code
-
Automated global registration of the underlying components
-
Global registration
- Webpack used in
require.context
Global registration src/main.js
Global import in
- Webpack used in
-
Note: The behavior of global registration must occur before the root Vue instance (via new Vue) is created
Component parameters
- No specified type
props: ['title', 'likes', 'isPublished', 'commentIds', 'author'] Copy the code
- Each prop has a specified value type
props: { title: String, likes: Number, isPublished: Boolean, commentIds: Array, author: Object, callback: Function, contactsPromise: Promise // or any other constructor } Copy the code
- Pass in different types of props
-
Pass in a Boolean value
<! -- means' true ', including cases where the prop has no value. --> <blog-post is-published></blog-post> <! -- Even if 'false' is static, we still need 'v-bind' to tell Vue --> <! This is a JavaScript expression, not a string. --> <blog-post v-bind:is-published="false"></blog-post>Copy the code
-
Pass in all properties of an object
If you want to pass in all of an object’s properties as prop, you can use v-bind with no arguments (instead of V-bind :prop-name). For example, for a given object post:
<blog-post v-bind="post"></blog-post>Copy the code
Prop validation
5. Parameter transfer between components
-
Unidirectional data flow
All prop forms a one-way downlink binding between their parent prop: updates to the parent prop flow down to the child, but not the other way around. This prevents accidental changes in the state of the parent component from the child, which can make the data flow of your application difficult to understand.
Additionally, every time the parent component changes, all prop in the child component will be refreshed to the latest value. This means that you should not change a prop inside a child component. If you do, Vue will issue a warning in the browser console.
There are two common cases of trying to change a prop:
- This prop is used to pass an initial value; This child component next wants to use it as a local prop data. In this case, it is best to define a local data Property and use this prop as its initial value:
props: ['initialCounter'], data: function () { return { counter: this.initialCounter } } Copy the code
This prop is passed in as a raw value and needs to be converted. In this case, it is best to use the value of this prop to define a calculated property:
props: ['size'], computed: { normalizedSize: function () { return this.size.trim().toLowerCase() } } Copy the code
PS: Note that in JavaScript objects and arrays are passed in by reference, so for a prop of an array or object type, changing the object or array itself in a child component will affect the state of the parent component.
- Props to verify
Vue.component('my-component', {props: {// Basic type checking (' null 'and' undefined 'will pass any type verification) propA: Number, // multiple possible types propB: [String, Number], // Required String propC: {type: String, required: true}, // Numbers with default values propD: {type: Number, default: 100}, // Object with default values propE: {type: Object, // Object or array default values must be obtained from a factory function default: function () {return {message: 'hello'}}}, // custom validation function propF: {validator: Function (value) {// This value must match one of the following strings: return ['success', 'warning', 'danger'].indexof (value)! == -1}}}})Copy the code
PS Note: Those prop are validated before a component instance is created, so instance properties (such as data, computed, and so on) are not available in default or Validator functions.
- Type checking
Type checking Type can be one of the following native constructors:
String
Number
Boolean
Array
Object
Date
Function
Symbol
Copy the code
In addition, type can be a custom constructor and checked with instanceof. For example, given the following ready-made constructor:
function Person (firstName, lastName) {
this.firstName = firstName
this.lastName = lastName
}
Copy the code
You can use:
Vue.component('blog-post', {
props: {
author: Person
}
})
Copy the code
To verify that the value of author Prop was created by new Person.
- The Attribute of the Prop
-
Imagine a template like this: To customize a theme for our date picker plug-in, we might add a special class name like this:
<bootstrap-date-input data-date-picker="activated" class="date-picker-theme-dark" > </bootstrap-date-input> Copy the code
In this case, we define two different class values:
Form-control, which is set in the component’s template
Date-picker-theme-dark, which is passed in from the component’s parent. For most attributes, the value supplied externally to the component replaces the value set internally by the component. So if you pass type=”text” it will replace type=”date” and break it! Fortunately, the class and style attributes are a little smarter, and the values on both sides are merged to get the final value: form-control date-picker-theme-dark.
-
Disabling Attribute Inheritance
If you don’t want the component’s root element to inherit attributes, you can set inheritAttrs: false in the component’s options. Such as:
Vue.component('my-component', { inheritAttrs: false, // ... }) Copy the code
This is especially useful with the instance’s $attrs property, which contains the attribute name and value passed to a component, for example:
{ required: true, placeholder: 'Enter your username' } Copy the code
With inheritAttrs: false and $attrs, you can manually determine which element these attributes will be assigned to. This 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>` }) Copy the code
Note that the inheritAttrs: false option does not affect the style and class bindings.
This pattern allows you to use base components more like raw HTML elements, without worrying about which element is the real root element:
<base-input v-model="username" required placeholder="Enter your username" > </base-input> Copy the code
-