Writing in the front

Recently, I was a little confused when WATCHING the video of Silicon Valley. I directly skipped the components and started to build the project with CLI. I found the vUE teaching video of Teacher Coderwhy and learned the components well.

Steps for creating and using components

  1. Create the component constructor object vue.extend ()
  2. Certified components
  3. Using the component

Create a component constructor in js and register the component (note that the template string is a template string, and the template content must have at least one enclosing element) :

    // Create the component constructor object vue.extend ()
    const cpnC = Vue.extend({
        template: '
      

I am title

I am content

'
}) Vue.component (global registration) Vue.component('my-cpn', cpnC) new Vue({ el: '#app',})Copy the code

This component can then be used in HTML, so it should be a syntactic sugar for HTML, increasing the reuse rate and reducing the work of CV developers.

<body>
    <div id="app">
        <my-cpn></my-cpn>
    </div>
</body>
Copy the code

Global components and local components

As you can see from the previous example, components are registered using Vue’s function object methods so that the registered component is a global component that can be resolved in any Vue instance. The other registration method is local registration, which can only be used in the parse element of the specified Vue instance:

    const cpnC = Vue.extend({
        template: '
      

I am title

I am content

'
new Vue({ el: '#demo'.components: { cpn: cpnC, } Copy the code

Father and son components

Components can also be registered inside a component, so that the template inside the parent component can use the child component already registered. True Oyi Dolls:

        1 / / component
        const cpnC1 = Vue.extend({
            template: '
      

Component 1

The contents of component 1

'
}) // Component 2 registered with component 1 const cpnC2 = Vue.extend({ template: ` < div > < h2 > component 2 < / h2 > < p > the content of the component 2 < / p > < cpnc1 > < / cpnc1 > < / div > `.components: { cpnc1: cpnC1, } }) //el is a Vue instance of #app, registering component 2 new Vue({ el: '#app'.components: { cpnc2: cpnC2, } }) Copy the code

Use components 2 and 1 in div#app (note that HTML tags do not support camel nomenclature, uppercase letters are recognized as lowercase letters) :

    <div id="app">
        <cpnc2></cpnc2>
        <cpnc1></cpnc1>
    </div>
Copy the code

In this case, component 1 cannot be resolved because it is not registered in the Vue instance or globally. In fact, this Vue instance can also be thought of as a root component, which is the starting point for endless dolls.

Register component syntax sugar

The previous steps to register components are a bit cumbersome, and are now rarely seen in this way.

    Vue.component (global registration)
    Vue.component('my-cpn', {
        template: '
      

I am title

I am content

'
}) Copy the code

The syntactic sugar notation skips the component constructor creation step and goes straight to a two-in-one, but the underlying functionality is still implemented by calling vue.extend ().

Component templates are removed

The syntactic sugar notation for registering components is really easy to write, but cramming all the HTML content into one place can seem confusing, especially if parent-child components are nested. We can use the template tag in HTML to write the contents of our component template with the id:

    <template id="cpn">
        <div>
            <h2>I am heading</h2>
            <p>I am content</p>
        </div>
    </template>
Copy the code
    // Global registration
    Vue.component('cpn', {
        template: '#cpn'
    })
    // Local registration
    new Vue({
        el: '#demo'.components: {
            cpn: {
                template: '#cpn'}}})Copy the code

Component’s data function

These HTML elements can be reused, but they are static and do not conform to the responsive characteristics of Vue. Can we set reactive data in the component? Yes! We can configure the data function in the component (note! Unlike the configuration in the instance, not an object. , the return value of this function is an object, and methods, etc. The following component registers an add-subtracter and uses it in HTML:

    new Vue({
        el: '#demo'.components: {
            cpn: {
                template: '#cpn'.data() {
                    return {
                        counter: 0}},methods: {
                    inc() {
                        this.counter++
                    },
                    dec() {
                        this.counter--
                    }
                }
            }

        }
    })
Copy the code
    <template id="cpn">
        <div>
            <h2>Current count: {{counter}}</h2>
            <button @click='inc'>+</button>
            <button @click='dec'>-</button>
        </div>
    </template>
    <div id="demo">
        <cpn></cpn>
    </div>
Copy the code

How about setting the data property as a function for magic? Let’s look at a scenario like this: we need to reuse the addition and subtracter. Will the counter property in multiple add-subtracters share values? Let’s try:

Each add-subtracter component’s counter value is independent! This is because the data function is called each time the component is used, and the new objects returned by each call are stored in a different memory space without affecting each other.

Parent-child component communication

  1. The parent component passes information to the child component via props
  2. Child components pass information to parent components through custom events
  3. The parent accesses the child: ChildrenorChildren or Childrenorrefs
  4. The child component accesses the parent component: parentandParent and parentAndRoot

The father the son

The element in the props is a string of the names of the properties of the variables being passed in the sub-component. The sub-component is passed the variables using the V-bind binding. Then the sub-component can manipulate the variables using the syntax of vUE:

<body>
    <template id="cpn1">
        <div>
            <h2>{{cmsg}}</h2>
            <h2 v-for="(item,index) in cmovies" :key='item'>{{item}}</h2>
        </div>
    </template>

    <div id="demo">
        <cpn1 :cmsg='message' :cmovies='movies'></cpn1>
    </div>
</body>
<script>

    const cpn1 = {
        template: '#cpn1'.props: ['cmsg'.'cmovies']}// Register component Vue.component
    new Vue({
        el: '#demo'.data: {
            message: 'hello'.movies: ['Batman'.'Superman'.'Wonderwoman']},components: {
            cpn1
        }
    })
</script>
Copy the code

Props can also be configured as objects. We can list props as objects with properties whose names and values are the names and types of the props. We can also provide default values and required properties for these props:

props: {
  title: String.likes: Number.isPublished: Boolean.commentIds: Array.author: Object.callback: Function.contactsPromise: Promise // or any other constructor
  // Prop with default values
  movies: {type:String.default:'Hello'.required:true // When passing props, the prop must be passed
  }
  msgs: {type:Array.default(){
          return[]},// When the type is array or object, the default attribute must be a function with a return value
      required:true // When passing props, the prop must be passed}}Copy the code

Child the parent

Custom events are required when a child component passes data to its parent. The steps for using custom events can be summarized as follows:

  1. $emit(‘myevent’,[**args])
  2. When the parent component receives a custom event (remember not to name it hump), it invokes the corresponding event callback function
  3. The callback function can optionally receive data from the child component and process it

Here’s an example:

<body>
    <! -- Subcomponent template -->
    <template id="cpn1">
        <div>
            <button v-for="(item,index) in categories" @click='btnClick(item)'>{{item.name}}</button>
        </div>
    </template>
    <! Parent component template -->
    <div id="demo">
        <cpn1 @my-click='cpnClick'></cpn1>
    </div>
</body>
<script>
    / / child component
    const cpn1 = {
        template: '#cpn1'.data() {
            return {
                categories: [{id: 1.name: 'Mobile Appliances' },
                    { id: 2.name: 'Utility' },
                    { id: 3.name: 'Family planning' },
                    { id: 4.name: 'Sports protection'}}},],methods: {
            btnClick(item) {
                this.$emit('my-click', item)
            }
        }
    }
    / / the parent component
    new Vue({
        el: '#demo'.components: {
            cpn1
        },
        methods: {
            cpnClick(item) {
                alert(item.name)
            }
        }
    })
</script>
Copy the code

Father to son

Simple case:

<body>
    <template id="cpn">
        <div></div>
    </template>
    <div id="demo">
        <cpn></cpn>
        <cpn ref="cpn2"></cpn>
        <button @click='btnClick1'>Parent component button - Controls component 1</button>
        <button @click='btnClick2'>Parent component button - Controls component 2</button>

    </div>
</body>
<script>
    // Register component Vue.component
    const cpnC = {
        template: '#cpn'.methods: {
            showMessage() {
                alert('Child component display function! ')}}}new Vue({
        el: '#demo'.components: {
            cpn: cpnC,
        },
        methods: {
            btnClick1() {
                this.$children[0].showMessage()
            },
            btnClick2() {
                this.$refs.cpn2.showMessage()
            }
        }
    })
</script>
Copy the code

Son to father

Parent can access the parent object with this.parent. Parent can access the parent object with this.parent. However, this feature is not recommended in practical development, because the reusability of a child component becomes worse if it relies on a parent component.

Slot

What is a slot? Slots expand device functions, such as USB slots and network cable slots for laptops. Vue slots are also used to enhance the scalability of components, using slots to extract commonalities and reserve differences (set slots).

Basic use of slots

Also a small case:

<body>
    <template id="cpn">
        <div>
            <h2>I am heading</h2>
            <p>I am content</p>
            <slot>
                <p>I'm the slot default</p>
            </slot>
        </div>
    </template>

    <div id="demo">
        <cpn></cpn>
        <cpn>
            <button>Button ao</button>
        </cpn>
        <cpn>
            <button>Button ao</button>
            <button>Button ao</button>
            <input type="text" placeholder="Textbox">
        </cpn>
    </div>
    <script>
        // Create the component constructor object vue.extend ()
        const cpnC = Vue.extend({
            template: '#cpn'
        })
        // Register component Vue.component

        new Vue({
            el: '#demo'.components: {
                cpn: cpnC,
            }
        })
    </script>
</body>
Copy the code

A named slot

As you can see, a slot can be inserted into any element, and the slot can be given a default value. When a component has multiple slots, if we still write as above, all slots will be replaced with the same content, so we need to name the slots (named slots) :

        <template id="cpn1">
            <div>
                <slot name="l">
                    </name=>>
                    <span>On the left</span>
                </slot>
                <slot name='m'>
                    <span>In the</span>
                </slot>
                <slot name='r'>
                    <span>right</span>
                </slot>
            </div>
        </template>
    
        <cpn1>
            <span slot="l">Changed to the left</span>
            <span slot="m">Change the middle</span>
            <span slot="r">To the right</span>
        </cpn1>
Copy the code

Compile scope

Is similar to the scope, js in HTML using the vue data, we can also through the scope to determine the scope of the vue data, assuming that a father and son components, is set in the father and son component attributes isShow, one is true, one is false, then the following case, the child components will not be displayed:

    <! -- Parent component -->
    <div id="demo">
    <! Parent component scope -->
        <cpn v-show='isShow'><! -- Subcomponent scope --></cpn>
    </div>
Copy the code

Here, because vshow is scoped by the parent component, isShow is true.

Scope slot

The parent component replaces the label of the slot, and the label content is provided by the child component. V-slot is the new syntax, the old syntax (slot-scope) was discarded after Vue3.0. V-slot is recommended to be written under the template tag

<! -- Default slot -->
<foo v-slot="{ msg }">
  {{ msg }}
</foo>

<! -- named slot -->
<foo>
  <template v-slot:one="{ msg }">
    {{ msg }}
  </template>
</foo>

Copy the code

Dynamic components

This part of the content in the nuggets have some tutorials, which this article in-depth analysis of the principle of dynamic components, but now the level is not enough, not able to understand, first, in the future to see in-depth analysis of Vue source code