八種vue實現組建通信的方式
一、組件通信
1、props 父組件—>子組件通信
- 父組件—屬性的方式傳值給子組件
- 子組件—props方式接收數據
<Son :datas="fData"></Son> <script> import Son from '@/components/son' export default{ name:'Father', components:{Son}, data(){ return{ fData:'我是父組件向子組件傳遞的值-props方式' } } } </script>
子組件props
接受的參數名稱,要與父組件傳遞時定義的屬性名一致
<template> <div>我是父組件的數據:{{fData}}</div> <div @click=changeData>我是父組件傳遞修改後的數據:{{mydata}}</div> </template> <script> export default{ name:'Son', props:{ fData:{ type:String, default:'' } } data(){ mydata:this.fatherData }, methods:{ changeData(){ this.mydata += '改變數據' } }, } </script>
註意:
- 子組件不能夠直接去修改父組件傳遞的值修改的:因為
Vue
的單向數據流機制,如果直接修改那父組件的值就被“污染”瞭。(props
是單向綁定的(隻讀屬性):當父組件的屬性變化時,將傳導給子組件,但是反過來不會)
報錯信息大概是:vue使用prop通信出錯:
Avoid mutating a prop directly since the value will be overwritten whenever the parent
- 解決方案:可以在子組件內定義一個變量mydata去接收fData數據
- 參數傳遞類型不確定是可以這麼寫:
props:{ fData:{ type:[String,Number], default:'' } }
2、$emit 子組件—>父組件傳遞
- 子組件綁定自定義事件
- $emit()第一個參數為:自定義的事件名稱,第二個參數為:需要傳遞的數據
- 使用 $emit() 觸發更改數據子組件
<el-button @click="handleEmit">改變父組件</el-button> <script> export default{ name:'Son', methods:{ handleEmit(){ this.$emit('triggerEmit','子組件的數據') } } } </script>
父組件(子組件發送的事件名稱,要和父組件接受的事件名稱一致)
<Son @triggerEmit="changeData"></Son> <script> import Son from '@/components/son' export default{ name:'Father', components:{Son}, methods:{ changeData(name){ console.log(name) // => 我是來自子組件的數據 } } } </script>
$emit與props結合 兄弟組件傳值
- 父組件引入兩個子組件
- 父組件充當一個橋梁作用父組件
<childA :myName="name"></ChildA> <ChildB :myName="name" @changeName="editName"></ChildB> export default{ data() { return { name: '數據你好' } }, methods: { editName(name){ this.name = name } } }
子組件B改變,接收數據
<p>姓名:{{ myName }}</p> <button @click="changeName">修改姓名</button> <script> export default{ props: { myName:String }, methods: { changeName() { this.$emit('changeName', '新數據名稱') } } } </script>
子組件A接收數據
<p>姓名:{{ newName }}</p> <script> export default{ props: { myName:String } } </script>
3、bus(事件總線) 兄弟組件通信
非父子組件或更多層級間組件間傳值,在Vue中通過單獨的事件中心來管理組件間的傳值
- 創建一個公共的bus.js文件
- 暴露出Vue實例
- 傳遞數據方,通過一個事件觸發bus.$emit(方法名,傳遞的數據)
- 接收數據方,在生命周期函數中,通過bus.$on(方法名,[params])來監聽
- 銷毀事件,在接受數據方,通過bus.$off(方法名)銷毀之後無法監聽數據
import Vue from "vue" const bus=new Vue() export default bus
需要改變數據的組件中定義調用
<template> <div> <div>我是通信組件A</div> <button @click="changeName">修改姓名</button> </div> </template> <script> import bus from "@/utils/Bus.js"; export default { components: {}, data() { return {}; }, mounted() { console.log(bus); }, methods: { changeName() { bus.$emit("editName", "數據集!"); }, }, }; </script> <style lang='scss' scoped> </style>
另外一個組件中同樣引入bus.js文件,通過$on監聽事件回調
<template> <div> <span>名稱:{{name}}</span> <div>我是通信組件B</div> </div> </template> <script> import bus from "@/utils/Bus.js"; export default { components: {}, data() { return {name}; }, mounted() { bus.$on("editName", (name) => { this.name=name console.log(name); // }); }, methods: {}, }; </script> <style lang='scss' scoped> </style>
4、$parent、$children 直接訪問組件實例
- 子組件通過—> $parent 獲得父組件實例
- 父組件通過—> $children 獲得子組件實例數組
子組件—this.$parent可以獲取到父組件的方法、data的數據等,並可以直接使用和執行
<template> <div>我是子組件</div> </template> <script> export default{ name:"Son", data(){ return{ sonTitle: '我是子組件的數據' } }, methods:{ sonHandle(){ console.log('我是子組件的方法') } }, created(){ console.log(this.$parent) console.log(this.$parent.fatherTitle) // => 我是父組件的數據 this.$parent.fantherHandle() // => 我是父組件的方法 } } </script>
父組件 — 獲取子組件實例的,並且獲取的實例是一個數組形式,this.$children[0]才可以獲取某個組件實例,並調用組件方法和數據
<template> <div> <Son>我是父組件</Son> </div> </template> <script> import Son from './son.vue' export default{ name: 'father', components:{ Son }, data(){ return{ fatherTitle: '我是父組件的數據' } }, methods:{ fantherHandle(){ console.log('我是父組件的方法') } }, mounted(){ console.log(this.$children) console.log(this.$children[0].sonTitle) // => 我是子組件的數據 this.$children[0].sonHandle() // => 我是子組件的方法 } } </script>
5、$refs
ref被用來給元素或子組件註冊引用信息。引用信息將會註冊在父組件的 $refs 對象上。
父組件使用 $refs 獲得組件實例
<template> <div> <Son ref="son"></Son> </div> </template> <script> import Son from './son.vue' export default{ name: 'father', components:{ Son }, mounted(){ console.log(this.$refs.son) /*組件實例*/ } } </script>
6、provide/inject(提供/註入) 多組件或深層次組件通信
provide/inject
詳解
- 父組件使用 provide 註入數據
- 子組件使用 inject 使用數據
/*父組件*/ export default{ provide: { return{ provideName: '販賣前端仔' } } }
至此provideName
這個變量可以提供給它其下的所有子組件,包括曾孫、孫子組件等,隻需要使用 inject 就能獲取數據
/*子組件*/ export default{ inject: ['provideName'], created () { console.log(this.provideName) // => "販賣前端仔" } }
- 父組件不需要知道哪個組件使用它提供出去的數據
- 子附件不需要知道這個數據從哪裡來
7、slot(slot-scope作用域插槽) 子元素–>父元素(類似於通信)
- 用作一個 (能被傳遞數據的)可重用模板,來代替已經渲染好的元素
- 在子組件中,隻需將數據傳遞到插槽,就像你將
prop
傳遞給組件一樣 - 註意:父級插槽接收內容是最外側元素 ,必須要有屬性
slot-scope
子元素
<template> <div> <div class="isSon"> <slot :info='arrList'></slot> </div> </div> </template> <script> export default { components: {}, data() { return {arrList:[1,'aa','張三']}; }, mounted() { }, methods: { }, }; </script>
父元素
<template> <div> <SonG> <span slot-scope="props"> <ul> aa <li v-for="item in props.info" :key="item"> {{item}} </li> </ul> </span> </SonG> </div> </template> <script> import SonG from '../components/SonG.vue' export default { components:{ SonG }, data () { return { } } } </script>
8、vuex狀態管理
- 相當於一個公共數據的倉庫
- 提供一些方法管理倉庫數據
import Vue from 'vue' import Vuex from 'vuex' Vue.use(Vuex) export default new Vuex.Store({ state: { }, mutations: { }, actions: { }, modules: { } })
到此這篇關於八種vue
實現組建通信的方式的文章就介紹到這瞭,更多相關vue
實現組建通信的方式內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!