vuejs component development

vuejs componentization

What is component development?

Component development is a popular development mode in recent two years. It encapsulates some common code blocks in daily project development into one function block. This function block contains structure, style, behavior, data (state), life cycle, etc. Then, during project development, the pages of the project are composed of these small components, similar to Lego building blocks.

Website: (web page - > component - > encapsulated code block)

Common reusable Codes:

  • Button
  • Popup
  • Modal box
  • Badge badge
  • Icon
    ...


Components are actually html tags encapsulated by developers themselves. Because the native html tags are very limited.

Why introduce component development?

It is for the reuse of code and convenient maintenance in the later stage. At the same time, it is also very convenient for the later expansion function, and it is well accepted by others in the later stage.

How does vuejs develop as a component?

Vue.component()

What are the common third-party component libraries of vuejs?

  • ElementUI (pc side project) (hungry front-end team)

    • https://element.eleme.cn/#/zh-CN/component/drawer
  • MintUI (mobile terminal project) (hungry front-end team)

    • http://mint-ui.github.io/docs/#/
  • iview (individual)

    • https://weapp.iviewui.com/components/switch
  • uview (generally used in conjunction with uniapp for applet and other mobile terminals)

    • https://www.uviewui.com/components/button.html
  • Vantui (mobile UI) (praise team)

    • https://vant-contrib.gitee.io/vant/#/zh-CN/goods-action

...

assembly

Basic usage of global components

First learn your own custom components and try them
vuejs components: 1. Global components 2. Local components define components, which must be written before instantiation.
Parameter 1 (string): the name of the component,
1.1 generally, ABC def GHI is used for naming. Each word is in lowercase, and the middle line is used for string.
1.2 at the same time, the way of small hump can also be used, but if it is named in the way of small hump, the baking string method shall be used when calling. Parameter 2(object): description object of the component (1. Structure html code 2. Style Css 3. Behavior js event 4. data 5
Lifecycle function)

Vue.component('mycompoent1', {
        /* tempalate It is necessary. In the process of writing, the template file has only one root node*/
        template: `
          <div>
            <h2>Component HTML structure</h2>
            <h2>Component HTML structure</h2>
          </div>
        `
    });
//The defined component names are referenced between html pages
<mycompoent1></mycompoent1>


Kebab method and naming of small hump

	Vue.component('my-compoent2', {
        template: `
          <div>
            <h2>Component HTML structure</h2>
            <h2>Component HTML structure</h2>
          </div>
        `
    });

    /*Nomenclature of small hump*/
    /* Call: mycomponent3 - > My component3*/
    Vue.component('myCompoent3', {
        template: `
          <div>
            <h2>Component HTML structure</h2>
            <h2>Component HTML structure</h2>
          </div>
        `
    });
	<my-compoent2></my-compoent2>
    <hr>
    <my-compoent3></my-compoent3>


Summary: when the user customizes the component, it is recommended to use the baking string method to name the component name. There is no error in this definition, and there will be no error in calling!

Style and behavior of global components

		Vue.component('mycompoent1', {
        created() {
            console.log('assembly mycomponent1 Produced');
            // Network requests generally occur
            this.getCommentList();
        },
        /*The data belonging to the component itself should be defined by a data function. The return value of the function is an object. The data in the object is generally called model data, and the attributes in model data are called model variables. Model variables can be used in template*/
        data() {
            return {
                title: 'hi component!',
                counter: 0,
                result: [],
                page: 1,
                limit: 5,
            }

        },
        /*Components can also exist in methods, where our event callback function is written*/
        methods: {
            async getCommentList() {
                // Network request from axios
                let url = `http://localhost:3000/api/v1/comment/list?page=${this.page}&limit=${this.limit}`;
                try {
                    // Request complete
                    this.isLoading = false;
                    const res = await axios.get(url); // res.data response body
                    this.result = res.data.data.result;
                    console.log('this.result ', this.result);
                } catch (e) {
                    this.result = [];
                    alert('Failed to get information!');
                    return;
                }
            },
            clickHandler() {
                this.counter++;
                console.log('clickHandler');
            }
        },
        template: `
          <div style="color:red;">
            <h2>My first component</h2>
            <p>Behavior: Events</p>
            <h3>{{ title }}</h3>
            <p>counter: {{ counter }}</p>
            <button @click="clickHandler()">Click me</button>
            <hr>
            <hr>
             <ul v-for="ele in result">
                <li>Serial number:{{ ele._id }}</li>
                <li>user name:{{ele.username}}</li>
                <li>Comment date:{{ele.addTime}}</li>
                <li>Comments:{{ele.content}}</li>
            </ul>
</div>
        `
    });

	<mycompoent1></mycompoent1>
    <mycompoent1></mycompoent1>
    <mycompoent1></mycompoent1>

Components are highly reusable and can be used as many times as you want

Local component

First define

	new Vue({
        el: '#app',
        data: {},
        /*Define the location of local components*/
        components: {
           /*key: Component name: baking string method; value: component description object*/
            'my-component2': myComponent1,
            'my-component1': myComponent2,
        }
    });

If the component description object is extracted, it can not be extracted, but it will be more concise.

const myComponent1 = {
		//Support lifecycle functions
        created() {
            console.log('created');
        },
        data() {
            return {
                counter: 0,
            }
        },
        methods: {
            clickHandler() {
                this.counter++;
                console.log('clickHandler');
            }
        },
        template: `
                    <div style="color: blue;">
                    <h1>I am the second local component!</h1>
                    <p>counter: {{ counter }}</p>
                    <button @click="clickHandler">Click me</button>
                    </div>
                `
    };

    const myComponent2 = {
        created() {
            console.log('created');
        },
        data() {
            return {
                counter: 0,
            }
        },
        methods: {
            clickHandler() {
                this.counter++;
                console.log('clickHandler');
            }
        },
        template: `
                    <div style="color: blue;">
                    <h1>I am the first local component!</h1>
                    <p>counter: {{ counter }}</p>
                    <button @click="clickHandler">Click me</button>
                    </div>
                `
    };

Component call: 1. Double label 2. Single label self closing
Suggestion: double label call; If it's a single pair, one can't get out

    <!--<my-component1/>-->
    <my-component1></my-component1>
    <hr>
    <my-component2></my-component2>

Dynamic component

Officially available:
Component features: the content displayed by the component depends on which component the attribute corresponding to the is attribute of the component is, and the content of which component is displayed

 <component :is="my-component1"></component>
	Vue.component('my-compoent1', {
        template: `
          <div>
            <h2>Component HTML structure</h2>
            <h2>Component HTML structure</h2>
          </div>
        `
    });


You can usually make a tab

<!DOCTYPE html>
<html lang="zh_CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Title</title>
    <style>
        * {
            margin: 0;
            padding: 0;
        }
        .list {
            width: 200px;
            height: 50px;
            display: flex;
        }
        .list li {
            border: 1px solid #000;
            width: 80px;
            height: 50px;
            line-height: 50px;
            text-align: center;
            list-style: none;
            cursor: pointer;
        }
        .list li.active {
            background-color: gold;
        }
    </style>
</head>
<body>
<div id="app">
    <ul class="list">
        <li :class="{'active': currentComponent == 'my-component1'}" @click="selectComponent('my-component1')">It's showing...
        </li>
        <li :class="{'active': currentComponent == 'my-component2'}" @click="selectComponent('my-component2')">Coming soon...
        </li>
    </ul>
    <!--keep-alive It is also officially provided and can be used directly. The function of this component can save the state of the component without re generating and destroying the component-->
    <keep-alive>
        <component :is="currentComponent"></component>
    </keep-alive>
</div>
</body>
<script src="https://cdn.bootcss.com/jquery/2.0.1/jquery.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>

<script>
    Vue.component('my-component1', {
        template: `
            <div>
                <h2>I am the first component!</h2>
                <p>It's showing...</p>
                <hr>
            </div>
        `
    });

    Vue.component('my-component2', {
        template: `
            <div>
                <h2>I'm the second component!</h2>
                <p>Coming soon...</p>
                <hr>
            </div>
        `
    });

    new Vue({
        el: '#app',
        data: {
            currentComponent: 'my-component1',
        },
        methods: {
            selectComponent(item) {
                console.log('item', item);
                this.currentComponent = item;
            }
        }
    });
</script>
</html>


Communication problems between components

(vuejs interview required)

What is the communication problem between components?

Since the page is composed of components, there are relationships between components.

Common relationships are as follows:

  • Nested Models
    • Parent child nesting (parent component, child component)
    • Master Sun nesting
  • Level
    • Sibling component

With this relationship, components need to transfer data. At this time, it is called the communication problem between components.
Common communications:

  • Parent child communication (attribute passing)
  • Child parent communication (callback function)
  • Sibling communication (1. Common parent component 2. EventBus event car)

All of the above communication methods can be solved using a solution called vuex.

Parent child communication (attribute passing)

Vue.component('father-component', {
        template: `
            <div>
            <h2>Parent component</h2>
            <p>Father's money:{{ money }}</p>
            <hr>
            //Use child components directly in parent components
            <son-component></son-component>
			</div>
        `
    });

    Vue.component('son-component', {
        template: `
            <div>
            <h3>Subcomponents</h3>
            <hr>
            </div>
        `
    });
<father-component></father-component>


If the parent component wants to transfer things to the child component, the father defines a data to put things, and the child component defines a prpos to take things

		Vue.component('father-component', {
        data() {
            return {
                money: 1000,
                title: 'I am the content of the parent component!'
            }
        },
        template: `
            <div>
            <h2>Parent component</h2>
            <p>Father's money:{{ money }}</p>
            <hr>
            <son-component :qian="money" :title="title"></son-component>
            </div>
        `
    });

    Vue.component('son-component', {
        props: ['qian', 'title'],
        template: `
            <div>
            <h3>Subcomponents</h3>
            <p>Money from father:{{ qian }}</p>
            <hr>
               <p>{{ title }}</p>
            <hr>
            </div>
        `
    });

Child parent communication (callback function)

1. You need to customize an event in the parent component (the name of the event is user-defined), and then define the callback function of the custom event in methods

<son-component @giveMoney="callback" :qian="money" :title="title"></son-component>

Definition method

		methods: {
            callback(data) {
                console.log('Greetings from my son:', data); // Information passed by data son (son: subcomponent)
            }
        },
  1. Trigger customized events in the parent component in the child component
<button @click="giveMeSameMoney">Dad, give me some living expenses</button>

Definition method

		methods: {
            giveMeSameMoney() {
                console.log('giveMeSameMoney');
                /*The first parameter is the user-defined event defined in the parent component, and the second parameter passes the parameters of the event callback function*/
                /*The second parameter is generally called payload load*/
                this.$emit('giveMoney', {money: 2000}); //  this.$emit is provided by vuejs
            }
        },

3. Father receiving
Method receiving

this.message = data.money;
<p>Greetings from my son:{{ message }}</p>

Entire code

		Vue.component('father-component', {
        data() {
            return {
                money: 1000,
                title: 'I am the content of the parent component!',
                message: '',
            }
        },
        methods: {
            callback(data) {
                console.log('Greetings from my son:', data); // Information passed by data son (son: subcomponent)
                this.message = data.money;
            }
        },
        /* Child parent communication: 1. You need to customize an event in the parent component (the name of the event is user-defined), and then define the callback function of the custom event in methods*/
        template: `
            <div>
            <h2>Parent component</h2>
            <p>Father's money:{{ money }}</p>
            <p>Greetings from my son:{{ message }}</p>
            <hr>
            <son-component @giveMoney="callback" :qian="money" :title="title"></son-component>

</div>
        `
    });

    Vue.component('son-component', {
        props: ['qian', 'title'],
        methods: {
            giveMeSameMoney() {
                console.log('giveMeSameMoney');
                /*The first parameter is the user-defined event defined in the parent component, and the second parameter passes the parameters of the event callback function*/
                /*The second parameter is generally called payload load*/
                this.$emit('giveMoney', {money: 2000}); //  this.$emit is provided by vuejs
            }
        },
        /*Child parent communication: 2. Trigger customized events in the parent component in the child component*/
        template: `
            <div>
            <h3>Subcomponents</h3>
            <p>Money from father:{{ qian }}</p>
            <p>Demand: the son thinks the money given by his father is not enough, so he hopes his father will give more? (callback function implementation?)</p>
            <button @click="giveMeSameMoney">Dad, give me some living expenses</button>
            <hr>
               <p>{{ title }}</p>
            <hr>
            </div>
        `
    });
    new Vue({
        el: '#app',
        data: {}
    });
<div id="app">
    <father-component></father-component>
</div>

Brother communication

Example: Xiong Da wants to send a message to Xiong Er, telling Xiong Er to go to beat bald Qiang at 5:00 this afternoon; Xiong Er replied to Xiong Da that the message has been received and there is no problem.

	<xiong-da-component></xiong-da-component>
    <hr>
    <xiong-er-component></xiong-er-component>
		Vue.component('xiong-da-component', {
        template: `
            <div>
            <h2>Xiong Da-assembly</h2>
            </div>
        `
    });

    Vue.component('xiong-er-component', {template: `
            <div>
            <h3>Xiong Er er-assembly</h3>
            </div>
        `
    });

Public parent component 1. Bear big information to parent component (callback function) 2. Parent component information to bear two (attribute transfer)
Three buses in EventBus computer network 1. Address bus 2. Control bus 3. Address bus 2 ^ 64

  • Event car: 1. Instantiate an event car
 const EventBus = new Vue();
  • Communication: there is an active party (who initiated the information) and a passive Party (the recipient of the information)
  • Event Cart: 2. You need to set listening events in the created lifecycle function of the passive Party (user defined)
  • Event Cart: 3. The business code of the active party needs to trigger the listening event in step 2

At first, Xiong 2 is the passive party. The event car is used in the life cycle function of Xiong 2 component. Set the listening function through. $on (the function is user-defined)

		created() {
            /*Passive Party: onClick*/
           EventBus.$on('waitForMyBigBrotherGiveMeCall', (data) => {
                console.log('Phone call from big brother:', data);
            });
        },

Xiong Da triggers this event as the active party, and creates a button click event in the Xiong Da component

<button @click="callMyLitterBrother">Call Xiong er</button>
		data() {
            return {
                message: 'Let's go and beat bald Qiang at five this afternoon',
            }
        },
		methods: {
            /*Active party: triggers a listening event*/
            callMyLitterBrother() {
                EventBus.$emit('waitForMyBigBrotherGiveMeCall', {message: this.message});
            }
        },

After Xiong Er received the message

		data() {
            return {
                myMessage: '',
            }
        },
        created() {
            /*Passive Party: onClick*/
            EventBus.$on('waitForMyBigBrotherGiveMeCall', (data) => {
                console.log('Phone call from big brother:', data);

                this.myMessage = data.message;

            });

        },
<p>Phone information from big brother:{{ myMessage }}</p>


After receiving the information, Xiong Er should give Xiong Da a message. At this time, Xiong Er is the active party and Xiong Da is the passive party.
At this time, Xiong Da does event monitoring:

		created() {
            /*Passive Party: Xiong Da waits for Xiong Er to deliver information*/
            EventBus.$on('waitForMyLitterBrotherGiveMeCall', (data) => {
                console.log('Greetings from little brother Xiong er', data);
            })

        },

Xiong Erhui message:

<button @click="giveMeMyBigBrotherCall">Call Xiong Da back</button>
		data() {
            return {
                myMessage: '',
                message: 'Message received, no problem!!!',
            }
        },
		methods: {
            giveMeMyBigBrotherCall(){
                /*Xiong Er active party*/
                EventBus.$emit('waitForMyLitterBrotherGiveMeCall', {message: this.message});
            }
        },

Xiong Da took it out after receiving the information:

		data() {
            return {
                message: 'Let's go and beat bald Qiang at five this afternoon',
                myMessage: '',
            }
        },
		created() {
            /*Passive Party: Xiong Da waits for Xiong Er to deliver information*/
            EventBus.$on('waitForMyLitterBrotherGiveMeCall', (data) => {
                console.log('Greetings from little brother Xiong er', data);
                this.myMessage = data.message;
            })

        },
<p>Reply from Xiong Er:{{ myMessage }}</p>

Entire code:

	const EventBus = new Vue();

    Vue.component('xiong-da-component', {

        created() {
            /*Passive Party: Xiong Da waits for Xiong Er to deliver information*/
            EventBus.$on('waitForMyLitterBrotherGiveMeCall', (data) => {
                console.log('Greetings from little brother Xiong er', data);
                this.myMessage = data.message;
            })
        },
        data() {
            return {
                message: 'Let's go and beat bald Qiang at five this afternoon',
                myMessage: '',
            }
        },
        methods: {
            /*Active party: trigger*/
            callMyLitterBrother() {
                EventBus.$emit('waitForMyBigBrotherGiveMeCall', {message: this.message});
            }
        },
        template: `
            <div>
            <h2>Xiong Da-assembly</h2>
            <button @click="callMyLitterBrother">Call Xiong er</button>
            <p>Reply from Xiong Er:{{ myMessage }}</p>
</div>
        `
    });
    Vue.component('xiong-er-component', {
        data() {
            return {
                myMessage: '',
                message: 'Message received, no problem!!!',
            }
        },
        created() {
            /*Passive Party: onClick*/
            EventBus.$on('waitForMyBigBrotherGiveMeCall', (data) => {
                console.log('Phone call from big brother:', data);
                this.myMessage = data.message;
            });
        },
        methods: {
            giveMeMyBigBrotherCall(){
                /*Xiong Er active party*/
                EventBus.$emit('waitForMyLitterBrotherGiveMeCall', {message: this.message});
            }
        },
        template: `
            <div>
            <h3>Xiong Er er-assembly</h3>
            <p>Phone information from big brother:{{ myMessage }}</p>
            <button @click="giveMeMyBigBrotherCall">Call Xiong Da back</button>
</div>
        `
    });
    new Vue({
        el: '#app',
        data: {}
    });
	<xiong-da-component></xiong-da-component>
    <hr>
    <xiong-er-component></xiong-er-component>

Tags: Vue.js

Posted on Wed, 08 Sep 2021 16:03:59 -0400 by BornForCode