Vue components_ Creation method_ data and methods_ Component switching_ Transfer between parent and child components_ data and props

Keywords: Javascript Front-end Vue.js

Create global component

Vue components are also Vue instances. Method 1: com1

Mode 1: component

Combine extend in Vue when creating components

const com1 = Vue.extend({
	template:"<h1>This is the first global component created</h1>"
    //Represents the UI code deconstruction of this component
})

Note: the template cannot put a single text, but must be wrapped with a label
Can contain only one root element

Register a component with the global

// Vue.component("name of component", constructor of component) {}
//The component name can contain uppercase, such as myCom1, but the reference needs my-com1
Vue.component("mycom1",com1)

Reference in page

<div id="app">
	<!-- Put the name of the component on the page in the form of a label -->
    <mycom1></mycom1>
</div>

Method 2: when registering a component, the second parameter receives an object (you do not need to use extend)

Vue.component("mycom2",{
	template:"<h2>This is direct use Vue.component Created components </h2>"
})

Method 3: set id

<template id="tmpl">
        <h3>This is an externally defined component UI deconstruction</h3>
</template>
Vue.component("mycom3",{
	template:"#tmpl"
})

Note: write the mount element first

Redefine the template tag

Create private component

Create a component in the create instance (it can only be used within the app)

var vm = new Vue({
	el:"#app",
	data:{},
	methods:{},
	components:{
        "mycom4":{
            template:"<h6>This is a defined private component</h6>"
        }
    }
})

data and methods in component

<div id="app">
    <counter></counter>
    <hr>
    <counter></counter>
</div>
const o = {count:0}

Vue.component("counter",{
	template:`<div>
              	<input type='button' value='+1' @click="add" />
                <h3>Current count The value is:{{count}}</h3>
              </div>`,
//You can have your own private data in the component, but the data must be a function and return a data object internally
	data:function(){
		
        //Using the following method, when < counter > is referenced twice in the page, data linkage occurs and the same data is manipulated
        //return o
        
        //The official recommended method returns a new object every time it is referenced.
        return {
			count:0
		}
	},
	methods:{
		add(){
			this.count++
		}
	}
})

Note: define the data in the component as a function. Whenever a component is referenced, the data function must be called first to obtain a private data object of the current component.

Switching of components

1) Two components

1. Create two components login and reg

Vue.component("login",{
	template:"<div>Login component</div>"
})
Vue.component("reg",{
	template:"<div>Register components</div>"
})

2.flag is true - login false - register

<div id="app">  
    <input type="button" value="Sign in" @click="flag=true">
    <input type="button" value="register" @click="flag=false">
    <login v-if="flag"></login>
    <reg v-else="flag"></reg>
</div>

2) Multiple components use < component: is = "" >

Create four components and define comname

Vue.component("com1",{
	template:"<h3>111111</h3>"
})

Vue.component("com2",{
	template:"<h3>22222</h3>"
})

Vue.component("com3",{
    template:"<h3>333333</h3>"
})

Vue.component("com4",{
	template:"<h3>444444</h3>"
})

var vm = new Vue({
	el:"#app",
	data:{
		comname:"com1"
 	},
	methods:{},
})

Use: is

<div id="app">
    <a href="#"@ Click =" comname ='com1 '"> display component 1</a>
    <a href="#"@ Click =" comname ='com2 '"> display component 2</a>
    <a href="#"@ Click =" comname ='com3 '"> display component 3</a>
    <a href="#"@ Click =" comname ='com4 '"> display component 4</a>
    
    <transition>
		<component :is="comname"></component>
    </transition>
    <!-- The received here is a string -->
</div>

Add animation effects

<style>
	.v-enter{
	/*About to enter*/
		opacity: 0;
		transform: translateX(100px);
	}
	.v-leave-to{
	/*Leave final arrival position*/
		opacity: 0;
		transform: translateX(-100px);
	}
	.v-enter-active,.v-leave-active{
		transition: all 0.4s ease;
		position: absolute;
    }
</style>

Pass from parent component to child component

1. Parent component transfers value to child component

In Vue, the default child component cannot get the data in the parent component

1) Bind the data to be passed to the sub component as user-defined data to the sub component through v-bind

<com1 :msg="parentMsg"></com1>

2) You cannot directly use the data passed by the parent component in the child component. You need to use props array to receive it first

props:["msg"]

Note: when using props to receive, the received name must be consistent with the user-defined attribute name passed by the parent component

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="https://cdn.jsdelivr.net/npm/vue@2.6.12"></script>
</head>
<body>
    <div id="app">
        <com1 :msg="parentMsg"></com1>
    </div>

    <script>
        var vm = new Vue({	//The instance is the parent component
            el:"#app",
            data:{
                parentMsg:"Ha ha ha ha"
            },
            methods:{},
            components:{    //Private component (sub component)
                "com1":{
                    template:`<div>
                        <h3>This is the title in the subcomponent{{msg}}</h3>
                        </div>`,
                        props:["msg"]
                }
            }
        })
    </script>
</body>
</html>

2. Transfer objects from parent component to child component

Similar to above

template:"<h3>Ha ha ha{{JSON.stringify(msgobj)}}</h3>"

3. Transfer method from parent component to child component

Use this.$refs to get elements and components

Transfer the data in data, using the form of attribute binding v-bind

Pass the methods in methods in the form of event binding v-on

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="https://cdn.jsdelivr.net/npm/vue@2.6.12"></script>
</head>
<body>
    <div id="app">
        <com1 @func="show"></com1>
    </div>

    <script>
        var vm = new Vue({
            el:"#app",
            data:{},
            methods:{
                show(){
                    console.log("Someone called the method of the parent component")
                }
            },
            components:{
                "com1":{
                    template:"<input type='button' @click='btnClick'/>",
                    methods:{
                        btnClick(){
                            //Call the func method passed from the parent component
                            this.$emit("func")
                        }
                    }
                }
            }
        })
    </script>
</body>
</html>

4. Transfer data from child component to parent component

In essence, the method passed by the parent component is called, but the child component takes the data as a parameter and passes it to the parent component method

var vm = new Vue({
	el:"#app",
	data:{},
	methods:{
		show(args){
			console.log("Someone called the method of the parent component"+args)
		}
	},
	components:{
		"com1":{
			template:"<input type='button' @click='btnClick'/>",
            data(){
                return{
                    sonMsg:"This is the data of the subcomponent"
                }
            },
			methods:{
				btnClick(){
				//Call the func method passed from the parent component
					this.$emit("func",this.sonMsg)
				}
			}
		}
	}
})

this.$refs get element content

<body>
    <div id="app">
        <h3 ref="myh3">{{ msg }}</h3>
        <input type="button" value="Get element content" @click="getInfo">
    </div>

    <script>
        var vm = new Vue({
            el:"#app",
            data:{
                msg:"000"
            },
            methods:{
                getInfo(){
                    console.log(this.$refs.myh3.innerHTML)
                }
            }
        })
    </script>
</body>

Modify the data on the subcomponent and call the methods of the subcomponent

<body>
    <div id="app">
        <input type="button" value="Get components on page" @click="getCom">
        <mycom ref="mycom"></mycom>
    </div>

    <script>

        Vue.component("mycom",{
            template:"<h3>This is a component {{msg}}</h3>",
            data:function(){
                return {
                    msg:"ok"
                }
            },
            methods:{
                show(){
                console.log("Method of calling subcomponent")
                }
            }
            
        })

        var vm = new Vue({
            el:"#app",
            data:{},
            methods:{
                getCom(){
                    // this.$refs.mycom.msg="123"
                    this.$refs.mycom.show();
                }
            }
        })
    </script>
</body>

The difference between data and props in Vue components

1. In the component, data is defined as function and returns an object

2.props is defined as an array in the component, where the values of the array are string names, representing the data passed by the parent component

3.props data cannot be modified directly. If you want to modify it, you must redefine an attribute on the data, and then define the value of the attribute as this.props

4.data is the private data of the component itself, and the data on data is readable and writable

5.props is the data from the outside. The data in props can only be read and cannot be rewritten

Comment list case

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="https://cdn.jsdelivr.net/npm/vue@2.6.12"></script>
</head>
<body>
    <div id="app">

        <cmt-box @func="addNewCmt"></cmt-box>

        <ul>
            <cmt-item v-for="(item,i) in list" :item="item" :key="i" ></cmt-item>
        </ul>
    </div>

    <script>

        Vue.component("cmt-item",{
            template:`<li>
            <h3>Commented by:{{ item.name }}</h3>
            <h5>Comments:{{ item.content }}</h5>
            </li>`,
            props:["item"]
        })

        Vue.component("cmt-box",{
            template:`<div>
            <label>Commented by:</label><br>
            <input type="text" v-model="name"><br>
            <label>Comments:</label><br>
            <textarea v-model="content"></textarea><br>
            <input type="button" value="Comment" @click="postComment">
            </div>
            `,
            data:function(){
                return {
                    name:"",
                    content:"",
                }
            },
            methods:{
                postComment(){
                    const cmt = {name:this.name,content:this.content };

                    //The way that the parent component is passed in the child component can be used to pass the data of the sub component as a parameter to the parent component.
                    this.$emit('func',cmt)

                    this.name=this.content=""
                }
            }
        })


        var vm = new Vue({
            el:"#app",
            data:{
                list:[
                    {name:"zs",content:"sofa"},
                    {name:"ls",content:"Bench"},
                    {name:"qqq",content:"summer sleeping mat"},
                    {name:"eee",content:"brick"}
                ]
            },
            methods:{
                addNewCmt(cmt){//Add a new comment
                    this.list.push(cmt)
                }
            },
        })
    </script>
</body>
</html>

Posted by jayrulez on Sun, 07 Nov 2021 19:15:41 -0800