Vue advanced component development

I Introduction to the idea of componentization

The essence of component-based development is to develop modules with the same function into reusable small components, and then realize the development of a complete page by introducing various components. Component-based development is like a tree structure, and each component is a branch node on the tree structure

1.1 Vue instance creation component

There are several ways to create a component constructor in Vue, but the general idea includes three steps, as follows:
1. Create a component constructor
2. Register components
3. Use components in Vue instance objects

The first method of creating and using components is based on the extend method:

<!DOCTYPE html>
<html lang="zh">
    <head>
        <meta charset="UTF-8">
        <meta name="viewpot" content="width=device-width, initial-scale=1.0">
        <meta http-equiv="X-UA-Compatible" content="ie=edge">
        <title>vuezujianhua</title>
        <script src='./vue.js'></script>
        <style>

        </style>
    </head>
    <body>
        <div id="shop" v-cloak>
            <!-- vue Use global components in instance objects -->
            <my_content></my_content>
        </div>

        <template id="content">
            <div>
                {{childMovies}}
            </div>
        </template>
        <script>
            // 1. Create a component constructor
            const content = Vue.extend({
                template:`
                    <div>
                        <h2>This is a title</h2>
                        <p>This is a paragraph</p>    
                    </div>
                `,
            })
            // 2. Register components
            Vue.component('my_content', content)
            var vm = new Vue({
                el:'#shop',
                data:{
                    movies: ['dominant sea power', 'One Piece'],
                },
                methods:{

                },

            })
        </script>
    </body>
</html>

Note: the component constructor is created first by calling the extend method in Vue. This implementation method is relatively low-level

Implementation mode 2: directly through Vue Component () syntax is implemented in sugar mode

Vue.component('my_content', {
                template:`
                    <div>
                        <h2>This is a title</h2>
                        <p>This is a paragraph</p>    
                    </div>
                `,
            })

The syntax sugar implementation directly puts the content of the implementation template in extend into the component. In fact, the underlying implementation of the syntax sugar also calls extend, but this implementation is more concise

1.2 global and local components

Global components: the creation and registration of global components are implemented in the same hierarchy as vue instances
For example:
Global components

<script>
            // Create a component constructor and register components, which is a global component, because component creation and registration are at the same level as new Vue instantiation
            Vue.component('my_content', {
                template:`
                    <div>
                        <h2>This is a title 1</h2>
                        <p>This is a paragraph</p>    
                    </div>
                `,
            })
            var vm = new Vue({
                el:'#shop',
                data:{
                    movies: ['dominant sea power', 'One Piece'],
                },
                methods:{

                },

            })
        </script>

Above Vue Component () creates and registers components through Vue objects, which are instantiated at the same level as Vue objects

Local component

<script>
            // Creating a component constructor and registering a component is a local component, because the component creation and registration are placed in the vue instance object
            var cpm = {
                template:`
                    <div>
                        <h2>This is a title 111</h2>
                        <p>This is a paragraph</p>    
                    </div>
                `,
            }
            var vm = new Vue({
                el:'#shop',
                data:{
                    movies: ['dominant sea power', 'One Piece'],
                },
                methods:{

                },
                components:{
                    'my_content': cpm
                }
            })
        </script>

Local component: because the component creation and registration are placed in the vue instance object, the registration is created through components

1.3 parent child components

The child component is registered and created in the parent component, and the reference is also in the parent component, for example:
Parent child component

<!DOCTYPE html>
<html lang="zh">
    <head>
        <meta charset="UTF-8">
        <meta name="viewpot" content="width=device-width, initial-scale=1.0">
        <meta http-equiv="X-UA-Compatible" content="ie=edge">
        <title>vuezujianhua</title>
        <script src='./vue.js'></script>
        <style>

        </style>
    </head>
    <body>
        <div id="shop" v-cloak>
            <!-- vue Use global components in instance objects -->
            <component1></component1>
            <!-- <component2></component2> A component created in a child component can only be used in the parent component and cannot skip a level -->
        </div>

        <template id="content">
            <div>
                {{childMovies}}
            </div>
        </template>
        <script>
            // Creating a component constructor and registering a component is a local component, because the component creation and registration are placed in the vue instance object

            Vue.component('component1', {
                template:`
                    <div>
                        <h2>This is a title 111</h2>
                        <p>This is a paragraph</p>
                        <component2></component2>  
                    </div>
                `,
                components:{
                    'component2':{
                        template:`
                            <div>
                                <h2>This is a title 222</h2>
                                <p>This is a paragraph 222</p>    
                            </div>
                        `,
                    }
                }
            })

            var vm = new Vue({
                el:'#shop',
                data:{
                    movies: ['dominant sea power', 'One Piece'],
                },
                methods:{

                },
            })
        </script>
    </body>
</html>

The implementation of the child component of component2 is implemented in its parent component component1, and it is used in the template of component1, but cannot be used in vue instances (in fact, new Vue instantiation can be regarded as a root component, and the idea of componentization is also based on vue instantiation)

1.4 template extraction

Above, we put the contents of the html template into the component, and then render the template through the template. In this way, many html templates will be stored in our component, so the code will be very bulky, so we need to decouple and separate the template

<!DOCTYPE html>
<html lang="zh">
    <head>
        <meta charset="UTF-8">
        <meta name="viewpot" content="width=device-width, initial-scale=1.0">
        <meta http-equiv="X-UA-Compatible" content="ie=edge">
        <title>vuezujianhua</title>
        <script src='./vue.js'></script>
        <style>

        </style>
    </head>
    <body>
        <div id="shop" v-cloak>
            <!-- vue Use global components in instance objects -->
            <component1></component1>
            <!-- <component2></component2> A component created in a child component can only be used in the parent component and cannot skip a level -->
        </div>

        <template id="content">
            <div>
                <div>
                    <h2>This is a title 111</h2>
                    <p>This is a paragraph</p>
                </div>
            </div>
        </template>
        <script>
            // Creating a component constructor and registering a component is a local component, because the component creation and registration are placed in the vue instance object

            Vue.component('component1', {
                template:'#content',
            })

            var vm = new Vue({
                el:'#shop',
                data:{
                    movies: ['dominant sea power', 'One Piece'],
                },
                methods:{

                },
            })
        </script>
    </body>
</html>

Note: we add the template tag under the template of vue instance object, and then set the unique name of the template through id, which is in vue When creating and registering components, component () directly locates the template through the id selector and then introduces and renders it, so that a large amount of html content will not be stored in vue components, and the code decoupling is good

Template separation in parent-child components

<!DOCTYPE html>
<html lang="zh">
    <head>
        <meta charset="UTF-8">
        <meta name="viewpot" content="width=device-width, initial-scale=1.0">
        <meta http-equiv="X-UA-Compatible" content="ie=edge">
        <title>vuezujianhua</title>
        <script src='./vue.js'></script>
        <style>

        </style>
    </head>
    <body>
        <div id="shop" v-cloak>
            <!-- vue Use global components in instance objects -->
            <component1></component1>
            <!-- <component2></component2> A component created in a child component can only be used in the parent component and cannot skip a level -->
        </div>

        <template id="content1">
            <div>
                <div>
                    <h2>This is a title 111</h2>
                    <p>This is a paragraph</p>
                    <component2></component2>
                </div>
            </div>
        </template>


        <template id="content2">
            <div>
                <div>
                    <h2>This is a title 222</h2>
                    <p>This is a paragraph 222</p>
                </div>
            </div>
        </template>
        <script>
            // Creating a component constructor and registering a component is a local component, because the component creation and registration are placed in the vue instance object

            Vue.component('component1', {
                template:'#content1',
                components: {
                    'component2': {template: '#content2'}
                }
            })

            var vm = new Vue({
                el:'#shop',
                data:{
                    movies: ['dominant sea power', 'One Piece'],
                },
                methods:{

                },
            })
        </script>
    </body>
</html>

Extract the templates of the child components component2 in the parent component component1 and reference them through the template. However, it should be noted that the use of component2 components can only be used in component1, that is, the child components can only be used in the parent component

1.5 data storage in sub assembly

vue subcomponents cannot directly access the data in the instance and need to be accessed through binding. The data in the subcomponent is stored in data, which is very similar to the structure of vue instance. However, data in the subcomponent is a function that can return objects. The function has its own function, which can play an independent data scope and will not cause confusion of data reference
When a function is called, there will be a stack space in memory to store the function object, set variables, and allocate memory space for storage, so the created variables have independent scopes

<div id="shop" v-cloak>
             <component1></component11>
        </div>
        
        <template id="content">
            <div>
                <h2>{{ title }}</h2>
                <p>I am the content,Hahaha 222</p>
                <p>I am the content,Hehe 2222</p>
            </div>
        </template>
        <script>

            Vue.component('component1',{
                template: '#content',
                data(){
                    return {'title': 'I'm Title 22222'}
                },
                methods:{

                }
            })

            var vm = new Vue({
                el:'#shop',
                data:{
                    msg: "kdf",
                },
                methods:{

                },
            })
        </script>

We can see that when the template of the subcomponent (the vue instance can be regarded as the root component of the group) is used to the title variable, the data is assigned through the interpolation expression, and the title is stored in the data function and an object containing the title attribute is returned

II Parent child component communication

There are two situations for parent-child component communication
1. The parent component passes data to the child component through props
2. The child component passes data to the parent component through the event of $emit to customize the event

2.1 the parent component transmits data to the child component through props

Bind the data in the parent component to the child component through v-bind

<!DOCTYPE html>
<html lang="zh">
    <head>
        <meta charset="UTF-8">
        <meta name="viewpot" content="width=device-width, initial-scale=1.0">
        <meta http-equiv="X-UA-Compatible" content="ie=edge">
        <title>vuezujianhua</title>
        <script src='./vue.js'></script>
        <style>

        </style>
    </head>
    <body>
        <div id="shop" v-cloak>
            <!-- vue Use global components in instance objects -->
            <component1></component1>
            <!-- <component2></component2> A component created in a child component can only be used in the parent component and cannot skip a level -->
        </div>

        <template id="content1">
            <div>
                <div>
                    <h2>{{ title + 'In parent component'}}</h2>
                    <p>This is a paragraph</p>
                    <component2 :mytitle='title'></component2>
                </div>
            </div>
        </template>


        <template id="content2">
                <div>
                    <h2>{{ mytitle + 'In subcomponents' }}</h2>
                    <p>This is a paragraph 222</p>
                </div>
        </template>
        <script>
            // Creating a component constructor and registering a component is a local component, because the component creation and registration are placed in the vue instance object

            Vue.component('component1', {
                template:'#content1',
                components: {
                    'component2': {
                        template: '#content2',
                        props:{
                        mytitle:{
                            type: String,
                            default(){
                                return "There are no passes in the parent component title"
                            },
                            required: false
                    }
                }
                    }
                },
                data(){
                    return {'title': 'Title 222'}
                },
                
            })

            var vm = new Vue({
                el:'#shop',
                data:{
                    movies: ['dominant sea power', 'One Piece'],
                },
                methods:{

                },
            })
        </script>
    </body>
</html>
vuezujianhua

Set the props attribute in the sub component and perform simple verification, then bind the title value passed in the parent component in the component, and then interpolate the reference in the sub component

2.2 the child component passes data to the parent component through the $emit custom event

When transferring data from the child component to the parent component, it is realized through custom events. The custom process of events is as follows:
Trigger the method in the subcomponent methods in the subcomponent, and then use this in the methods$ Emit ('eventname ', para) emits the event to the parent component, then uses v-on in the template of the parent component to listen for the event passed by the child component, and then touches the methods in the parent component to make the corresponding request

<!DOCTYPE html>
<html lang="zh">
    <head>
        <meta charset="UTF-8">
        <meta name="viewpot" content="width=device-width, initial-scale=1.0">
        <meta http-equiv="X-UA-Compatible" content="ie=edge">
        <title>vuezujianhua</title>
        <script src='./vue.js'></script>
        <style>
            ul>li {
                list-style: none;
            }
        </style>
    </head>
    <body>
        <!-- Parent component template -->
        <div id="shop" v-cloak>
             <son_component @childbtn='fatherbtn'>
             </son_component>
        </div>

        <!-- Subcomponent template -->
        <template id="content">
            <div>
                <ul v-for="item in goodList">
                    <li><a href="#" @click='childclick(item)'>{{item.name}}</a></li>
                </ul>
            </div>
        </template>
        <script>

            const son_component = {
                template: '#content',
                data: function(){
                    goodLists = [
                        {id: '1', name:'Popular recommendation'},
                        {id: '2', name:'Mobile digital'},
                        {id: '3', name:'Household appliances'},
                        {id: '4', name:'Computer office'},
                ]
                    return {'goodList': goodLists}

                },
                methods:{
                    childclick(item){
                        this.$emit('childbtn', item); //Emit events and pass parameters to the parent component
                    }
                },
            }

            var vm = new Vue({
                el:'#shop',
                data:{
                    movies: ['dominant sea power', 'One Piece'],
                },
                methods:{
                    fatherbtn(item){
                        console.log("father", item)
                    }
                },
                components:{
                    son_component
                }

            })
        </script>
    </body>
</html>

Note: subcomponents use the custom event this$ Emit ('eventname ', para) emits events to the parent component

Keywords: Vue

Added by porrascarlos80 on Fri, 04 Mar 2022 08:46:31 +0200