Vue中組件的傳值方式詳解
前言
Vue中最常見的組件之間的通信方式有12種,分別為:props、$emit、sync、v-model、ref、$children / $parent、$attrs / $listeners、provide / inject、EventBus、 Vuex、 $root、 slot。
今天我們會詳細講解父傳子props方式和子傳父¥emit以及非父子組件傳值。
一、父傳子
props聲明:
父傳子的實現(xiàn)方式就是通過props屬性,子組件通過props屬性接收從父組件傳過來的值,而父組件傳值的時候使用 v-bind 將子組件中預(yù)留的變量名綁定為data里面的數(shù)據(jù)即可
定義方式:
字符串:
export default {
props: ['foo'],
created() {
// props 會暴露到 `this` 上
console.log(this.foo)
}
}對象方式:
export default {
props: {
title: String,
likes: Number
}
}舉例:
父組件:
<template>
<div id="app">
<!--App props 配置方式 -->
<student id="002" name="李四" sex="男" age="18"></student>
<student id="003" name="王五" sex="女"></student>
</div>
</template>
<script>
import student from "@/components/Student";
export default {
name: 'App',
components: {
student
}
}
</script>子組件:
<template>
<div>
<h2 >學生ID:{{ id }}</h2>
<h2>學生姓名:{{ name }}</h2>
<h2>學生性別:{{ sex }}</h2>
<h2>學生年齡:{{ age }}</h2>
</div>
</template>
<script>
export default {
// eslint-disable-next-line vue/multi-word-component-names
name: "student",
data() {
return {}
},
// 聲明 接收app傳遞過來的數(shù)據(jù)
props:['id','name','sex','age']
/*methods:{
up(){
this.$props.name = '阿薩德';
}
},*/
// 接收數(shù)據(jù)的時候限制數(shù)據(jù)的類型
// props: {
// id: String,
// name: String,
// sex: String,
// age: Number
// }
// props:{
// id: {
// type:String,
// required:true
// },
// name: {
// type:String,
// required:true
// },
// sex: {
// type:String,
// required:true
// },
// age: {
// type:String, // 類型
// default:'18', // 默認值
// required:false, // 必要的 true false
// validator: function (value) { //驗證數(shù)據(jù)
// return value >= 1;
// }
// }
//
// }
}
</script>
<style scoped>
</style>效果圖:

原理:所有的 props 都遵循著單向綁定原則,props 因父組件的更新而變化,自然地將新的狀態(tài)向下流往子組件,而不會逆向傳遞。
這避免了子組件意外修改父組件的狀態(tài)的情況,不然應(yīng)用的數(shù)據(jù)流將很容易變得混亂而難以理解。
另外,每次父組件更新后,所有的子組件中的 props 都會被更新到最新值。(子組件中不能更待props值,會出現(xiàn)報錯?。?/p>
二、子傳父
父組件:
<template>
<div>
<!-- 通過父組件 給子組件綁定一個自定事件 實現(xiàn)子組件給父組件 -->
<!-- ****** 傳遞數(shù)據(jù) -->
<Student @zhangsan="getStudentName"></Student>
<hr/>
<Student ref="student"></Student>
</div>
</template>
<script>
import Student from "@/components/Student";
export default {
name: 'App',
data() {
return {}
}, components: {
Student
}, methods: {
getStudentName(name) {
console.log("獲取到了學生的的信息" + name)
}
},mounted() {
/* $on(eventName) 監(jiān)聽事件 */
/* Vue 為每個窗口 都提供了一個 事件接口 Events interface */
this.$refs.student.$on('zhangsan',this.getStudentName)
}
}
</script>子組件:
<template>
<div>
<h2>學生姓名:{{ name }} </h2>
<h2>學生性別:{{ sex }} </h2>
<button @click="sendStudentName">點我傳遞學生信息</button>
</div>
</template>
<script>
export default {
// eslint-disable-next-line vue/multi-word-component-names
name: "Student",
data() {
return {
name: '張三',
sex: '男'
}
},methods:{
sendStudentName(){
// $emit 觸發(fā)事件 >>> $emit(eventName)
this.$emit('zhangsan',this.name);
// this.$emit('zhangsan',this.name,.,.,.,.,.,.);
}
}
}
</script>
<style scoped>
</style>效果圖:

三、非父子組件
兄弟組件之間的數(shù)據(jù)傳遞,通過 eventBus 來做中間的橋梁,傳輸方通過 Bus.$emit('自定義事件名', 數(shù)據(jù))傳數(shù)據(jù),接收方通過 Bus.$on('自定義事件名', callback)接收數(shù)據(jù),兩者之間的自定義屬性名保持一致
傳值思想其實是一致的,先使用$on定義一個全局事件,后面寫個回調(diào)函數(shù),觸發(fā)這個事件執(zhí)行的方法,可以接參數(shù)bus.$on('msg',val=>{ }),msg就是全局事件,然后在想要獲取這個全局事件里面的值就調(diào)用他,不過這時候不是 this.emit 而是 bus . emit 而是 bus.emit而是bus.emit
A組件:
<template>
<div>
A組件:
<span>{{elementValue}}</span>
<input type="button" value="點擊觸發(fā)" @click="elementByValue">
</div>
</template>
<script>
// 引入公共的bug,來做為中間傳達的工具
import Bus from './bus.js'
export default {
data () {
return {
elementValue: 4
}
},
methods: {
elementByValue: function () {
Bus.$emit('val', this.elementValue)
}
}
}
</script>B組件:
<template>
<div>
B組件:
<input type="button" value="點擊觸發(fā)" @click="getData">
<span>{{name}}</span>
</div>
</template>
<script>
import Bus from './bus.js'
export default {
data () {
return {
name: 0
}
},
mounted: function () {
var vm = this
// 用$on事件來接收參數(shù)
Bus.$on('val', (data) => {
console.log(data)
vm.name = data
})
},
methods: {
getData: function () {
this.name++
}
}
}
</script>四、其他傳值方式
組件中可以使用 $parent和 $children獲取到父組件實例和子組件實例,進而獲取數(shù)據(jù)$parent 當前組件樹的根 Vue 實例。
如果當前實例沒有父實例,此實例將會是其自己。
$children 當前實例的直接子組件。
需要注意 $children 并不保證順序,也不是響應(yīng)式的。如果你發(fā)現(xiàn)自己正在嘗試使用 $children 來進行數(shù)據(jù)綁定,考慮使用一個數(shù)組配合 v-for 來生成子組件,并且使用 Array 作為真正的來源。
總結(jié):
父組件通過 prop 給子組件下發(fā)數(shù)據(jù),子組件通過事件給父組件發(fā)送消息
最后的最后賦一張借鑒來的圖供大家快速記憶:

到此這篇關(guān)于Vue中組件的傳值方式詳解的文章就介紹到這了,更多相關(guān)Vue組件傳值內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Vue3項目實現(xiàn)前端導(dǎo)出Excel的示例代碼
這篇文章主要介紹了Vue3項目實現(xiàn)前端導(dǎo)出Excel的示例,在vue3的項目中導(dǎo)出Excel表格的功能,可以借助xlsx庫來實現(xiàn),下面是詳細的操作步驟,需要的朋友可以參考下2025-01-01
Vue中$emit調(diào)用父組件異步方法模擬.then實現(xiàn)方式
這篇文章主要介紹了Vue中$emit調(diào)用父組件異步方法模擬.then實現(xiàn)方式,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2024-09-09

