.sync原理(Vue組件父子傳值)


使用前提:

首先,我們需要明確的是,子父組件之間通訊,子組件是不能直接改變父組件的值的。(父組件是大佬,小弟不能改變大佬的值,但是父組件可以改變子組件的值)

作用:

通過某種方式,子組件可以”直接“改變父組件的值。

場景:

控制彈框的顯示與關閉。在父組件中打開子組件彈框,然后在點擊子組件中的按鈕關閉彈框。

方法:

1. 一般我們子父傳值的處理如下:

  注意:子組件向父組件傳值時,父組件中@changeVisibleState="changeVisible"中,方法名不要加括號!!!!@changeVisibleState="changeVisible()"

// 父組件
<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. 改進:

這樣的寫法沒錯,但是顯的比較臃腫,明明我只是要改一個值,就不能簡單點?

答案是,當然是可以的。

大家肯定會想,那我不能直接改變父組件的值?想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>


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM