.sync原理(Vue组件父子传值)

使用前提:vue

首先,咱们须要明确的是,子父组件之间通信,子组件是不能直接改变父组件的值的。(父组件是大佬,小弟不能改变大佬的值,可是父组件能够改变子组件的值)函数

做用:this

经过某种方式,子组件能够”直接“改变父组件的值。spa

场景:code

控制弹框的显示与关闭。在父组件中打开子组件弹框,而后在点击子组件中的按钮关闭弹框。component

方法:blog

1. 通常咱们子父传值的处理以下:ip

  注意:子组件向父组件传值时,父组件中@changeVisibleState="changeVisible"中,方法名不要加括号!!!!@changeVisibleState="changeVisible()"
input

// 父组件
<template>
    <div class="parent-file">
        <input type="button" value="打开子组件" @click="show">
        <!-- 子组件插槽 -->
        <child @changeVisibleState="changeVisible" :visible="childShow"/>
    </div>
</template>

<script>
import child from "./child"
    export default {
        data () {
            return {
                childShow: false
            }
        },
        components: {
            child
        },
        methods: {
            show(){
                this.childShow = true;
            },
            changeVisible (val) {
                this.childShow = val;
            }
        }
    }
</script>
// 子组件
<template>
    <div class="child-file">
        <input type="button" value="点我隐身" @click="doClose" v-show="visible">
    </div>
</template>

<script>
    export default {
        props: [ 'visible' ],
        methods: {
            doClose () {
                this.$emit("changeVisibleState", false)
            }
        }
    }
</script>

2. 改进:it

这样的写法没错,可是显的比较臃肿,明明我只是要改一个值,就不能简单点?

答案是,固然是能够的。

你们确定会想,那我不能直接改变父组件的值?想v-model那样,多爽。

vue也是考虑到了这点,因此提供了一个更好的解决方案

// 父组件
//  先把方法写到行内,箭头函数的写法。
//  方法名为何是update:visible,是下面子组件的emit方法定义的。
<template>
    <div class="parent-file">
        <input type="button" value="打开子组件" @click="show">
        <!-- 子组件插槽 -->
        <child @update:visible="(val)=>{ childShow = val }" :visible="childShow"/>
    </div>
</template>

<script>
import child from "./child"
    export default {
        data () {
            return {
                childShow: false
            }
        },
        components: {
            child
        },
        methods: {
            show(){
                this.childShow = true;
            },
            // 以简化代码
            // changeVisible (val) {
            //     this.childShow = val;
            // }
        }
    }
</script>
// 子组件
<template>
    <div class="child-file">
        <input type="button" value="点我隐身" @click="doClose" v-show="visible">
    </div>
</template>

<script>
    export default {
        props: [ 'visible' ],
        methods: {
            doClose () {
                // 修改前代码
                // this.$emit("changeVisibleState", false)

                // 改变写法
                this.$emit("update:visible",false);
            }
        }
    }
</script>

3. 最后:

对于 @update:visible="(val)=>{childShow = val}" :visible="childShow",vue提供了一个语法糖,将其替换成 :visible.sync = "childShow" ,这样是否是看起来简洁多了。

那么就变成了:

// 父组件
<template>
    <div class="parent-file">
        <input type="button" value="打开子组件" @click="show">
        <!-- 子组件插槽 -->
        <child :visible.sync = "childShow"/>
    </div>
</template>

<script>
import child from "./child"
    export default {
        data () {
            return {
                childShow: false
            }
        },
        components: {
            child
        },
        methods: {
            show(){
                this.childShow = true;
            },
            // 以简化代码
            // changeVisible (val) {
            //     this.childShow = val;
            // }
        }
    }
</script>
// 子组件
<template>
    <div class="child-file">
        <input type="button" value="点我隐身" @click="doClose" v-show="visible">
    </div>
</template>

<script>
    export default {
        props: [ 'visible' ],
        methods: {
            doClose () {
                // 修改前
                // this.$emit("changeVisibleState", false)

                // 改变写法
                // 注意:emit中的函数名,必定要以这种格式"update:props"命名,其中props就是咱们子父之间通信的值
                this.$emit("update:visible", false);
            }
        }
    }
</script>
相关文章
相关标签/搜索