Vue. Js components
Components are reusable Vue instances. Components are used to encapsulate some functions of a page, and encapsulate the structure, style, and logical code of a function as a whole. This improves the reusability and maintainability of functionality, allowing us to focus better on business logic.
The component is a custom HTML tag. The component name is used as the custom tag name.
<div id="app">
<! -- Normal p tag -->
<p>This is the P tag</p>
<! -- Vue.js component -->
<my-component></my-component>
</div>
Copy the code
The official documentation
The component registration
Component creation.
Global registration
Globally registered components can be used in any VUE instance or component.
// Global component registration must precede root instance creation
Vue.component('my-component', {
template: This is our globally registered component
})
/ / root instance
new Vue({
el: '#app'.data: {}})Copy the code
use
<! App2 vUE instance app2 vUE instance app2 vUE instance app2
<div id="app">
<p>This is the P tag</p>
<! -- Vue.js component -->
<my-component></my-component>
</div>
Copy the code
Component based
Components are essentially reusable VUE instances, so they can receive the same options as new VUE, such as Data, methods, and lifecycle hooks. But options like EL are specific to the root instance, and components cannot receive el options.
Component naming rules
First (dash split), kebab-case: ‘my-component’
Second (uppercase, camel name), PascalCase: ‘MyComponent’
// kebab-case to register
Vue.component('my-com-a', {
template: '
This is the content of a component
'
});
// PascalCase to register
Vue.component('MyComB', {
template: '
This is the content of the B component
'
});
Copy the code
But no matter which way you write it, only kebab-case can be used in the DOM.
<! -- Component usage -->
<my-com-a></my-com-a>
<my-com-b></my-com-b>
Copy the code
The template options
The template option is used to set the structure of the component, which is eventually introduced into the root instance or other components.
Vue.component('MyComA', {
template: This is the content of component A: {{1 + 2 * 3}} '
})
Copy the code
The data options
The data option is used to store the component’s data. Unlike the root instance, the component’s data option must be a function, and the data is set in the return value of the function. This is done to ensure that each component instance can maintain its own copy of the returned object without interfering with each other.
Vue.component('MyComA', {
template: `
{{ title }}
{{ content }}
`,
data () {
return {
title: 'This is the component title'.content: 'This is component content'}}})Copy the code
Local registration
A partially registered component can only be used in the current instance.
new Vue({ el: '#app', data: { }, components: { 'my-com-a': { template: ` < div > < h3 > {{title}} < / h3 > < p > {{content}} < / p > < / div > `, data () {return {title: 'component A title, the content: 'Component A contents'}}},}});Copy the code
use
<div id="app">
<my-com-a></my-com-a>
</div>
Copy the code
Configure the option object for the component separately
If there are too many local components, it is not very convenient to modify the content of component options. In this case, it is much easier to configure the component option object separately, which helps improve maintainability.
// The option object for component A
var MyComponentA = {
template: `
{{ title }}
{{ content }}
`,
data () {
return {
title: 'Component A heading'.content: 'Component A contents'}}};// The option object for component B
var MyComponentB = {
template: `
{{ title }}
{{ content }}
`,
data () {
return {
title: 'component B'.content: 'Component B content'}}}new Vue({
el: '#app'.data: {},components: {
'my-component-a': MyComponentA,
MyComponentB MyComponentB: MyComponentB}})Copy the code
Component communication
Component communication refers to the operation of transferring data between components.
Parent component passes value to child component
Receives a value from the parent component via the props option of the child component.
// Create a child component
Vue.component('my-component-a', {
// The props option should not have the same attribute as the data option, otherwise there will be overwriting problems
props: ['title'.'content'].template: `
{{ title }}
{{ content }}
`
})
new Vue({
el: '#app'.data: {
item: {
title: 'Here's the sample title'.content: 'Here's the sample content'}}})Copy the code
Receive data using the props option
<! -- Static property Settings -->
<my-component-a
title="This is a static title."
content="This is static content."
></my-component-a>
<! -- Dynamic property binding -->
<my-component-a
:title="item.title"
:content="item.content"
></my-component-a>
Copy the code
Props naming rules: It is recommended to use camelCase for prop naming and kebab-case for parent component binding.
The official documentation
Unidirectional data flow
All prop between parent and child components are bound one-way down, which is called the one-way data flow feature of a component prop. That is, if the parent component value changes, the prop value of the child component changes; otherwise, the change of the prop value of the child component does not affect the parent component value.
If prop data is to be processed by a child component, it should be stored in data to avoid processing prop data directly.
Vue.component('my-component', {
props: ['innerTitle'].template: `
{{ title }}
`,
data () {
return {
title: this.innerTitle
}
}
})
Copy the code
Note: If prop is an array or an object, child operations on it affect the state of the parent. Because arrays or objects are passed addresses by the parent component, due to the prop one-way data flow feature, we cannot change the address reference of arrays or objects, but we can change their internal property values, which affects the parent component as well.
There are two ways to eliminate this effect:
- When an array or object is passed in, a copy of it is stored in data and then manipulated
- Instead of passing in arrays, pass in values that the child components need
Props type
When you declare props, you can also set the type of the value that can be received, and Vue will report an error if the value passed does not match the set type.
props: {
parStr: String.parNum: Number.parArr: Array.parObj: Object.parAny: undefined.// null
parData: [String.Boolean]},Copy the code
Props to verify
When multiple rules need to be set on prop, you can set the value of prop as an option object.
props: {
// Basic type checking (' null 'and' undefined 'will pass any type verification)
propA: Number.// Multiple possible types
propB: [String.Number].// A mandatory string
propC: {
type: String.required: true
},
// A number with default values
propD: {
type: Number.default: 100
},
// Objects with default values
propE: {
type: Object.// Object or array defaults must be obtained from a factory function
default: function () {
return { message: 'hello'}}},// Customize the validation function
propF: {
validator: function (value) {
// Vue will prompt you with an error if the return value is false
This value must match one of the following strings
return ['success'.'warning'.'danger'].indexOf(value) ! = = -1}}},Copy the code
Note: Data, methods and other functions of the instance cannot be used in the verification function. Because the validation process is done before the instance is created.
The props attribute
When a parent component gives a property to a child component that does not exist in the props, it is automatically bound to the root element of the child component.
If the component root element already has an attribute, the value inside the component is replaced. The exception is the class and style attributes, which are automatically merged when both inside and outside are set.
If you don’t want to inherit properties set by the parent component, you can set inheritAttrs: False, but only for ordinary properties, leaving class and style unaffected.
Vue.component('MyComponent', {
inheritAttrs: false.template: '
});
Copy the code
The value of
<div id="app">
<my-component
data-index="3"
:title="' Sample header content '"
style="height: 200px;"
class="colorRed"
></my-component>
</div>
Copy the code
Child components pass values to parent components
When the parent passes a value, the child is processed and may need to return the processed result to the parent. For example, if an item is a child component and a shopping cart is a parent component, the parent component needs to obtain the number of items, so the child component needs to pass the value to the parent component when the number changes.
The child component sends a value to the parent component by firing a custom event via $emit(), and the parent component listens for the custom event to fetch the value. You are advised to use kebab-case (dash dash) to name user-defined events.
Child components
Vue.component('ProductItem', {
props: ['title'].template:
{{title}} {{ count }}
`,
data () {
return {
count: 0}},methods: {
countIns1 () {
// 1 is the value to be passed
this.$emit('count-change'.1);
this.count++;
},
countIns5 () {
// 5 is the value to be passed
this.$emit('count-change'.5);
this.count += 5; }}});Copy the code
The parent component
new Vue({
el: '#app'.data: {
products: [{id: 1.title: 'A catty of apples'
},
{
id: 2.title: 'A banana'
},
{
id: 3.title: 'One orange'}].totalCount: 0
},
methods: {
onCountChange (productCount) {
this.totalCount += productCount; }}});Copy the code
The value of
<div id="app">
<h3>The shopping cart</h3>
<product-item
v-for="product in products"
:key="product.id"
:title="product.title"
@count-change="onCountChange"
></product-item>
<p>{{totalCount}}</p>
</div>
Copy the code
Components and v – model
When v-model is used for components, it needs to be implemented using props and custom functions.
Child components
/ / child component
var ComInput = {
props: ['value'].template: ` `.// @input="$emit('input', $event.target.value)"
methods: {
onInput (event) {
this.$emit('input', event.target.value)
}
}
}
Copy the code
The parent component
new Vue({
el: '#app'.data: {
iptValue: ' '
},
components: {
ComInput
}
});
Copy the code
The value of
<div id="app">
<p>The input box contains the following contents: {{iptValue}}</p>
<com-input v-model="iptValue"></com-input>
</div>
Copy the code
Non-parent components pass values
The first method is to relay data through the parent component:
Sibling component B-> parent component A-> sibling component C
However, when the nested relationship of components is complex, this way of transferring values is more complicated.
The second method, EventBus, is also called the EventBus
EventBus
The EventBus is an independent event center that manages the transfer of values between different components.
EventBus manages component-passing operations through a new Vue instance, where components register and invoke events to pass data to the instance. The component that sends data triggers a BUS event, and the component that receives data registers the corresponding event with the BUS.
Create the eventbus.js file
// Eventbus. js file contents
const bus = new Vue()
Copy the code
Introducing the EventBus. Js
<script src="lib/vue.js"></script>
<! -- Eventbus.js after vue.js -->
<script src="EventBus.js"></script>
Copy the code
Component A
// Commodity components
Vue.component('ProductItem', {
template: {{count}}+1 ',
data () {
return {
count: 0}},methods: {
countIns () {
// Trigger custom events for bus to pass data
bus.$emit('countChange'.1);
this.count++; }}});Copy the code
The component B
// Count components
Vue.component('ProductTotal', {
template: ' total number: {{totalCount}}
',
data () {
return {
totalCount: 0
}
},
created () {
// Register events with bus and receive data
bus.$on('countChange'.(productCount) = > {
// After the instance is created, you can use data and other functions
this.totalCount += productCount; }); }})Copy the code
The root instance
/ / root instance
new Vue({
el: '#app'.data: {}});Copy the code
EventBus can transfer values between any component. This is just an example of sibling components
<div id="app">
<h3>The shopping cart</h3>
<product-item></product-item>
<product-total></product-total>
</div>
Copy the code
Other means of communication
There are two ways to manipulate other components directly:
-
$root
Used to access the current component root instance and to pass values between components.
It is not recommended to be used in small test components.
The official documentation
In addition, $parent, $children, and $root are similar for easy access to parent and child components. It is not recommended for ordinary use.
-
$refs
The ref attribute assigns an ID reference to an HTML tag or component for direct access in JavaScript.
$refs, used after the page is rendered to get the HTML tag or subcomponent with the ref attribute set.
The official documentation
component
var ComA = { template: '
Component A contents: {{value}}', data () { return { value: 'Sample content'}}}var vm = new Vue({ el: '#app'.methods: { fn () { this.$refs.comA.value = 'New content'}},components: { ComA }, // execute after the page is rendered mounted () { console.log(this.$refs) this.$refs.comA.value = "Modified content"}})Copy the codeHTML
<div id="app"> <! Set the ref attribute to the child component --> <com-a ref="comA"></com-a> <button @click="fn">button</button> </div> Copy the code
Component slot
Component slots allow you to easily set component contents.
<! Components without component slots cannot set content like normal HTML tags.
<com-a></com-a>
<! -- Components with component slots can be easily set component content -->
<com-b>This is a component with slots</com-b>
Copy the code
A single slot
Slot Settings are required using
Vue.component('ComA', {
template: Components ` < div > < h3 > title < / h3 > < slot > this is the default content of slot < / slot > < / div > `,
data () {
return {
value: 'Child component data'}}});Copy the code
Setting component content
<div id="app">
<com-a>This is the content of the component</com-a>
<com-a>This is the content of the second component:<span>This is span</span>
</com-a>
<com-a>Here is the parent component's view template, which can only use the parent's data: {{parValue}}</com-a>
<com-a></com-a>
</div>
Copy the code
A named slot
If there are multiple locations in the build that require slots, give
a name as required. Such named slots are called named slots.
If
is not set to name, the default name is default.
/ / child component
Vue.component('ComA', {
template: `
`
});
Copy the code
Setting component content
<div id="app">
<com-a>
<template v-slot:header>
<h3>The header content of the component</h3>
</template>
<! -- <template v-slot:default> <p> The body of the component 1</p> <p> The body of the component 2</p> </template> -->
<! -- equivalent to the comment section above -->
<p>Body content of the component 1</p>
<p>Body content of the component 2</p>
<! -- slot: # -->
<template #footer>
<p>Component Bottom Content</p>
</template>
</com-a>
</div>
Copy the code
Scope slot
A normal slot can only use parent component data, whereas a scoped slot can use child component data.
The component uses V-bind to
the data that needs to be used by the slot. This property for passing data to the slot is called slot prop.
// Option object for child component B
var ComB = {
template: ` < div > < p > the content of the component B: < / p > < slot: value = "value" : num = "num" > < / slot > < / div > `,
data () {
return {
value: 'This is the data inside component B.'.num: 200}}}// The option object of child component A
var ComA = {
template:
Contents of component A:
`,
data () {
return {
value: 'This is the data inside component A.'.num: 100}}}Copy the code
Setting component content
<div id="app">
<! -- Multiple slots with scope slot writing mode -->
<com-a>
<template v-slot:default="dataObj">
{{ dataObj.value }}
{{ dataObj.num }}
</template>
<template v-slot:footer="dataObj">
{{ dataObj.value }}
</template>
</com-a>
<! -- Slot writing with default slot scope only -->
<! -- <com-b v-slot="dataObj"> -->
<com-b #default="dataObj">
{{ dataObj }}
</com-b>
<! Receive data from scope slot via ES6 destruct operation
<com-b v-slot="{ value, num }">
{{ value }}
{{ num }}
</com-b>
</div>
Copy the code
Built-in component
Dynamic components
Dynamic components are suitable for handling the frequent switching of multiple components. Such as TAB switching and so on.
< Component > is used to render a ‘meta-component’ as a dynamic component, with the IS attribute determining which component to render.
<! -- Component sets dynamic components -->
<component :is="currentCom"></component>
Copy the code
We can do this by dynamically changing the component currentCom points to.
<div id="app">
<! -- The button represents the title function of the TAB -->
<button
v-for="title in titles"
:key="title"
@click="currentCom = title"
>
{{ title }}
</button>
<! -- Component sets dynamic components -->
<component :is="currentCom"></component>
</div>
<script src="lib/vue.js"></script>
<script></script>
Copy the code
Keep alive – components
The keep-alive component can be used if we want to avoid rerendering or preserving the component state during the dynamic component switch.
<! Set which components will be cached by include -->
<! -- No Spaces between string comma delimiters -->
<! -- <keep-alive include="ComA,ComB,ComC"> -->
<! -- <keep-alive :include="['ComA', 'ComB', 'ComC']"> -->
<! -- <keep-alive :include="/Com[ABC]/"> -->
<! Exclude specifies which components will not be cached.
<! -- <keep-alive exclude="ComD"> -->
<! -- <keep-alive :exclude="['ComD']"> -->
<! -- <keep-alive :exclude="/ComD/"> -->
<! -- Set the maximum number of cache components -->
<keep-alive max="2">
<! -- Dynamic Component -->
<component :is="currentCom"></component>
</keep-alive>
Copy the code
Transitional components
Provides a variety of transitions and animations for Vue when inserting, updating, or removing the DOM. Mainly include:
- The transition component
- Custom transition class name
- The transition – group components
The transition component
Used to provide entry and exit transitions for elements and components:
- Conditional Rendering (V-IF)
- Conditional Display (V-show)
- Dynamic components
- Component root node
<transition>
<p v-if="show">hello world</p>
</transition>
Copy the code
The component provides six classes for setting the concrete effects of transitions.
<style>
/* Sets the final state of the appearance */
.v-leave-to {
opacity: 0;
}
/* Set the execution of the transition */
.v-leave-active {
transition: opacity 1s;
}
/* Sets the initial state of entry */
.v-enter {
opacity: 0;
}
/* Sets the final state of entry */
.v-enter-to {
opacity: 0.5;
}
/* Set up the entry process */
.v-enter-active {
transition: all 1s;
}
</style>
Copy the code
Transition component related properties
-
The name attribute can be used to set different transition effects for multiple elements and components. In this case, you need to change the form of V – to the corresponding name-.
Such as:
The corresponding class name prefix is demo-Enter, etc.
-
By setting the Appear property, you can transition components during initial rendering.
Custom transition class name
Custom class names take precedence over regular class names and are useful when using third-party CSS animation libraries.
The attributes used to set the custom transition class name are as follows:
- enter-class
- enter-active-class
- enter-to-class
- leave-class
- leave-active-class
- leave-to-class
The properties used to set the initial transition class name are as follows:
- appear-class
- appear-to-class
- appear-active-class
<transition
enter-active-class="test"
leave-active-class="test"
>
<p v-if="show">This is the P tag</p>
</transition>
Copy the code
Animate.css
Animate. CSS is a third-party CSS animation library that uses class names to Animate elements.
The Animate. CSS website
CDN reference
<link
rel="stylesheet"
href="https://cdnjs.cloudflare.com/ajax/libs/animate.css/4.1.1/animate.min.css"
/>
<! -- Compatible version of the animate__ prefix is not required, but the full version is recommended.
<! - "https://cdnjs.cloudflare.com/ajax/libs/animate.css/4.0.0/animate.compat.css" -- >
Copy the code
use
<! -- Add a third party animation library class name effect to the component using custom transition class name Settings -->
<transition
enter-active-class="animate__bounceInDown"
leave-active-class="animate__bounceOutDown"
>
<! Animate__animated --> Animate__animated --> Animate__animated
<p
v-if="show"
class="animate__animated"
>hello world</p>
</transition>
Copy the code
Matters needing attention:
- Animate__ prefix version and compat version selection problem, recommend to choose prefix version
- Remember the base class name animate__animated
The transition – group components
- The tag attribute is used to set container elements, which default to
<span>
- Transitions are applied to inner elements, not containers
- Child nodes must have independent keys for the animation to work properly
<transition-group
tag="ul"
>
<li
v-for="item in items"
:key="item.id"
>
{{ item.title }}
</li>
</transition-group>
Copy the code
When a list element changes and the element moves, you can set the effect of the move by using the.v-move class name
.v-move {
transition: all .5s;
}
Copy the code
The other transition styles are set the same as the Transition component.