元件通訊

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>
  • 注意:

    1. 子元件不能夠直接去修改父元件傳遞的值修改的:因為Vue的單向資料流機制,如果直接修改那父元件的值就被“汙染”了。(props是單向繫結的(只讀屬性):當父元件的屬性變化時,將傳導給子元件,但是反過來不會)

      報錯資訊大概是:vue使用prop通訊出錯:Avoid mutating a prop directly since the value will be overwritten whenever the parent

    2. 解決方案:可以在子元件內定義一個變數mydata去接收fData資料
    3. 引數傳遞型別不確定是可以這麼寫:
      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、vuex狀態管理

  • 相當於一個公共資料的倉庫
  • 提供一些方法管理倉庫資料
import Vue from 'vue'
import Vuex from 'vuex' Vue.use(Vuex) export default new Vuex.Store({
state: {
},
mutations: {
},
actions: {
},
modules: {
}
})

官網