"Fashion learning Vue by rocket" -- Chapter 13: components in Vue (difficulties)

Posted by lazersam on Fri, 26 Nov 2021 21:42:40 +0100

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:

  1. After the Prop is passed in as the initial value, the sub component wants to use it as local data;
  2. 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

Topics: Javascript Front-end JQuery Vue Vue.js