5-5 组件及组件间的通信-单向数据流

目录:

  •  单向数据流验证
  • 如果子组件向把它作为局部数据来使用,可以将数据存入另一个变量中再操作,不影响父组件中的数据
  • 如果子组件向修改数据并且同步更新到父组件

一、单项数据流验证

props是单向绑定的,当父组件的属性变化是,将传导给子组件,但是不会返回过来。而且不允许子组件直接修改父组件中的数据,不然会报错。官方参考: 单向数据流

1.1、验证props是单向绑定,父组件属性变化,也会传导给子组件

实例代码如下:

<body>
    <div id="box">
        <h2>父组件:{{name}}</h2>
        <input type="text" v-model="name">
        <hr>

        <my-hello :name="name"></my-hello>
    </div>

    <template id="hello">
        <div>
            <h3>子组件: {{name}}</h3>
        </div>
    </template>
    <script src="../vue.js"></script>
    <script>
        var vm = new Vue({ //父组件
            el: '#box',
            data:{
                name: 'tom'
            },
            components:{
                'my-hello':{ //子组件
                    template: "#hello",
                    props:['name']
                }
            }
        });
    </script>
</body>
props单向绑定验证

页面输出如下:(父组件的数据改了,子组件的值也跟着改变)

父组件:tomcat


子组件: tomcat

1.2、验证不允许子组件直接修改父组件中的数据,不然会报错

实例代码如下:

<body>
    <div id="box">
        <h2>父组件:{{name}}</h2>
        <input type="text" v-model="name">
        <hr>

        <my-hello :name="name"></my-hello>
    </div>

    <template id="hello">
        <div>
            <h3>子组件: {{name}}</h3>
            <button @click="change">修改数据</button>
        </div>
    </template>
    <script src="../vue.js"></script>
    <script>
        var vm = new Vue({ //父组件
            el: '#box',
            data:{
                name: 'tom'
            },
            components:{
                'my-hello':{ //子组件
                    template: "#hello",
                    props:['name'],
                    methods:{
                        change(){
                            this.name='alice';
                        }
                    }
                }
            }
        });
    </script>
</body>
修改子组件值,不会修改父组件值

页面输出如下:(看出修改父组件传递给子组件的值,父组件是不会受到改变)

父组件:tom


子组件: alice

报错如下:
vue.js:634 [Vue warn]: Avoid mutating a prop directly since the value will be overwritten whenever the parent component re-renders. 
Instead, use a data or computed property based on the prop's value. Prop being mutated: "name"

found in

---> <MyHello>
       <Root>

只修改子组件中父组件传过来的值,但是不会报错,解决方式有2种,如下:

  方式1:如果子组件向把它作为局部数据来使用,可以将数据存入另一个变量中再操作,不影响父组件中的数据。

  方式2:如果子组件向修改数据并且同步更新到父组件,有两个方法:

    a.使用sync(1.0版本中支持,2.0版本中不支持,2.3版本又开始支持),这边需要显式的触发一个更新事件。

              b.可以将父组件中的数据包装成对象,然后在子组件中修改对象的属性(因为对象是引用类型,指向同一个内存空间)  => 推荐

二、子组件向把它作为局部数据来使用,可以将数据存入另一个变量中再操作,不影响父组件中的数据

思路图如下:

实现代码如下:

<body>
    <div id="box">
        <h2>父组件:{{name}}</h2>
        <hr>
        <my-hello :name="name"></my-hello>
    </div>

    <template id="hello">
        <div>
            <h3>子组件: {{username}}</h3>
            <button @click="change">修改数据</button>
        </div>
    </template>
    <script src="../vue.js"></script>
    <script>
        var vm = new Vue({ //父组件
            el: '#box',
            data:{
                name: 'tom'
            },
            components:{
                'my-hello':{ //子组件
                    template: "#hello",
                    props:['name'],
                    data(){
                        return {
                            username: this.name //方式1:将数据存入另一个变量中再操作
                        }
                    },
                    methods:{
                        change(){
                            this.username='alice';
                        }
                    }
                }
            }
        });
    </script>
</body>
子组件向把它作为局部数据来使用,可以将数据存入另一个变量中再操作,不影响父组件中的数据

三、子组件向修改数据并且同步更新到父组件

3.1、使用sync

说明:使用sync(1.0版本中支持,2.0版本中不支持,2.3版本又开始支持),这边需要显式的触发一个更新事件。sync-修饰符

实现代码如下:

<body>
    <div id="box">
        <h2>父组件:{{name}}</h2>
        <input type="text" v-model="name">
        <hr>
        <!--绑定name,并且允许子组件改,并且跟父组件中的值同步-->
        <my-hello :name.sync="name"></my-hello>
    </div>

    <template id="hello">
        <div>
            <h3>子组件: {{name}}</h3>
            <button @click="change">修改数据</button>
        </div>
    </template>
    <script src="../vue.js"></script>
    <script>
        var vm = new Vue({ //父组件
            el: '#box',
            data:{
                name: 'tom'
            },
            components:{
                'my-hello':{ //子组件
                    template: "#hello",
                    props:['name'],
                    methods:{
                        change(){
                            //这个是固定格式:必须是update:props属性,新值
                            this.$emit('update:name', 'Alice') //方式2: a.使用.sync,需要显式的触发一个更新事件
                        }
                    }
                }
            }
        });
    </script>
</body>
使用:name.sync

3.2、可以将父组件中的数据包装成对象,然后在子组件中修改对象的属性(推荐)

说明:可以将父组件中的数据包装成对象,然后在子组件中修改对象的属性(因为对象是引用类型,指向同一个内存空间)  => 推荐

 

<body>
    <div id="box">
        <h2>父组件:{{name}}</h2>
        <h2>父组件:{{user.age}}</h2>
        <hr>
        <!--绑定name,并且允许子组件改,并且跟父组件中的值同步-->
        <my-hello :name.sync="name" :user="user"></my-hello>
    </div>

    <template id="hello">
        <div>
            <h3>子组件: {{name}}</h3>
            <h3>子组件: {{user.age}}</h3>
            <button @click="change">修改数据</button>
        </div>
    </template>
    <script src="../vue.js"></script>
    <script>
        var vm = new Vue({ //父组件
            el: '#box',
            data:{
                name: 'tom',
                user:{
                    name: '高哥哥',
                    age: 24
                }
            },
            components:{
                'my-hello':{ //子组件
                    template: "#hello",
                    props:['name','user'],
                    methods:{
                        change(){
                            //这个是固定格式:必须是update:props属性,新值
                            //this.$emit('update:name', 'Alice') //方式2: a.使用.sync,需要显式的触发一个更新事件
                            // this.user = {};这个叫改,只是改对象中的某个属性,不叫改
                            this.user.age = 18;//user的地址空间没有改,只是user对象属性改了,这个不算改
                        }
                    }
                }
            }
        });
    </script>
</body>
可以将父组件中的数据包装成对象,然后在子组件中修改对象的属性

 

posted @ 2020-03-13 13:54  帅丶高高  阅读(248)  评论(0)    收藏  举报