通过大头儿子和小头爸爸,给女朋友讲明白了vue中父子组件的传值

写在前面: 我是「扬帆向海」,这个暱称来源于我的名字以及女朋友的名字。我热爱技术、热爱开源、热爱编程。技术是开源的、知识是共享的

这博客是对自己学习的一点点总结及记录,如果您对 Java算法 感兴趣,可以关注我的动态,我们一起学习。

用知识改变命运,让我们的家人过上更好的生活


女朋友:“扬帆,你给我上一次讲了 vue中的组件
,我现在自己学习父子组件的传值,可是官方文档看不懂啊!你能不能通过父子组件传值的知识实现大头儿子和小头爸爸互相通信呢?”

: “可以呀!我先分别给你讲父组件向子组件传值和子组件向父组件传值,最后在给你写个案例,实现父子组件的相互通信。”

在这里插入图片描述

点击【说话】按钮,大头儿子给小头爸爸传递消息。

在这里插入图片描述

小头爸爸收到消息,点击【回复】按钮,给大头儿子发送消息。

在这里插入图片描述


一、父组件向子组件传值

1. 传值步骤

① 子组件在props中创建一个属性,用以接收父组件传过来的数据;

② 父组件中注册子组件。通过属性绑定(v-bind:)的形式,把需要传递给子组件的数据传递到子组件的内部,供子组件使用;

③ 在子组件标签中添加子组件props中创建的属性;

④ 把需要传给子组件的值赋给该属性

2. 代码示例

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <title>父组件向子组件传值</title>
    <script src="js/vue.js"></script>
</head>

<body>
    <div id="app">
        <!-- 父组件中注册子组件 -->
        <!-- 在子组件标签中添加子组件props中创建的属性, 把需要传给子组件的值赋给该属性 -->
        <mycom :parent-msg='pmsg' :content='hello'></mycom>
    </div>
    <script>
        var vm = new Vue({
            el: '#app',
            data: {
                pmsg: '父组件中的内容',
                hello: '我是父组件传过来的'
            },
            components: {
                mycom: {
                    data: function () {
                        return {
                            msg: '我是子组件本身的数据'
                        }
                    },
                    // 子组件在props中创建一个属性,用以接收父组件传过来的值
                    props: ['parentMsg', 'content'],
                    template: '<h3>{{msg + "---" + parentMsg + "----" + content}}</h3>'
                }
            }
        });
    </script>
</body>

</html>

【效果如下】
在这里插入图片描述

3. 注意事项

prop 是子组件用来接受父组件传递过来的数据的一个自定义属性。

② 父组件的数据需要通过 props 把数据传给子组件,子组件需要显式地用 props 选项声明 “prop”:

prop 是单向绑定的:当父组件的属性变化时,将传导给子组件,但是不会反过来。

props中的数据都是只读的,无法进行重新赋值。

二、子组件向父组件传值

1. 传值步骤

① 子组件需要以某种方式例如点击事件的方法来触发一个自定义事件;

② 将需要传递的值作为$emit的第二个参数,该值将作为实参传递给响应自定义事件的方法;

③ 在父组件中注册子组件,在子组件标签上监听该自定义事件,并添加一个响应该事件的处理方法

2. 代码示例

点击子组件中的按钮,给父组件发送子组件的信息

<body>
    <div id="app">
        <h3>父组件</h3>
        <child @receive="handleEvent"></child>
    </div>
    <script>
        Vue.component('child', {
            template: `
                <div>
                    <h3>子组件</h3>
                    <button @click="sendMessage()">发送</button>
                </div>
            `,
            data() {
                return {
                }
            },
            methods: {
                sendMessage() { // 按钮的点击事件
                    this.$emit("receive","父组件您好,我是子组件!") // 调用父组件传递过来的方法,并且把数据传递出去
                }
            }
        })
        var vm = new Vue({
            el: '#app',
            methods: {
                // 定义在子组件中通过 this.$emit() 调用的方法
                handleEvent(val) {
                    console.log("父组件收到的消息是:",val)
                }
            }
        })
    </script>
</body>

【效果如下】
在这里插入图片描述

3. 注意事项

① 父组件是使用 props 传递数据给子组件,但如果子组件要把数据传递回去,就需要使用自定义事件!

② 我们可以使用 v-on 绑定自定义事件, 每个 Vue 实例都实现了事件接口(Events interface),即:

使用 $on(eventName) 监听事件
使用 $emit(eventName) 触发事件

③ 父组件可以在使用子组件的地方直接用 v-on 来监听子组件触发的事件。

三、大头儿子小头爸爸案例

这个案例实现了文章开头:大头儿子和小头爸爸之间的通信

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>父子组件通信</title>
    <script src="js/vue.js"></script>
    <style>
        .father,
        .son {
            width: 150px;
            height: 100px;
        }

        .info {
            color: #446ee4;
            font-size: 20px;
            font-size: bold;
        }

        .desc {
            font-size: 18px;
        }

        .btn {
            width: 100px;
            float: left;
            height: 40px;
            font-size: 18px;
            color: #fff;
            font-weight: bold;
            background: #446ee4;
            margin-top: 15px;
        }

        .parent,
        .child {
            display: inline-block;
            width: 550px;
        }
    </style>
</head>

<body>
    <div id="app">
        <div class="parent">
            <img class="father" src="images/father.jpg">
            <div class="info">我是小头爸爸</div>
            <div v-if="msg !== ''" class="desc">小头爸爸接收到的消息:【{{msg}}】</div>
            <div v-if="replyMsg !== ''" class="desc">小头爸爸回复说:【{{replyMsg}}】</div>
            <button class="btn" @click="reply()">回复</button></button>
        </div>
        <div class="child">
            <child :reply-msg="replyMsg" @listen="listenHandle($event)"></child>
        </div>
    </div>
    <script>
        Vue.component('child', {
            props: {
                replyMsg: {
                    type: String,
                    default: ''
                }
            },
            template: `
                <div>
                    <img class="son" src="images/son.jpg">
                    <div class="info">我是大头儿子</div>
                    <div v-if="msg !== ''" class="desc">大头儿子说:【{{msg}}】</div>
                    <div v-if="replyMsg !== ''" class="desc">大头儿子接收到的消息:【{{replyMsg}}】</div>
                    <button class="btn" @click="say()">说话</button>
                </div>
            `,
            data() {
                return {
                    msg: ''
                }
            },
            methods: {
                say() {
                    this.msg = '小头爸爸好!'
                    this.$emit("listen", this.msg)
                }
            }
        })
        var vm = new Vue({
            el: '#app',
            data() {
                return {
                    msg: '',
                    replyMsg: ''
                }
            },
            methods: {
                listenHandle(val) {
                    this.msg = val
                },
                reply() {
                    this.replyMsg = '小头儿子好,消息已收到'
                }
            },

        })
    </script>
</body>

</html>

【效果如下】

在这里插入图片描述

四、总结

在这里插入图片描述

在组件传值过程中,无论是父传子、还是子传父,它们都有一个共同点就是有一个中间介质。父传子的介质是props中的属性,子传父的介质是自定义事件。

父子组件的关系可以总结为prop向下传递,事件向上传递。父组件通过prop给子组件下发数据,子组件通过事件给父组件发送信息。

父组件通过 v-bind:绑定参数传给子组件,子组件通过props接受这个参数。

在组件的最底层开始写事件,由最底层组件逐步向上$emit事件流,并携带相应参数,最后在父组件内完成总的数据处理。


由于水平有限,本博客难免有不足,恳请各位大佬不吝赐教!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章