vue 組件通信傳值

1. 父組件向子組件傳值

父組件通過 prop 給子組件下發(fā)數(shù)據(jù),子組件通過$emit觸發(fā)事件給父組件發(fā)送消息,即 prop 向下傳遞,事件向上傳遞。

  • 新建父組件文件
<template>
  <div>
     父組件:
    <input type="text" v-model="name">
    <!--引入子組件-->
    //這里傳的是一個變量值(可修改的,所以要使用v-bind屬性)
    <son :inputName="name"></son> 
  </div>
</template>

<script>
// 引入子組件
import son from './son'

export default {
  name: 'father',
  data () {
    return {
      name: '',  
    }
  },
  components: { //接收組件
    son
  }
}
</script>
  • 新建子組件文件
<template>
  <div>
    子組件:
    <span>{{inputName}}</span> //接收父組件傳過來的值
  </div>
</template>

<script>
export default {
  name: 'son',
  data () {
    return {}
  },
  // 接受父組件的值
  props: {
    inputName: String, //聲明的類型
    required: true
  }
}
</script>
image.png

另一種(在封裝組件里傳值)父組件向子組件傳值

局部封裝


image.png
image.png

‘a’是字符串數(shù)組

2. 子組件向父組件傳值

vue是禁止子組件直接向父組件傳值的,所以只能通過$emit觸發(fā)事件來達到目的。

  • 新建子組件文件
<template>
  <div>
    子組件:
    <span>{{sonValue}}</span> 
    <!-- 定義一個子組件傳值的方法 -->
    <button @click="sonClick">點擊觸發(fā)</button> //綁定一個點擊事件
  </div>
</template>

<script>
export default {
  name: 'son',
  data () {
    return {
      sonValue: '我是子組件的數(shù)據(jù)'
    }
  },
  methods: {
    sonClick () {
      // sonByValue是在父組件on監(jiān)聽的方法
      // 第二個參數(shù)this.sonValue是需要傳給父組件的值,就是return中的值
      this.$emit('sonByValue', this.sonValue)
    }
  }
}
</script>
  • 新建父組件文件
<template>
  <div>
    父組件:
    <span>{{name}}</span>  
    <!-- 引入子組件 定義一個on的方法監(jiān)聽子組件的狀態(tài)-->
    //@sonByValue是接收子組件的事件名稱,需要和子組件保持一致
    <son @sonByValue="outSon"></son>  //outSon自定義名稱方法
  </div>
</template>

<script>
import son from './son'

export default {
  name: 'father',
  data () {
    return {
      name: ''
    }
  },
  methods: {
    // sonValue就是子組件傳過來的值
    outSon(sonValue) {
      // 把子組件里傳過來的值賦值給this.name,當點擊觸發(fā)方法時,就把值傳過來了并顯示在頁面上了
      this.name = sonValue 
    }
  },
  components: {
    son
  }
}
</script>
image.png

3.非父子組件傳值(兄弟組件傳值)

需要新建一個公共的公共實例文件bus.js,作為中間倉庫來傳值

  • 1.在src目錄下新建一個bus.js文件
import Vue from 'vue'
export default new Vue()
  • 2.新建組件A
<template>
  <div id="emit">
    A組件:
    <span>{{elementValue}}</span>
    <button @click="elementByValue">點擊觸發(fā)</button>
  </div>
</template>

<script>
// 引入公共的bug,來做為中間傳達的工具
import Bus from './bus.js'

export default {
  name: 'componentA',
  data () {
    return {
      elementValue: '我要給兄弟組件傳值啦'
    }
  },
  methods: {
    elementByValue () {
     // 用$emit來觸發(fā)
      Bus.$emit('val', this.elementValue)
      // console.log(this.elementValue)
    }
  }
}
</script>
  • 新建組件B
<template>
  <div>
    B組件:
    <!--<button @click="getBata">點擊觸發(fā)</button>-->
    <span>{{name}}</span>
  </div>
</template>

<script>
// 引入公共的bug,來做為中間傳達的工具
import Bus from './bus.js'

export default {
  name: 'componentB',
  data () {
    return {
      name: ''
    }
  },
  mounted () {
    var vm = this
    // 用$on來接收
    Bus.$on('val', (data) => {
      console.log(data)
      vm.name = data
    })
  }
  // methods: {
  //   getBata () {
  //     this.name++
  //   }
  // }
}
</script>

4. 袓孫隔代傳值

當一個模板里嵌套了很多層時,如:組先、兒子、孫子、曾孫等,你要從最里層曾孫組件里去訪問最外層袓先的數(shù)據(jù),如果你要一層一層的去傳值的話,那這會非常麻煩,并且數(shù)據(jù)容易出錯。這時就需要用到provide 和inject方法,它們倆需要一起使用,以允許一個祖先組件向其所有子孫后代注入一個依賴,不論組件層次有多深,并在起上下游關系成立的時間里始終生效。

不推薦直接用于應用程序代碼中。一般使用的場景是自定義組件庫的時候,底層組件之間需要通信的時候使用。

  • provide: 一個對象或返回一個對象的函數(shù)

  • inject:一個字符串數(shù)組,或 一個對象,對象的 key 是本地的綁定名

    1. 新建袓先級組件
<template>
  <div>
    <span>祖先級組件:parent</span>
    <input type="text" v-model="toGdata.name">
    <div>
      <dadC></dadC> // 定義父組件
    </div>
  </div>
</template>

<script>
// 引入父組件
import dadC from './dadC'

export default {
  name: 'parent',
  data () {
    return {
      toGdata: {name: '李三'} // 存放數(shù)據(jù)
    }
  },
  // import引入的組件需要注入到對象中才能使用
  components: {
    dadC
  },
  // 注入數(shù)據(jù)
  provide () {
    return {
      toGdata: this.toGdata
    }
  }
}
</script>
    1. 新建兒子級組件
<template>
  <div>
    <span>兒子級組件C:dadC</span>
    <div>
      <grandSon></grandSon>  // 定義孫子組件
    </div>
  </div>
</template>

<script>
// 引入孫子組件
import grandSon from './grandSon'

export default {
  name: 'dadC',
  data () {
    return {}
  },
  // import引入的組件需要注入到對象中才能使用
  components: {
    grandSon
  }
}
</script>
    1. 新建孫子級組件
<template>
  <div>
    <span>孫子級組件G:grandSon</span>
    <div>
      接受來自袓父級組件parent的數(shù)據(jù)【toGdata】:{{toGdata}}
      <input type="text" v-model="fromParentData.name">
    </div>
  </div>
</template>

<script>
export default {
  name: 'grandSon',
  data () {
    return {
      fromParentData: this.toGdata
    }
  },
  // 接受袓先級傳過來的數(shù)據(jù)
  inject: ['toGdata'],
  components: {}
}
</script>

注意:這里不論子組件嵌套有多深, 只要調用了 inject 那么就可以注入 provide 中的數(shù)據(jù),而不局限于只能從當前父組件的props屬性中回去數(shù)據(jù)

image.png

總結:
在簡單的功能模塊,可以通過傳遞對象實現(xiàn)跨級組件通信,復雜的功能模塊不建議使用,因為傳遞的數(shù)據(jù),如果其他的兒子級組件,其他兒子級組件的孫子級組件也在使用的話,會造成數(shù)據(jù)的混亂,甚至無法理解數(shù)據(jù)是在哪里變化的,排查故障艱難。
跨級組件通信可以定義一個中央事件總線(eventBus),但是更復雜的系統(tǒng),還是建議使用vuex。

參考以下資料:
https://blog.csdn.net/weihaifeng163/article/details/88338822
https://www.cnblogs.com/pangchunlei/p/12112318.html

?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

  • 1.父子通信 1.父組件(parent.vue) 子組件(child.vue) 2.子父通信 1.子組件(chil...
    星星藏進黑夜閱讀 449評論 0 2
  • 前言 組件是 vue.js最強大的功能之一,而組件實例的作用域是相互獨立的,這就意味著不同組件之間的數(shù)據(jù)無法相互引...
    用技術改變世界閱讀 2,304評論 1 3
  • Vue的組件化給前端開發(fā)帶來極大的便利,這種依賴數(shù)據(jù)來控制Dom的模式,區(qū)別于以前的開發(fā)控制Dom的開發(fā)理念,這也...
    Max_Law閱讀 1,194評論 0 3
  • 前言 vue的核心就是組件的使用,組件是可復用的vue實例。如果項目中某一個部分需要在多個頁面中使用到,我們就可以...
    Oct13_JJP閱讀 858評論 0 20
  • 前言 vue的核心就是組件的使用,組件是可復用的vue實例。如果項目中某一個部分需要在多個頁面中使用到,我們就可以...
    Wo信你個鬼閱讀 1,275評論 0 0

友情鏈接更多精彩內容