首頁  >  文章  >  web前端  >  vue3組件間怎麼通訊?通訊方式淺析

vue3組件間怎麼通訊?通訊方式淺析

青灯夜游
青灯夜游轉載
2023-04-21 19:53:461616瀏覽

在我們寫 vue3 的專案中,我們都會進行元件通信,我們除了使用 pinia 公共資料來源的方式除外,我們還可採用那些更簡單的API方法呢?那下面我就來跟大家介紹介紹幾種父子元件和子父元件通訊的方式。

vue3組件間怎麼通訊?通訊方式淺析

1、父子元件通訊

1.1 defineProps

父子元件通訊我們第一個想到的就是props,我們在子元件顯示宣告所接受的props,然後我們在從父元件傳入對應的key與value, 這樣我們就可以在子元件上接收到父元件傳過來的屬性與值。 【相關推薦:vuejs影片教學web前端開發

#具體實作如下:

// children.vue
<template>
  <ul class="list-group">
      <li class="list-group-item" v-for="item in list" :key="index">
        {{item}}
      </li>

  </ul>
</template>

<script setup>
import { defineProps } from &#39;vue&#39;;
const props = defineProps({
    list :{
        type: Array,
        default: () => {}
    }
})
</script>
// parent.vue
<template>
  <div class="parent-wrap">
      <input type="text" v-model="value" class="form-control" placeholder="请输入">
      <div class="input-group-append">
          <button class="btn btn-primary" @click="handleAdd">添加</button>
      </div>
  </div>
  <!-- child -->
  <childrenVue :list="list"></childrenVue>
</template>
<script setup>
import { ref } from &#39;vue&#39;;
import childrenVue from &#39;./children.vue&#39;;
const value = ref(&#39;&#39;)
const list = ref([&#39;javaScript&#39;, &#39;Html&#39;, &#39;CSS&#39;])
const handleAdd = () =>{
    list.value.push(value.value)
    value = &#39;&#39;
}
</script>

vue3組件間怎麼通訊?通訊方式淺析

如上圖所示,我們既實現了在子元件上顯示了父元件傳過來的list 數組,還使可以向list新增資料使子元件資料更新。

1.2 provide/inject

當我們聊完了props,我們第二個要介紹的就是 vue3 的一個組合式選項 provide 和inject。

projct用於提供可以被後代元件注入的值,而inject用於聲明要透過從上層提供方匹配並注入進當前元件的屬性。 其程式碼實作如下:

// children.vue
<template>
    <ul class="list-group">
        <li class="list-group-item" v-for="item in list" :key="item">{{item}}</li>
    </ul>
</template>
<script setup>
import { inject } from &#39;vue&#39;;
const list = inject(&#39;list&#39;)
</script>
// parent.vue
<template>
    <div class="parent-wrap">
        <input type="text" v-model="value" class="form-control" placeholder="请输入">
        <div class="input-group-append">
            <button class="btn btn-primary" @click="handleAdd">添加</button>
        </div>
    </div>
    <!-- child -->
    <childVue />
</template>
<script setup>
import childVue from "./child.vue";
const { ref, provide, readonly } = require("vue");
const value = ref(&#39;&#39;)
const list = ref([&#39;javaScript&#39;, &#39;HTML&#39;, &#39;CSS&#39;])
provide(&#39;list&#39;, readonly(list.value))
const handleAdd = () => {
list.value.push(value.value)
}
</script>

vue3組件間怎麼通訊?通訊方式淺析

如上圖所示,我們使用provide API向外提供了一個key 為list ,值為list.value,同時將list,value 設定成了唯讀屬性,防止子元件修改父元件的資料來源。然後我們 injectAPI接收了 list,實作了父子元件的通訊。

2.子父元件通訊

2.1 defineEmits

#上面我介紹了兩種父向子傳值的方法,但在我們開發中,我們還會遇到子向父元件傳值的情況,那我們該怎麼解決呢?第一個方法就是vue3中的defineEmits API,程式碼實作如下:

// children.vue
<template>
    <div class="parent-wrap">
        <input type="text" v-model="value" class="form-control" placeholder="请输入" />
        <div class="input-group-append">
            <button class="btn btn-primary" @click="handleAdd">添加</button>
        </div>
    </div>
</template>
<script setup>
const { ref, defineEmits } = require("vue");
const value = ref(&#39;&#39;)
const emits = defineEmits([&#39;add&#39;]) //父传子

  // 给父组件传一个函数
const handleAdd = () => {
    emits(&#39;add&#39;, value.value)
    value.value= &#39;&#39;
}
</script>
// parent.vue
<template>  
    <childVue @add=&#39;handleAdd&#39;/>
    <ul class="list-group">
        <li class="list-group-item" v-for="item in list" :key="item">{{item}}</li>
    </ul>
</template>
<script setup>
import { ref } from &#39;@vue/reactivity&#39;;
import childVue from &#39;./child.vue&#39;;
const list = ref([&#39;javaScript&#39;, &#39;HTML&#39;, &#39;CSS&#39;])
const handleAdd = (val) => {
    list.value.push(val)
}
</script>

vue3組件間怎麼通訊?通訊方式淺析

如上圖所示,我們在子元件上 emit一個出了一個add事件給父元件接收,同時在父元件上呼叫來執行新增的邏輯,再將inputvalue變成空,實作了父組件向子組件傳參。

2.2 v-model:xxx emit

在介紹完defineEmits後, 我們再來介紹一種與其有異曲同工之處的v-model:xxx emit的方法,實作如下:

// children.vue
<template>
    <div class="parent-wrap">
        <input type="text" v-model="value" class="form-control" placeholder="请输入" />
        <div class="input-group-append">
            <button class="btn btn-primary" @click="handleAdd">添加</button>
        </div>
    </div>
</template>
<script setup>
const { ref, defineProps, defineEmits } = require("vue");
const value = ref(&#39;&#39;)
const props = defineProps({
    list: {
        type: Array,
        default: () => []
    }
})
const emits = defineEmits([&#39;list&#39;])
  // 给父组件一点东西
const handleAdd = () => {
    // props.list.push(value.value)  //不建议直接修改props的值 把握不住数据源的流转
    const arr = props.list
    arr.push(value.value)
    emits(&#39;list&#39;, arr)
    value.value= &#39;&#39;
}

</script>
<template>  
    <childVue v-model:list="list" @list =&#39;add&#39;/>
    <ul class="list-group">
        <li class="list-group-item" v-for="item in list" :key="item">{{item}}</li>
    </ul>
</template>
<script setup>
import { ref } from &#39;@vue/reactivity&#39;;
import childVue from &#39;./child.vue&#39;;
const list = ref([&#39;javaScript&#39;, &#39;HTML&#39;, &#39;CSS&#39;])
const add =(val) => {
    console.log(val);
    console.log(list);
}
</script>

vue3組件間怎麼通訊?通訊方式淺析

再和上面的defineEmits方法比較完以後,相信大家也看出了這兩者的異曲同工在哪裡了。我們這裡是先將父元件的list傳給了子元件,再在子元件修改了父元件的資料來源,同時再emit還給父元件,實作了子組件向父組件傳值。

(學習影片分享:vuejs入門教學程式設計基礎影片

以上是vue3組件間怎麼通訊?通訊方式淺析的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文轉載於:juejin.cn。如有侵權,請聯絡admin@php.cn刪除