.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>
相關文章
相關標籤/搜索