使用前提: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>