<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      【干貨】Vue3 組件通信方式詳解

      前言

      毫無疑問,組件通信是Vue中非常重要的技術之一,它的出現能夠使我們非常方便的在不同組件之間進行數據的傳遞,以達到數據交互的效果。所以,學習組件通信技術是非常有必要的,本文將總結Vue中關于組件通信的八種方式,幫助大家在使用Vue的過程中更加得心應手!

      如果文中有不對、疑惑的地方,歡迎在評論區留言指正!!

      一、什么是組件通信

      在開始之前我們需要明白什么是組件通信,組件通信可以拆分為兩個部分:

      • 組件
      • 通信

      都知道組件是vue最強大的功能之一,vue中每一個.vue文件我們都可以視之為一個組件,簡單來說組件就是對UI結構的復用。

      通信指的是發送者通過某種媒體以某種格式來傳遞信息到收信者以達到某個目的。廣義上,任何信息的交通都是通信。而組件間通信即指組件(.vue)通過某種方式來傳遞信息以達到某個目的,舉個栗子我們在使用UI框架中的table組件,可能會往table組件中傳入某些數據,這個本質就形成了組件之間的通信

      二、為什么要進行組件通信

      通信的本質是信息同步,共享。回到vue中,每個組件之間的都有獨自的作用域,組件間的數據是無法共享的但實際開發工作中我們常常需要讓組件之間共享數據,這也是組件通信的目的要讓它們互相之間能進行通訊,這樣才能實現數據間的交互,完成某種功能的開發。

      三、組件通信的分類

      組件間通信的分類可以分成以下

      • 父子組件之間的通信
      • 兄弟組件之間的通信
      • 祖孫與后代組件之間的通信
      • 非關系組件間之間的通信

      他們之間的關系如下圖:

      組件

      目前最常用是props/$emitvuex/pinia ,接下來是 provide/inject,其他不建議使用;
      實際項目中,簡單父子組件傳遞采用props/$emit ,涉及全局共享的數據一般采用 vuex/pinia 結合存儲對象localStorage/sessionStorage使用。

      Vue3 組件通信方式

      四、Vue3 的八種組件通信方式

      • props
      • $emit
      • expose / ref
      • $attrs
      • v-model
      • provide / inject
      • Vuex
      • mitt

      五、Vue3 八種通信方式用法講解

      1. props

      用 props 傳數據給子組件有兩種方法,如下

      方法一,setup() 方法寫法

      // Parent.vue 傳送
      <child :msg1="msg1" :msg2="msg2"></child>
      <script>
      import child from "./child.vue"
      import { ref, reactive } from "vue"
      export default {
          data(){
              return {
                  msg1:"這是傳級子組件的信息1"
              }
          },
          setup(){
              // 創建一個響應式數據
              
              // 寫法一 適用于基礎類型  ref 還有其他用處,下面章節有介紹
              const msg2 = ref("這是傳級子組件的信息2")
              
              // 寫法二 適用于復雜類型,如數組、對象
              const msg2 = reactive(["這是傳級子組件的信息2"])
              
              return {
                  msg2
              }
          }
      }
      </script>
      
      // Child.vue 接收
      <script>
      export default {
        props: ["msg1", "msg2"],// 如果這行不寫,下面就接收不到
        setup(props) {
          console.log(props) // { msg1:"這是傳給子組件的信息1", msg2:"這是傳給子組件的信息2" }
        },
      }
      </script>
      

      方法二,setup 語法糖

      // Parent.vue 傳送
      <child :msg2="msg2"></child>
      <script setup>
          import child from "./child.vue"
          import { ref, reactive } from "vue"
          const msg2 = ref("這是傳給子組件的信息2")
          // 或者復雜類型
          const msg2 = reactive(["這是傳級子組件的信息2"])
      </script>
      
      // Child.vue 接收
      <script setup>
          // 不需要引入 直接使用
          // import { defineProps } from "vue"
          const props = defineProps({
              // 寫法一
              msg2: String
              // 寫法二
              msg2:{
                  type:String,
                  default:""
              }
          })
          console.log(props) // { msg2:"這是傳級子組件的信息2" }
      </script>
      

      注意:

      如果父組件是setup(),子組件setup 語法糖寫法的話,是接收不到父組件里 data 的屬性,只能接收到父組件里 setup 函數里傳的屬性。

      如果父組件是setup 語法糖寫法,子組件setup()方法寫法,可以通過 props 接收到 data 和 setup 函數里的屬性,但是子組件要是在 setup 里接收,同樣只能接收到父組件中 setup 函數里的屬性,接收不到 data 里的屬性

      官方也說了,既然用了 3,就不要寫 2 了,所以不推薦setup()方法寫法。下面的例子,一律只用語法糖的寫法。

      2. $emit

      // Child.vue 派發
      <template>
          // 寫法一
          <button @click="emit('myClick')">按鈕</buttom>
          // 寫法二
          <button @click="handleClick">按鈕</buttom>
      </template>
      <script setup>
          
          // 方法一 適用于Vue3.2版本 不需要引入
          // import { defineEmits } from "vue"
          // 對應寫法一
          const emit = defineEmits(["myClick","myClick2"])
          // 對應寫法二
          const handleClick = ()=>{
              emit("myClick", "這是發送給父組件的信息")
          }
          
          // 方法二 不適用于 Vue3.2版本,該版本 useContext()已廢棄
          import { useContext } from "vue"
          const { emit } = useContext()
          const handleClick = ()=>{
              emit("myClick", "這是發送給父組件的信息")
          }
      </script>
      
      // Parent.vue 響應
      <template>
          <child @myClick="onMyClick"></child>
      </template>
      <script setup>
          import child from "./child.vue"
          const onMyClick = (msg) => {
              console.log(msg) // 這是父組件收到的信息
          }
      </script>
      

      3. expose / ref

      父組件獲取子組件的屬性或者調用子組件方法。

      // Child.vue
      <script setup>
          // 方法一 不適用于Vue3.2版本,該版本 useContext()已廢棄
          import { useContext } from "vue"
          const ctx = useContext()
          // 對外暴露屬性方法等都可以
          ctx.expose({
              childName: "這是子組件的屬性",
              someMethod(){
                  console.log("這是子組件的方法")
              }
          })
          
          // 方法二 適用于Vue3.2版本, 不需要引入
          // import { defineExpose } from "vue"
          defineExpose({
              childName: "這是子組件的屬性",
              someMethod(){
                  console.log("這是子組件的方法")
              }
          })
      </script>
      
      // Parent.vue  注意 ref="comp"
      <template>
          <child ref="comp"></child>
          <button @click="handlerClick">按鈕</button>
      </template>
      <script setup>
          import child from "./child.vue"
          import { ref } from "vue"
          const comp = ref(null)
          const handlerClick = () => {
              console.log(comp.value.childName) // 獲取子組件對外暴露的屬性
              comp.value.someMethod() // 調用子組件對外暴露的方法
          }
      </script>
      

      4. attrs

      attrs:包含父作用域里除 class 和 style 除外的非 props 屬性集合

      // Parent.vue 傳送
      <child :msg1="msg1" :msg2="msg2" title="3333"></child>
      <script setup>
          import child from "./child.vue"
          import { ref, reactive } from "vue"
          const msg1 = ref("1111")
          const msg2 = ref("2222")
      </script>
      
      // Child.vue 接收
      <script setup>
          import { defineProps, useContext, useAttrs } from "vue"
          // 3.2版本不需要引入 defineProps,直接用
          const props = defineProps({
              msg1: String
          })
          // 方法一 不適用于 Vue3.2版本,該版本 useContext()已廢棄
          const ctx = useContext()
          // 如果沒有用 props 接收 msg1 的話就是 { msg1: "1111", msg2:"2222", title: "3333" }
          console.log(ctx.attrs) // { msg2:"2222", title: "3333" }
          
          // 方法二 適用于 Vue3.2版本
          const attrs = useAttrs()
          console.log(attrs) // { msg2:"2222", title: "3333" }
      </script>
      

      5. v-model

      可以支持多個數據雙向綁定

      // Parent.vue
      <child v-model:key="key" v-model:value="value"></child>
      <script setup>
          import child from "./child.vue"
          import { ref, reactive } from "vue"
          const key = ref("1111")
          const value = ref("2222")
      </script>
      
      // Child.vue
      <template>
          <button @click="handlerClick">按鈕</button>
      </template>
      <script setup>
          
          // 方法一  不適用于 Vue3.2版本,該版本 useContext()已廢棄
          import { useContext } from "vue"
          const { emit } = useContext()
          
          // 方法二 適用于 Vue3.2版本,不需要引入
          // import { defineEmits } from "vue"
          const emit = defineEmits(["key","value"])
          
          // 用法
          const handlerClick = () => {
              emit("update:key", "新的key")
              emit("update:value", "新的value")
          }
      </script>
      

      6. provide / inject

      provide / inject 為依賴注入

      provide:可以讓我們指定想要提供給后代組件的數據或

      inject:在任何后代組件中接收想要添加在這個組件上的數據,不管組件嵌套多深都可以直接拿來用

      // Parent.vue
      <script setup>
          import { provide } from "vue"
          provide("name", "RDIF")
      </script>
      
      // Child.vue
      <script setup>
          import { inject } from "vue"
          const name = inject("name")
          console.log(name) // RDIF
      </script>
      

      7. Vuex

      // store/index.js
      import { createStore } from "vuex"
      export default createStore({
          state:{ count: 1 },
          getters:{
              getCount: state => state.count
          },
          mutations:{
              add(state){
                  state.count++
              }
          }
      })
      
      // main.js
      import { createApp } from "vue"
      import App from "./App.vue"
      import store from "./store"
      createApp(App).use(store).mount("#app")
      
      // Page.vue
      // 方法一 直接使用
      <template>
          <div>{{ $store.state.count }}</div>
          <button @click="$store.commit('add')">按鈕</button>
      </template>
      
      // 方法二 獲取
      <script setup>
          import { useStore, computed } from "vuex"
          const store = useStore()
          console.log(store.state.count) // 1
      
          const count = computed(()=>store.state.count) // 響應式,會隨著vuex數據改變而改變
          console.log(count) // 1 
      </script>
      

      8. mitt

      Vue3 中沒有了 EventBus 跨組件通信,但是現在有了一個替代的方案 mitt.js,原理還是 EventBus。

      先安裝 npm i mitt -S

      然后像以前封裝 bus 一樣,封裝一下

      mitt.js
      import mitt from 'mitt'
      const mitt = mitt()
      export default mitt
      

      然后兩個組件之間通信的使用

      // 組件 A
      <script setup>
      import mitt from './mitt'
      const handleClick = () => {
          mitt.emit('handleChange')
      }
      </script>
      
      // 組件 B 
      <script setup>
      import mitt from './mitt'
      import { onUnmounted } from 'vue'
      const someMethed = () => { ... }
      mitt.on('handleChange',someMethed)
      onUnmounted(()=>{
          mitt.off('handleChange',someMethed)
      })
      </script>
      

      六、參考資料

      vue.js: https://cn.vuejs.org/

      vuex是什么:https://vuex.vuejs.org/zh/

      工作中要使用Git,看這篇文章就夠了:http://www.guosisoft.com/article/detail/410508049313861

      企業數字化轉型如何做?看過來:http://www.guosisoft.com/article/detail/408745545576517

      Vue2.x 組件通信方式:http://www.guosisoft.com/article/detail/411234710110277

      【保姆級教程】Vue項目調試技巧:http://www.guosisoft.com/article/detail/430312211521605

      Vue 前端開發團隊風格指南(史上最全):http://www.guosisoft.com/article/detail/415491255230533

      國思RDIF低代碼快速開發平臺(支持vue2、vue3):http://www.guosisoft.com/article/detail/557095625134149

      七、結語

      如果本文對你有一點點幫助,點個贊支持一下吧,你的每一個【贊】都是我創作的最大動力 _

      更多技術文章請往:

      http://www.guosisoft.com/article

      http://www.rdiframework.net/article

      大家一起共同交流和進步呀!!

      posted @ 2024-06-26 10:43  .NET快速開發框架  閱讀(1321)  評論(0)    收藏  舉報
      主站蜘蛛池模板: 亚洲av成人在线一区| 日韩av一区二区三区不卡| 亚洲第一香蕉视频啪啪爽| 国产盗摄xxxx视频xxxx| 视频一区二区三区四区不卡| 天堂V亚洲国产V第一次| 国产系列丝袜熟女精品视频| 中文字幕人妻无码一夲道| 精品无码久久久久久尤物| 国产成人AV在线免播放观看新| 南充市| 蜜臀av久久国产午夜福利软件| 人妻激情另类乱人伦人妻| 国产熟女一区二区五月婷| 午夜射精日本三级| 丰满人妻一区二区三区色| 亚洲欧美自偷自拍视频图片| 亚洲avav天堂av在线网爱情| 午夜天堂一区人妻| 亚洲第一国产综合| 亚洲午夜理论无码电影| 忻州市| 一区二区三区午夜无码视频| 国产色无码专区在线观看| 日韩老熟女av搜索结果| 国产第一页浮力影院入口| 国产v综合v亚洲欧美久久| 亚洲欧美人成人让影院| 亚洲香蕉网久久综合影视| 欧美老熟妇又粗又大| 日韩精品人妻av一区二区三区| 免费高清特级毛片A片| 元氏县| 中文字幕人妻中文AV不卡专区| 欧美乱强伦xxxx孕妇| 欧美精品国产综合久久| 99久久精品国产一区二区| 亚洲精品无码高潮喷水A| 成人精品自拍视频免费看| 亚洲av日韩在线资源| 国内精品自线在拍|