vue之父组件与子组件的通信

1.背景

参数传递(多理解)
1.父传子<c-parent :messagevue="message"></c-parent>,请看下面具体的截图描述
2.子传父<c-add @eadd="madd"></c-add>,请看下面具体的截图描述


父子组件对象访问(很简单)
1.父组件访问子组件:使用$children或$refs reference(引用)
    this.$children[i] 获取调子对象
    this.$refs.child1ref 获取调子对象
2.子组件访问父组件:使用$parent
    this.$parent 获取到父对象
   
总结:
1.父组件访问子组件时一般使用$refs,因为$children需要知道下标才可以;
2.建议不要直接通过$parent获取父组件的数据,更加不要去修改,因为这样耦合度高,代码维护困难;

2.父组件向子组件传递参数-props

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <!--  <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>-->
    <script src="../js/vue.js"></script>
</head>
<body>
<h2>组件-父组件与子组件间数据传递</h2>
<pre>
1.父组件传到子组件使用:props
2.子组件传到父组件使用:$emit event
    需求:
    1.将vue实例中的message传到c-parent 组件中
    2.c-parent 组件中的 messageParent 数据传到 c-child 组件中
    注意:这里有3层关系 vue实例(爷爷)--> 父组件(父亲)--> 子组件(孙子)
</pre>
<hr>
<h2>案例如下:</h2>
<div id="app">
    <!--相当于将message中的数据传递到 messagevue 里,可以理解为赋值-->
    <c-parent :messagevue="message"></c-parent>

</div>
<!--父模板-->
<template id="parentId">
    <div>我是父组件,
        <br>
        父模板中获取到vue实例中的数据--------------:{{messagevue}}
        <!--相当于将messageParent中的数据传递到 messageparent2 里,可以理解为赋值-->
        <c-child :messageparent2="messageParent"></c-child>
    </div>
</template>
<!--子模板-->
<template id="childId">
    <div>我是子组件
        <br>
        子模板中获取到父组件中的数据为--------------:{{messageparent2}}
    </div>
</template>
<script>
    let app = new Vue({
        el: '#app',
        data: {
            message: '我是vue实例的消息'
        },
        // 1.创建主键并注册
        components: {
            'c-parent': {
                template: '#parentId',
                props: ['messagevue'],
                // 组件中数据存放
                data() {
                    return {
                        messageParent: '我是父组件中的消息'
                    }
                },
                components: {
                    'c-child': {
                        template: '#childId',
                        props: ['messageparent2'],
                        data() {
                            return {
                                messageChild: '我是子组件中的消息'
                            };
                        }
                    }
                }
            }
        }
    })
</script>
</body>
</html>
View Code

3.props的数据校验

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <!--  <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>-->
    <script src="../js/vue.js"></script>
</head>
<body>
<h2>组件-props数据校验</h2>
<pre>
用通俗的话讲就是:
    父传到子时,我们可以要求传入的必须是数字、字母、默认值等
    如下:
String
Number
Boolean
Array
Object
Date
Function
Symbol
</pre>
<hr>
<h2>案例如下:</h2>
<div id="app">
    <!--父组件给子组件赋值-->
    <c-parent :message4="message"></c-parent>
    <hr>
 <!--   <c-parent :obj1="obj"></c-parent>-->

</div>
<!--模板-->
<template id="templateId">
    <div>props参数传递校验,获取到父组件的值为:{{message4}}
    </div>
</template>
<script>
    let app = new Vue({
        el: '#app',
        data: {
            // message: '我是vue实例的消息'
            message: 10,
            obj: {name: 'vue name', age: 3}
        },
        // 1.创建主键并注册
        components: {
            'c-parent': {
                template: '#templateId',
                //props: ['message1']
                props: {
                    // 只能传入数字类型,如果传入了非数字类型,也可以显示,只是打卡浏览器控制台有报错提示信息
                    message2: Number,
                    // 必须传入字符串
                    message3: {
                        typ: String,
                        required: true,
                        // 如果父组件没有赋值,将显示该值,注意赋值为null也算是赋值了的
                        default: '我是默认值'
                    },
                    // 自定义验证
                    message4: {
                        type: Number,
                        validator: function (value) {
                            return value > 100
                        }
                    },
                    // 对象
                    obj1: {
                        type: Object,
                        default: function () {
                            return {name: 'ldp', age: 18}
                        }
                    }
                }
            }
        }
    })
</script>
</body>
</html>
View Code

4.子组件向父组件传递-$emit

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <!--  <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>-->
    <script src="../js/vue.js"></script>
</head>
<body>
<h2>组件-子组件向父组件传递</h2>
<pre>
1.子传父使用$emit
    需求:简易乘法计算器,在子组件接收数据,在父组件展示结果
</pre>
<hr>
<h2>案例如下:</h2>
<div id="app">
    <!--将子组件的事件eadd 赋值 给父组件madd-->
    <c-add @eadd="madd"></c-add>
    计算结果展示:{{numb1}}X{{numb2}}={{add}}
</div>
<!--模板-->
<template id="templateId">
    <div>
        请输入第一个数字:<input v-model="cnumb1">
        <br>
        请输入第二个数字:<input v-model="cnumb2">
        <br>
        <button @click="cadd">结果</button>
    </div>
</template>
<script>
    let app = new Vue({
        el: '#app',
        data: {
            numb1: 0,
            numb2: 0
        },
        // 计算属性
        computed: {
            add() {
                return this.numb1 * this.numb2
            }
        },
        // 方法
        methods: {
            madd(n1, n2) {
                this.numb1 = n1
                this.numb2 = n2
            }
        },
        // 组件
        components: {
            'c-add': {
                template: '#templateId',
                data() {
                    return {
                        cnumb1: 0,
                        cnumb2: 0
                    }
                },
                methods: {
                    cadd() {
                        // 将事件和参数传递到父组件中取
                        this.$emit('eadd', this.cnumb1, this.cnumb2)
                    }
                }
            }
        }
    })
</script>
</body>
</html>
View Code

5.父组件访问子组件-$children

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <!--  <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>-->
    <script src="../js/vue.js"></script>
</head>
<body>
<h2>组件-父组件访问子组件$children</h2>
<pre>
1.父组件访问子组件:使用$children或$refs reference(引用)
    this.$children[i]
    this.$refs.child1ref
2.子组件访问父组件:使用$parent
    this.$parent
    需求:
    1.定义一个父组件c-parent
    2.定义2个子组件c-child1 与 c-child2,并定义一个name
    3.在父组件中获取所有的子组件的name

总结:
    1.父组件访问子组件时一般使用$refs,因为$children需要知道下标才可以;
    2.建议不要直接通过$parent获取父组件的数据,更加不要去修改,因为这样耦合度高,代码维护困难;


</pre>
<hr>
<h2>案例如下:</h2>
<div id="app">
    <c-parent></c-parent>
</div>
<!--父组件模板-->
<template id="parentid">
    <div>
        父组件
        <c-child1></c-child1>
        <c-child2></c-child2>
        <button @click="showNames">列出子组件名称</button>
        <ul>
            <li v-for="(item,index) in names">{{index+1}}-{{item}}</li>
        </ul>
    </div>
</template>
<!--子组件模板1-->
<template id="child1id">
    <div>
        子组件1
    </div>
</template>
<!--子组件模板2-->
<template id="child2id">
    <div>
        子组件2
    </div>
</template>
<script>
    let app = new Vue({
        el: '#app',
        // 组件
        components: {
            'c-parent': {
                template: '#parentid',
                data() {
                    return {names: []}
                },
                methods: {
                    showNames() {
                        // 遍历拥有的子组件,并累加到父组件的names数组中
                        for (let i = 0; i < this.$children.length; i++) {
                            this.names.push(this.$children[i].name)
                        }
                    }
                },
                components: {
                    'c-child1': {
                        template: '#child1id',
                        data() {
                            return {
                                name: '子组件1的name'
                            }
                        }
                    },
                    'c-child2': {
                        template: '#child2id',
                        data() {
                            return {
                                name: '子组件2的name'
                            }
                        }
                    }
                }
            }
        }
    })
</script>
</body>
</html>
View Code

6.父组件访问子组件-$refs

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <!--  <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>-->
    <script src="../js/vue.js"></script>
</head>
<body>
<h2>组件-父组件访问子组件$refs</h2>
<pre>
1.$refs reference(引用)
    需求:
    1.定义一个父组件c-parent
    2.定义2个子组件c-child1 与 c-child2,并定义一个name
    3.在父组件中获取c-child1的name
</pre>
<hr>
<h2>案例如下:</h2>
<div id="app">
    <c-parent></c-parent>
</div>
<!--父组件模板-->
<template id="parentid">
    <div>
        父组件
        <c-child1 ref="child1ref"></c-child1>
        <c-child2 ref="child2ref"></c-child2>
        <button @click="showChild1Name">获取子组件c-child1的name</button>
        <br>
        取到的子组件name为:{{cname}}
    </div>
</template>
<!--子组件模板1-->
<template id="child1id">
    <div>
        子组件1
    </div>
</template>
<!--子组件模板2-->
<template id="child2id">
    <div>
        子组件2
    </div>
</template>
<script>
    let app = new Vue({
        el: '#app',
        // 组件
        components: {
            'c-parent': {
                template: '#parentid',
                data() {
                    return {cname: ''}
                },
                methods: {
                    showChild1Name() {
                        // 通过 $refs 与 <c-child1 ref="child1-ref"></c-child1> 获取指定子组件的name
                        this.cname = this.$refs.child1ref.name
                    }
                },
                components: {
                    'c-child1': {
                        template: '#child1id',
                        data() {
                            return {
                                name: '子组件1的name'
                            }
                        }
                    },
                    'c-child2': {
                        template: '#child2id',
                        data() {
                            return {
                                name: '子组件2的name'
                            }
                        }
                    }
                }
            }
        }
    })
</script>
</body>
</html>
View Code

7.子组件访问父组件-$parent

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <!--  <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>-->
    <script src="../js/vue.js"></script>
</head>
<body>
<h2>组件-子组件访问父组件$parent</h2>
<pre>
1.子组件访问父组件:使用$parent
    需求:
    1.定义一个父组件c-parent,并定义一个name
    2.定义1个子组件c-child1
    3.在子组件中获取父组件的name

总结:
    1.建议不要直接通过$parent获取父组件的数据,更加不要去修改,因为这样耦合度高,代码维护困难;
</pre>
<hr>
<h2>案例如下:</h2>
<div id="app">
    <c-parent></c-parent>
</div>
<!--父组件模板-->
<template id="parentid">
    <div>
        父组件
        <c-child1></c-child1>
    </div>
</template>
<!--子组件模板1-->
<template id="child1id">
    <div>
        子组件1
        <button @click="showParentName">获取父组件的name</button>
        <br>
        父组件的name为:{{name}}
    </div>
</template>
<script>
    let app = new Vue({
        el: '#app',
        // 组件
        components: {
            'c-parent': {
                template: '#parentid',
                data() {
                    return {name: '父组件的name'}
                },
                components: {
                    'c-child1': {
                        template: '#child1id',
                        data() {
                            return {
                                name: ''
                            }
                        },
                        methods: {
                            showParentName() {
                                this.name = this.$parent.name
                            }
                        }
                    }
                }
            }
        }
    })
</script>
</body>
</html>
View Code

完美!

原文地址:https://www.cnblogs.com/newAndHui/p/13840783.html