There are tens of millions of front-end frames, and the unique vue accounts for half
I'm the fashion. Let's take a rocket to learn Vue
Chapter 13: components in Vue (difficulties)
Review of the previous chapter: That's all for the animation transition in Vue today.
"Good guy, cow, this animation is OK, just remember several class names? Continue," said the fashion.
"Yes, young man, come on, the whole difficulty, the components in Vue!!!" the old man said loudly.
"Come on, come on," said the fashion
Vue.js component
Component is one of the most powerful functions of Vue.js.
Components can extend HTML elements and encapsulate reusable code.
The component system allows us to build large-scale applications with independent reusable small components. The interface of almost any type of application can be abstracted into a component tree:
For example, you may have components such as page header, sidebar and content area, and each component contains other components such as navigation links and blog posts.
Global component
// register Vue.component('my-component', { template: '<div>A custom component</div>' }) |
// Create root instance new Vue({ el: '#app' }) |
// Template <div id="app"> <my-component></my-component> </div> |
These components are registered globally. That is, they can be used in the template of any newly created Vue root instance (new Vue) after registration
Local registration
Local registration
var Child = { template: '<div>A custom component</div>' } new Vue({ // ... components: { // < My child > < / my child > will only be available in the parent component template 'my-child': Child } })
Data must be a function. The data option of a component must be a function. Therefore, each instance can maintain an independent copy of the returned object:
var counter = { template:`<button @click="num++">{{num}}</button>`, data:function(){return {num:1}} } new Vue({ el:"#app", components:{ counter, } })
Component call
<div id="app"> <counter></counter> <counter></counter> <counter></counter> </div>
Component transfer parameters
When a value is passed to a prop attribute, it becomes an attribute of that component instance.
<child message="hello!"></child> Vue.component('child', { // Declare props props: ['message'], // Like data, prop can also be used in templates // You can also use this.message in the vm instance template: '<span>{{ message }}</span>' })
Dynamic Prop
You also know that prop can be dynamically assigned through v-bind
<div> <input v-model="parentMsg"> <br> <child :my-message="parentMsg"></child> </div>
If you want to pass all the attributes of an object as prop, you can use v-bind without any parameters
todo: { text: 'study Vue', isComplete: false } <todo-item v-bind="todo"></todo-item> = <todo-item v-bind:text="todo.text" v-bind:is-complete="todo.isComplete"></todo-item>
Unidirectional binding
Prop is one-way binding: when the properties of the parent component change, it will be transmitted to the child component, but not vice versa. In addition, every time the parent component is updated, all props of the child component will be updated to the latest value. This means that you should not change the prop inside the subcomponent
In two cases, we can't help but want to modify the data in prop:
- After the Prop is passed in as the initial value, the sub component wants to use it as local data;
- Prop is imported as raw data and processed by sub components into other data output.
1. Define a local variable and initialize it with the value of prop:
props: ['initialCounter'], data: function () { return { counter: this.initialCounter } }
2. Define a calculation attribute, process the value of prop and return:
props: ['size'], computed: { normalizedSize: function () { return this.size.trim().toLowerCase() } }
verification
You can specify validation rules for the prop of a component. Vue issues a warning if the incoming data does not meet the requirements. This is useful for developing components for others to use.
Vue.component('example', { props: { // Basic type detection (` null 'means that any type is allowed) propA: Number, // There may be many types propB: [String, Number], // Required and string propC: { type: String, required: true }, // Value with default value propD: { type: Number, default: 100 },
type can be one of the following native constructors:
- String
- Number
- Boolean
- Array
- Object
- Date
- Function
- Symbol
How do child components communicate with parent components
We know that the parent component uses prop to pass data to the child component. But how do child components communicate with parent components? At this time, Vue's custom event system comes in handy.
Each Vue instance implements an event interface, namely:
Listen for events with $on(eventName)
Use $emit(eventName) to trigger the event
Parent components can directly use v-on to listen for events triggered by child components where child components are used.
<div id="app"> <p>{{ total }}</p> <counter v-on:add="addTotal"></counter> <counter v-on:add="iaddTotal"></counter> </div>
Vue.component('counter', { template: '<button v-on:click="addCounter">{{ counter }}</button>', data: function () { return { counter: 0 } }, methods: { addCounter: function () { this.counter += 1 this.$emit('add') } }, }) new Vue({ el: '#counter-event-example', data: { total: 0 }, methods: { addTotal: function () { this.total += 1 } } })
Slot slot
When using components, we often combine them like this:
<app> <app-header></app-header> <app-footer></app-footer> </app>
Single slot
It is assumed that the my component component has the following templates:
<div> <h2>I am the title of the subcomponent</h2> <slot> Displayed only if there is no content to distribute. </slot> </div>
Parent component template
<div> <h1>I am the title of the parent component</h1> <my-component> <p>This is some initial content</p> <p>This is more initial content</p> </my-component> </div>
result
<div> <h1>I am the title of the parent component</h1> <div> <h2>I am the title of the subcomponent</h2> <p>This is some initial content</p> <p>This is more initial content</p> </div> </div>
Named slot
Sometimes we need multiple slots. For example, suppose we have an app layout component:
<div class="container"> <header> <slot name="header"></slot> </header> <main> <slot></slot> </main> <footer> <slot name="footer"></slot> </footer> </div>
The slot element has a special feature: name. This feature can be used to define additional slots:
Parent component template
<app-layout> <h1 slot="header">Here may be a page title</h1> <p>A paragraph of the main content.</p> <p>Another main paragraph.</p> <p slot="footer">Here are some contact information</p> </app-layout>
The result is:
<div class="container"> <header> <h1>Here may be a page title</h1> </header> <main> <p>A paragraph of the main content.</p> <p>Another main paragraph.</p> </main> <footer> <p>Here are some contact information</p> </footer> </div>
A without name The exit will have the implied name "default".
"After talking about the components, how does the fashion feel?" said the old man.
"Ah? What happened?" the fashion was confused