這是一篇詳細講解vue父子組件之間通信的文章,初始學習vue的時候,總是搞不清楚幾個情況
- 通過props在父子組件傳值時,v-bind:data="data",props接收的到底是哪個?
- this.$emit提交的事件名稱,v-on:handleChange="handleChange",和父組件監聽時候創建的方法名是否一樣?到底哪個才是v-on應該監聽的事件名稱?
你是否也有這樣的疑惑呢?如果你跟我有一樣的疑惑,那么繼續往下看吧~~
1.創建一個父組件 Parent.vue,在data中添加一個parentAge
<template> <div class="my-parent"> <h3>我是父組件</h3> <p>父組件的年齡是:{parentAge}}</p> </div> </template> <script> export default { data() { return { parentAge: 50 }; } }; </script> <style> .my-parent { text-align: left; text-indent: 1em; width: 1000px; height: 500px; border: 1px solid #555; } </style>
2.創建子組件,在data中添加一個childAge
<template> <div class="my-child"> <h3>我是子組件</h3> <p>子組件的年齡是:{{childAge}}</p> </div> </template> <script> export default { data() { return { childAge: 27 }; } }; </script> <style> .my-child { margin: 20px; width: 760px; height: 200px; border: 1px solid red; } </style>
3.把父子組件關聯起來,並通過v-bind(即簡寫“:”)將父組件中的parentAge值,傳遞給子組件
v-on綁定的屬性名稱deliverParentAge與data中定義的parentAge名稱可以不一樣
屬性deliverParentAge通過v-bind綁定的,也是子組件中通過props接收的,而parentAge是要傳遞給子組件的數值,它是一個值
<template> <div class="my-parent"> <h3>我是父組件,我想告訴我的子組件,我的年齡值是:{{parentAge}}</h3> <h3>我要通過v-bind(即簡寫":")語法糖綁定一個屬性deliverParentAge,將父組件的值傳遞到子組件中</h3> <!-- 下面就是我的子組件 --> <my-child :deliverParentAge="parentAge"></my-child> </div> </template> <script> import MyChild from "./Child"; export default { components: { MyChild }, data() { return { parentAge: 49 }; } }; </script>
4.子組件通過props屬性,在子組件中接收父組件傳過來的值
<template> <div class="my-child"> <h5>我是子組件,我可以通過屬性props來接收父組件傳過來的年齡值是:{{deliverParentAge}}</h5> </div> </template> <script> export default { data() { return { childAge: 27 }; }, props: { deliverParentAge: Number } }; </script>
5.現在來修改父組件的值(這個不是真的修改而是通過this.$emit提交一個事件,將子組件的行為告訴父組件)
<template> <div class="my-child"> <h5>我是子組件,我可以通過屬性props來接收父組件傳過來的年齡值是:{{deliverParentAge}},這是一個數字類型</h5> <h5>並且,我要告訴他,他今年生日已經過了,所以他的年齡應該<button @click="AddAge">加1</button></h5> 下面我要通過this.$emit方法提交一個事件addParentAge,告訴我的父組件,他的實際年齡 </div> </template> <script> export default { data() { return { childAge: 27 }; }, props: { deliverParentAge: Number }, // 新建一個計算屬性,將父組件原來的值加1 computed: { parentActualAge() { return this.deliverParentAge + 1; } }, methods: { AddAge() { this.$emit("addParentAge", this.parentActualAge); } } }; </script>
6.父組件通過語法糖v-on(即簡寫為“@”)來監聽子組件提交的事件addParentAge
this.$emit提交的事件名稱addParentAge,與方法handleAddParentAge名稱可以不一樣
addParentAge是子組件提交的事件名稱,也是父組件通過v-on監聽的事件名稱,而handleAddParentAge是父組件自定義的方法名稱
<template> <div class="my-parent"> <h3>我是父組件,我想告訴我的子組件,我的年齡值是:{{parentAge}}</h3> <h3>我要通過v-bind(即簡寫":")語法糖綁定一個屬性parentAge,告訴子組件我的年齡值是:{{parentAge}}</h3> <!-- 下面就是我的子組件 --> <my-child :deliverParentAge="parentAge" @addParentAge="handleAddParentAge"></my-child> <h3>通過監聽子組件提交的事件addParentAge,我知道到了自己的實際年齡應該是:{{parentAge+1}},並通過方法handleAddParentAge,在控制台打印出我的真實年齡</h3> </div> </template> <script> import MyChild from "./Child"; export default { components: { MyChild }, data() { return { parentAge: 49 }; }, methods: { handleAddParentAge(actualAge) { console.log("父組件的實際年齡是:", actualAge); } } }; </script>
現在來看控制台打印出來的內容
7.現在將子組件data中的值,提交給父組件來看看
<template> <div class="my-child"> <h5>我是子組件,我可以通過屬性props來接收父組件傳過來的年齡值是:{{deliverParentAge}},這是一個數字類型</h5> <h5>現在我要告訴父組件,我的年齡是{{childAge}},這樣他就可以知道,我們<button @click="DiffAge">相差</button>多少歲</h5> <h5>並且,我要告訴他,他今年生日已經過了,所以他的年齡應該<button @click="AddAge">加1</button></h5> 下面我要通過this.$emit方法提交一個事件addParentAge,告訴我的父組件,他的實際年齡 </div> </template> <script> export default { data() { return { childAge: 27 }; }, props: { deliverParentAge: Number }, computed: { parentActualAge() { return this.deliverParentAge + 1; } }, methods: { AddAge() { this.$emit("addParentAge", this.parentActualAge); }, DiffAge() { this.$emit("differAge", this.childAge); } } }; </script>
8.父組件通過v-on監聽子組件提交的事件differAge
<template> <div class="my-parent"> <h3>我是父組件,我想告訴我的子組件,我的年齡值是:{{parentAge}}</h3> <h3>我要通過v-bind(即簡寫":")語法糖綁定一個屬性parentAge,告訴子組件我的年齡值是:{{parentAge}}</h3> <!-- 下面就是我的子組件 --> <my-child :deliverParentAge="parentAge" @differAge="handleDifferAge" @addParentAge="handleAddParentAge"></my-child> <h3>通過監聽子組件提交的事件addParentAge,我知道到了自己的實際年齡應該是:{{parentAge+1}},並通過方法handleAddParentAge,在控制台打印出我的真實年齡</h3> <h3>通過監聽子組件提交的事件differAge,並通過方法handleDifferAge,在控制台打印出子組件的年齡</h3> </div> </template> <script> import MyChild from "./Child"; export default { components: { MyChild }, data() { return { parentAge: 49 }; }, methods: { handleAddParentAge(actualAge) { console.log("父組件的實際年齡是:", actualAge); }, handleDifferAge(child) { console.log("我們的年齡差是:", this.parentAge + 1 - child); } } }; </script>
現在來看看頁面展示的效果和控制台打印出來的信息
下面貼上完整的代碼
// Parent.vue <template> <div class="my-parent"> <h3>我是父組件,我想告訴我的子組件,我的年齡值是:{{parentAge}}</h3> <h3>我要通過v-bind(即簡寫":")語法糖綁定一個屬性parentAge,告訴子組件我的年齡值是:{{parentAge}}</h3> <!-- 下面就是我的子組件 --> <my-child :deliverParentAge="parentAge" @differAge="handleDifferAge" @addParentAge="handleAddParentAge"></my-child> <h3>通過監聽子組件提交的事件addParentAge,我知道到了自己的實際年齡應該是:{{parentAge+1}},並通過方法handleAddParentAge,在控制台打印出我的真實年齡</h3> <h3>通過監聽子組件提交的事件differAge,並通過方法handleDifferAge,在控制台打印出子組件的年齡</h3> </div> </template> <script> import MyChild from "./Child"; export default { components: { MyChild }, data() { return { parentAge: 49 }; }, methods: { handleAddParentAge(actualAge) { console.log("父組件的實際年齡是:", actualAge); }, handleDifferAge(child) { console.log("我們的年齡差是:", this.parentAge + 1 - child); } } }; </script> <style lang="stylus" scoped> .my-parent { text-align: left; text-indent: 1em; width: 1000px; height: 500px; border: 1px solid #555; } </style>
// Child.vue <template> <div class="my-child"> <h5>我是子組件,我可以通過屬性props來接收父組件傳過來的年齡值是:{{deliverParentAge}},這是一個數字類型</h5> <h5>現在我要告訴父組件,我的年齡是{{childAge}},這樣他就可以知道,我們<button @click="DiffAge">相差</button>多少歲</h5> <h5>並且,我要告訴他,他今年生日已經過了,所以他的年齡應該<button @click="AddAge">加1</button></h5> 下面我要通過this.$emit方法提交一個事件addParentAge,告訴我的父組件,他的實際年齡 </div> </template> <script> export default { data() { return { childAge: 27 }; }, props: { deliverParentAge: Number }, computed: { parentActualAge() { return this.deliverParentAge + 1; } }, methods: { AddAge() { this.$emit("addParentAge", this.parentActualAge); }, DiffAge() { this.$emit("differAge", this.childAge); } } }; </script> <style> .my-child { margin: 20px; width: 760px; height: 200px; border: 1px solid red; } </style>
希望對你有用,歡迎提問與指正,一起學習前端呀!