Vue components (detailed)

Table of contents

Components:

Global components:

Declare template in HTML page:

Local components:

The first way of local components:

The second way of local components:

Slot slot:

Anonymous slots:

Named slots:

Parent-child component communication:

Simple and rude $refs and $parent:

$refs parent component gets child component data:

 The $parent subcomponent gets the data of the parent component:

Formal father-son communication:

The child component gets the parent component data:

Parent component gets child component data:

Communication of non-parent-child components:

Contamination mixins:

Partially mixed in:

Global mixin:

One last word to everyone:


Official website address: Component Registration - Vue.js (vuejs.org)

Components:

Components can be simply understood as modular units, and Vue components can improve code reusability. Using components can solve the problem of frequently changing requirements

In the future, each component will be a separate file, and the final execution will be placed on a page.

Components have three steps: declaration, registration, and use; except for global components, because global components are already registered when they are declared

Global components:

Refers to components that can be used in different scopes

Code demo:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <div id="app">
        <hello></hello><!--使用-->
    </div>
</body>
<script src="../js/vue2.7.js"></script><!--根据自己的vue文件地址-->
<script>
    //声明加注册
    Vue.component("hello",{
        template:`<div>hello,{
   
   {name}}</div>`,
        data(){//这边也是可以加data以及其他的各种主属性
            return{
                name:"我是hello"
            }
        },
    })
    let app=new Vue({
        el:"#app"
    })
</script>
</html>

Browser result:

Declare template in HTML page:

Of course, the local component can also declare the template on the HTML page, which is the same as the global one.

Code demo:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <div id="app">
        <hello></hello><!--使用-->
    </div>
    <template id="myhello">
        <div>hello,{
   
   {name}}</div>
    </template>
</body>
<script src="../js/vue2.7.js"></script><!--根据自己的vue文件地址-->
<script>
    //声明加注册
    Vue.component("hello",{
        template:"#myhello",//通过id选择器选择上面的id
        data(){
            return{
                name:"我是hello"
            }
        },
    })
    let app=new Vue({
        el:"#app"
    })
</script>
</html>

The effect is the same as the one at the beginning, so I won’t do a demonstration; this method has prompts when writing the HTML page and the js will not be too messy. Both methods are fine, and you can use whichever you like.

Local components:

Refers to a component that can only be used within the scope in which the component is defined

The first way of local components:

This time the method is to declare and register together; this method is not recommended, the reusability is not strong, and there are too many js codes that are inconvenient to view

Code demo:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <div id="app">
        <baibai></baibai><!--使用-->
    </div>
</body>
<script src="../js/vue2.7.js"></script><!--根据自己的vue文件地址-->
<script>
    let app=new Vue({
        el:"#app",
        components:{
            baibai:{//声明加注册
                template:`<div>拜拜{
   
   {name}}</div>`,
                data() {//data是在局部组件baibai里面
                    return {
                        name:"小明"
                    }
                },
            },
        },
    })
</script>
</html>

Browser result:

The second way of local components:

This time, declaration and registration are used separately; this method is currently used in the mainstream, with strong reusability and concise and easy to understand

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <div id="app">
        <baibai></baibai><!--使用-->
    </div>
</body>
<script src="../js/vue2.7.js"></script><!--根据自己的vue文件地址-->
<script>
    var baibai={//声明
        template:`<div>拜拜{
   
   {name}}</div>`,
        data() {
            return {
                name:"小明"
            }
        }
    }
    let app=new Vue({
        el:"#app",
        components:{
            baibai//注册
        },
    })
</script>
</html>

I used the abbreviation for the above registration; the following is the full registration, basically no one will write this in full;

But when you see other people’s code writing, you must be able to understand it

let app=new Vue({
    el:"#app",
    components:{
        baibai:baibai//注册
    },
})

Slot slot:

The purpose of slot (slot ) is to make the component more extensible, used to mix the content of the parent component and the template of the child component itself

Take a chestnut:  For example, weapons in the game can be embedded with gems, but you must have a slot before you can insert gems into it.

Anonymous slots:

An anonymous slot literally means a slot without a name, which is characterized by the ability to place any content you want

 Using an anonymous slot page will have multiple content if there are multiple slots.

 Code demo:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <div id="app">
        <baibai>
            <div>我是插槽的内容</div><!--组件中间的内容-->
        </baibai><!--使用-->
    </div>
</body>
<script src="../js/vue2.7.js"></script><!--根据自己的vue文件地址-->
<script>
    var baibai={//声明
        template:`<div>
                    <slot></slot>
                    拜拜{
   
   {name}}
                    <slot></slot>
                </div>`,
        data() {
            return {
                name:"小明"
            }
        }
    }
    let app=new Vue({
        el:"#app",
        components:{
            baibai//注册
        },
    })
</script>
</html>

 Browser result:

 Because two slots are written, two contents are output on the web page.

Named slots:

A named slot can use a special attribute name to configure the distribution content, and multiple named slots can have different names

 The named function lists three implementation methods in the HTML code. Carrots and cabbages have their own favorites, which one is suitable for you

 Code demo:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <div id="app">
        <baibai>
            <!--第一种方式-->
            <div slot="tou">头部内容,旧语法,据说2.6.0后废弃,但是我2.7.0还能使用</div>
            <!--第二种方式-->
            <template #shenti>
                <div>
                    身体内容,新语法,缩写
                </div>
            </template>
            <!--第三种方式-->
            <template v-slot:jiao>
                脚部内容,新语法
            </template>
        </baibai><!--使用-->
    </div>
</body>
<script src="../js/vue2.7.js"></script><!--根据自己的vue文件地址-->
<script>
    var baibai={//声明
        template:`<div>
                    <slot name="tou"></slot>
                    <slot name="shenti"></slot>
                    <div>拜拜{
   
   {name}}<div>
                    <slot name="jiao"></slot>
                </div>`,
        data() {
            return {
                name:"小明"
            }
        }
    }
    let app=new Vue({
        el:"#app",
        components:{
            baibai//注册
        },
    })
</script>
</html>

 Browser result:

Parent-child component communication:

Passing values ​​from parent to child is also a very important operation in Vue, and it will be easier to write code if it is used well.

Simple and rude $refs and $parent:

The function of these two properties is to obtain the array of child component instances and the parent component instance.

With an instance, you can easily manipulate the properties and methods of the component .

$refs parent component gets child component data:

The use of $refs requires that you declare your own reference name on the child element through the ref attribute

Writing:

 <dawa ref="dawa"></dawa><!--子类的组件;ref声明的名称父组件中要通过它来获取数据-->

The following example writes a button binding click event in the parent component to manipulate the age data of the child component to add one

Code demo:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <div id="app">
        你好,{
   
   {name}}
        <dawa ref="dawa"></dawa><!--里面ref属性不写的话就传不了值-->
        <button type="button" @click="AgeFun">子类年龄+1</button><!--在父类里面写的按钮-->
    </div>
</body>
<script src="../js/vue2.7.js"></script><!--根据自己的vue文件地址-->
<script>
    var dawa={
        template:`
            <div>
                子组件----{
   
   {childName}}--{
   
   {age}}
            </div>
        `,
        data() {
            return {
                childName:"大娃",
                age:18,
            }
        },
    }
    let app=new Vue({
        el:"#app",
        data() {
            return {
                name:"父类"
            }
        },
        methods: {
            AgeFun(){
                //拿到子组件的age值并且+1
                this.$refs.dawa.age=this.$refs.dawa.age+1
            }
        },
        components:{
            dawa
        },
    })
</script>
</html>

This result below is what I got when I clicked twice

Browser result:

 You can also get parent component data in the browser console:

 The $parent subcomponent gets the data of the parent component:

Each child component has only one parent component, and the child component can get the data of the parent component directly through $parent without declaring the name of the parent component

Code demo:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <div id="app">
        你好,{
   
   {name}}
        <dawa></dawa>
    </div>
</body>
<script src="../js/vue2.7.js"></script><!--根据自己的vue文件地址-->
<script>
    var dawa={
        template:`
            <div>
                子组件----{
   
   {childName}}--{
   
   {age}}
                <!--在子组件中写了一个按钮操作修改父类的name属性-->
                <button type="button" @click="updateFu">改父类名</button>
            </div>
        `,
        data() {
            return {
                childName:"大娃",
                age:18,
            }
        },
        methods: {
            updateFu(){
                this.$parent.name="爹爹"//点击后修改父类名称改为爹爹
            }
        },
    }
    let app=new Vue({
        el:"#app",
        data() {
            return {
                name:"父类"
            }
        },
        components:{
            dawa
        },
    })
</script>
</html>

The following result is the result after I clicked

Formal father-son communication:

Most of the methods on the market use this method of father-son communication, and the relatively simple and crude type will be a little more difficult to understand.

The child component gets the parent component data:

Pass-by-value attribute name rules:

  • The attribute name passed by the parent component should not be the same as the attribute name of the child component
  • The attribute name passed by the parent component should not appear in uppercase, and can be separated by English underscores: "_"

Writing by value:

The age attribute is a fixed value, name is a single data binding and the name attribute binding of the parent component

<dawa age="18" :name="name"></dawa>

Get the writing method:

Write props at the same level as data in subcomponents to get

props:["age","name"]

Code demo:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <div id="app">
        你好,{
   
   {name}}
        <dawa age="18" :name="name"></dawa>
    </div>
</body>
<script src="../js/vue2.7.js"></script><!--根据自己的vue文件地址-->
<script>
    var dawa={
        template:`
            <div>
                子组件----{
   
   {childName}}--{
   
   {age}}
                <br>
                <!--在子组件中将获取的属性简单演示一下-->
                父组件----{
   
   {age}}--{
   
   {name}}
            </div>
        `,
        data() {
            return {
                childName:"大娃",
                age:18,
            }
        },
        props:["age","name"],
    }
    let app=new Vue({
        el:"#app",
        data() {
            return {
                name:"父类"
            }
        },
        components:{
            dawa
        },
    })
</script>
</html>

Browser result:

Parent component gets child component data:

The parent component obtains the data of the child component by using $emit and custom events.

The parent component needs to do two things to get the data of the child component:

When the parent component uses the child component, it needs to bind a custom event to it

<!--@zidingyi是一个自定义事件,此事件会在后面在子组件注册-->
<dawa @zidingyi="fuFun" ></dawa>
//父组件里的方法
methods:{
    fuFun(val){
        // 拿到数据
        console.log(val);
    }
}

 Subcomponents take the initiative to trigger this event and pass data

//点击后给父组件传值
template:`
    <div>
        <button @click="butFun">给父组件传值</button>
    </div>
`,
//子组件里的方法
methods:{
    butFun(){
        // 子组件触发自定义事件zidingyi,同时传递数据
        this.$emit('zidingyi','数据1');
    }
}

Code demo:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <div id="app">
        你好,{
   
   {name}}
        <dawa @zidingyi="fuFun" ></dawa>
    </div>
</body>
<script src="../js/vue2.7.js"></script><!--根据自己的vue文件地址-->
<script>
    var dawa={
        template:`
            <div>
                子组件----{
   
   {childName}}--{
   
   {age}}
                <button @click="butFun">给父组件传值</button>
            </div>
        `,
        data() {
            return {
                childName:"大娃",
                age:18,
            }
        },
        methods:{
            butFun(){
                this.$emit('zidingyi',this.childName);
            }
        }
    }
    let app=new Vue({
        el:"#app",
        data() {
            return {
                name:"父类"
            }
        },
        methods: {
            fuFun(val){
                console.log(val);
            }
        },
        components:{
            dawa
        },
    })
</script>
</html>

After clicking, the method in the parent class is executed, and the data of the subclass is printed on the console.

Browser result:

Communication of non-parent-child components:

Non-parent-child component communication means that a child component can transfer data with another child component, and the child component and parent component can also transfer data to each other

Communication is divided into three steps:

Create a public component

Vue.prototype.$middleBus = new Vue();

The sender, on the public component, triggers an event

this.$middleBus.$emit('zhidingyi','你好,我是'+this.childName);

The receiver listens to this zhidingyi event on the public component and accepts the data

This code is generally written in the life cycle hook, which is executed only once after deployment, and the mounted hook is the most suitable.

this.$middleBus.$on('zhidingyi',val=>{
     // 使用箭头函数,可以不改变this的指向,仍然和外部的this保持一致,指向dawa
     console.log(this.childName+"接收到了值,值是:"+val);//在控制台打印一下
});

Code demo:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <div id="app">
        你好,{
   
   {name}}
        <dawa></dawa>
        <erwa></erwa>
    </div>
</body>
<script src="../js/vue2.7.js"></script><!--根据自己的vue文件地址-->
<script>
    //在Vue类的原型对象上,增加一个公共组件
    Vue.prototype.$middleBus = new Vue();
    var dawa={
        template:`
            <div>
                子组件1----{
   
   {childName}}--{
   
   {age}}
                <button @click="butFun">给其他人传值</button>
            </div>
        `,
        data() {
            return {
                childName:"大娃",
                age:18,
            }
        },
        methods: {
            butFun(){
                this.$middleBus.$emit('zhidingyi','你好,我是'+this.childName);
            }
        },
    }
    var erwa={
        template:`
            <div>
                子组件2----{
   
   {childName}}--{
   
   {age}}
            </div>
        `,
        data() {
            return {
                childName:"二娃",
                age:12,
            }
        },
        mounted() {
            this.$middleBus.$on('zhidingyi',val=>{
                // 使用箭头函数,可以不改变this的指向,仍然和外部的this保持一致,指向child01
                console.log(this.childName+"接收到了值,值是:"+val);//在控制台打印一下
            });
        },
    }
    let app=new Vue({
        el:"#app",
        data() {
            return {
                name:"父类"
            }
        },
        components:{
            dawa,erwa
        },
    })
</script>
</html>

After clicking, Erwa received the data in the console

Browser result:

Contamination mixins:

Provides a very flexible way to distribute reusable functionality in Vue components. A mixin object can contain arbitrary component options. When a component uses a mixin object, all the options of the mixin object will be "mixed" into the options of the component itself

Partially mixed in:

The mixed-in component should be written on it, or there will be no error report

Other components can directly use the properties of the mixed component

Code demo:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <div id="app">
        你好,{
   
   {name}}
        <dawa></dawa>
        <erwa></erwa>
    </div>
</body>
<script src="../js/vue2.7.js"></script><!--根据自己的vue文件地址-->
<script>
    var sanwa= {
        data() {
            return {
                mixinname: '三娃',
            };
        },
        mounted() {
            console.log('我是混入的组件,我的名字叫:'+this.mixinname);
        },
    };
    var dawa={
        template:`
            <div>
                子组件1----{
   
   {childName}}--{
   
   {age}}--混入组件的名称:{
   
   {mixinname}}
            </div>
        `,
        data() {
            return {
                childName:"大娃",
                age:18,
            }
        },
        mixins:[sanwa]
    }
    var erwa={
        template:`
            <div>
                子组件2----{
   
   {childName}}--{
   
   {age}}
            </div>
        `,
        data() {
            return {
                childName:"二娃",
                age:12,
            }
        },
        mixins:[sanwa]
    }
    
    let app=new Vue({
        el:"#app",
        data() {
            return {
                name:"父类"
            }
        },
        components:{
            dawa,erwa
        },
    })
</script>
</html>

Browser result:

Global mixin:

Be careful with global mixins as it will affect the instance as well as every component

Whether you want to mix it in or not, it is mixed in for you, and it is not very useful and basically you don’t need it.

Writing:

Vue.mixin(myMixin);

One last word to everyone:

Guess you like

Origin blog.csdn.net/zky__sch/article/details/132289586