Rumah  >  Artikel  >  hujung hadapan web  >  Bagaimana untuk berkomunikasi antara komponen? Inventori kaedah komunikasi komponen Vue (bernilai dikumpulkan)

Bagaimana untuk berkomunikasi antara komponen? Inventori kaedah komunikasi komponen Vue (bernilai dikumpulkan)

青灯夜游
青灯夜游ke hadapan
2022-08-19 20:04:021403semak imbas

VueBagaimana untuk berkomunikasi antara komponen? Artikel ini mengambil kira 10 kaedah komunikasi komponen Vue2 dan Vue3 Saya harap ia akan membantu semua orang!

Bagaimana untuk berkomunikasi antara komponen? Inventori kaedah komunikasi komponen Vue (bernilai dikumpulkan)

Terdapat banyak cara untuk menyampaikan komponen dalam Vue, dan terdapat banyak perbezaan dalam pelaksanaan Vue2 dan Vue3 artikel ini akan menggunakan tiga kaedah: 选项式API 组合式API dan setup Kaedah pelaksanaan yang berbeza secara menyeluruh memperkenalkan kaedah komunikasi komponen Vue2 dan Vue3. Kaedah komunikasi yang akan dilaksanakan ditunjukkan dalam jadual di bawah. (Belajar perkongsian video: tutorial video vue)

方式 Vue2 Vue3
父传子 props props
子传父 $emit emits
父传子 $attrs attrs
子传父 $listeners 无(合并到 attrs方式)
父传子 provide provide
子传父 inject inject
子组件访问父组件 $parent
父组件访问子组件 $children
父组件访问子组件 $ref expose&ref
兄弟传值 EventBus mitt

props

props ialah salah satu kaedah komunikasi yang paling biasa digunakan dalam komunikasi komponen. Komponen induk dihantar melalui v-bind, dan komponen anak diterima melalui props Berikut ialah tiga kaedah pelaksanaannya

  • API Pilihan
//父组件

<template>
  <div>
    <Child :msg="parentMsg" />
  </div>
</template>
<script>
import Child from './Child'
export default {
  components:{
    Child
  },
  data() {
    return {
      parentMsg: '父组件信息'
    }
  }
}
</script>


//子组件

<template>
  <div>
    {{msg}}
  </div>
</template>
<script>
export default {
  props:['msg']
}
</script>
  • Gabungan Api
//父组件

<template>
  <div>
    <Child :msg="parentMsg" />
  </div>
</template>
<script>
import { ref,defineComponent } from 'vue'
import Child from './Child.vue'
export default defineComponent({
  components:{
    Child
  },
  setup() {
    const parentMsg = ref('父组件信息')
    return {
      parentMsg
    };
  },
});
</script>

//子组件

<template>
    <div>
        {{ parentMsg }}
    </div>
</template>
<script>
import { defineComponent,toRef } from "vue";
export default defineComponent({
    props: ["msg"],// 如果这行不写,下面就接收不到
    setup(props) {
        console.log(props.msg) //父组件信息
        let parentMsg = toRef(props, 'msg')
        return {
            parentMsg
        };
    },
});
</script>
  • susun sintaks gula
//父组件

<template>
  <div>
    <Child :msg="parentMsg" />
  </div>
</template>
<script setup>
import { ref } from 'vue'
import Child from './Child.vue'
const parentMsg = ref('父组件信息')
</script>

//子组件

<template>
    <div>
        {{ parentMsg }}
    </div>
</template>
<script setup>
import { toRef, defineProps } from "vue";
const props = defineProps(["msg"]);
console.log(props.msg) //父组件信息
let parentMsg = toRef(props, 'msg')
</script>

Perhatikan aliran data dalam

props Ia adalah item tunggal, iaitu komponen anak tidak boleh mengubah nilai yang diluluskan oleh komponen induk

Dalam gabungan API, jika anda ingin menggunakan pembolehubah lain dalam komponen anak untuk menerima nilai daripada prop, anda perlu menggunakan toRef untuk menukar sifat dalam props.

emit

Komponen anak boleh menerbitkan acara dan lulus beberapa parameter melalui emit, dan komponen induk memantau acara ini melalui v-on

  • API Pilihan
//父组件

<template>
  <div>
    <Child @sendMsg="getFromChild" />
  </div>
</template>
<script>
import Child from './Child'
export default {
  components:{
    Child
  },
  methods: {
    getFromChild(val) {
      console.log(val) //我是子组件数据
    }
  }
}
</script>

// 子组件

<template>
  <div>
    <button @click="sendFun">send</button>
  </div>
</template>
<script>
export default {
  methods:{
    sendFun(){
      this.$emit('sendMsg','我是子组件数据')
    }
  }
}
</script>
  • API Gabungan
//父组件

<template>
  <div>
    <Child @sendMsg="getFromChild" />
  </div>
</template>
<script>
import Child from './Child'
import { defineComponent } from "vue";
export default defineComponent({
  components: {
    Child
  },
  setup() {
    const getFromChild = (val) => {
      console.log(val) //我是子组件数据
    }
    return {
      getFromChild
    };
  },
});
</script>

//子组件

<template>
    <div>
        <button @click="sendFun">send</button>
    </div>
</template>

<script>
import { defineComponent } from "vue";
export default defineComponent({
    emits: ['sendMsg'],
    setup(props, ctx) {
        const sendFun = () => {
            ctx.emit('sendMsg', '我是子组件数据')
        }
        return {
            sendFun
        };
    },
});
</script>
  • sediakan gula sintaks
//父组件

<template>
  <div>
    <Child @sendMsg="getFromChild" />
  </div>
</template>
<script setup>
import Child from './Child'
const getFromChild = (val) => {
      console.log(val) //我是子组件数据
    }
</script>

//子组件

<template>
    <div>
        <button @click="sendFun">send</button>
    </div>
</template>
<script setup>
import { defineEmits } from "vue";
const emits = defineEmits(['sendMsg'])
const sendFun = () => {
    emits('sendMsg', '我是子组件数据')
}
</script>

attr dan pendengar

Komponen anak menggunakan $attrs untuk mendapatkan semua atribut komponen induk kecuali atribut yang diluluskan oleh props dan atribut mengikat atribut (kelas dan gaya).

Subkomponen menggunakan $pendengar untuk mendapatkan semua pendengar acara v-on bagi komponen induk (tidak termasuk .pengubah suai asli), yang tidak lagi digunakan dalam Vue3 tetapi attr dalam Vue3 bukan sahaja boleh mendapatkan komponen induk Sifat yang diluluskan juga boleh diperolehi daripada pendengar acara v-on komponen induk

  • API Pilihan
//父组件

<template>
  <div>
    <Child @parentFun="parentFun" :msg1="msg1" :msg2="msg2"  />
  </div>
</template>
<script>
import Child from './Child'
export default {
  components:{
    Child
  },
  data(){
    return {
      msg1:'子组件msg1',
      msg2:'子组件msg2'
    }
  },
  methods: {
    parentFun(val) {
      console.log(`父组件方法被调用,获得子组件传值:${val}`)
    }
  }
}
</script>

//子组件

<template>
  <div>
    <button @click="getParentFun">调用父组件方法</button>
  </div>
</template>
<script>
export default {
  methods:{
    getParentFun(){
      this.$listeners.parentFun('我是子组件数据')
    }
  },
  created(){
    //获取父组件中所有绑定属性
    console.log(this.$attrs)  //{"msg1": "子组件msg1","msg2": "子组件msg2"}
    //获取父组件中所有绑定方法    
    console.log(this.$listeners) //{parentFun:f}
  }
}
</script>
  • API Gabungan
//父组件

<template>
  <div>
    <Child @parentFun="parentFun" :msg1="msg1" :msg2="msg2" />
  </div>
</template>
<script>
import Child from './Child'
import { defineComponent,ref } from "vue";
export default defineComponent({
  components: {
    Child
  },
  setup() {
    const msg1 = ref('子组件msg1')
    const msg2 = ref('子组件msg2')
    const parentFun = (val) => {
      console.log(`父组件方法被调用,获得子组件传值:${val}`)
    }
    return {
      parentFun,
      msg1,
      msg2
    };
  },
});
</script>

//子组件

<template>
    <div>
        <button @click="getParentFun">调用父组件方法</button>
    </div>
</template>
<script>
import { defineComponent } from "vue";
export default defineComponent({
    emits: ['sendMsg'],
    setup(props, ctx) {
        //获取父组件方法和事件
        console.log(ctx.attrs) //Proxy {"msg1": "子组件msg1","msg2": "子组件msg2"}
        const getParentFun = () => {
            //调用父组件方法
            ctx.attrs.onParentFun('我是子组件数据')
        }
        return {
            getParentFun
        };
    },
});
</script>
  • sediakan gula sintaks
//父组件

<template>
  <div>
    <Child @parentFun="parentFun" :msg1="msg1" :msg2="msg2" />
  </div>
</template>
<script setup>
import Child from './Child'
import { ref } from "vue";
const msg1 = ref('子组件msg1')
const msg2 = ref('子组件msg2')
const parentFun = (val) => {
  console.log(`父组件方法被调用,获得子组件传值:${val}`)
}
</script>

//子组件

<template>
    <div>
        <button @click="getParentFun">调用父组件方法</button>
    </div>
</template>
<script setup>
import { useAttrs } from "vue";

const attrs = useAttrs()
//获取父组件方法和事件
console.log(attrs) //Proxy {"msg1": "子组件msg1","msg2": "子组件msg2"}
const getParentFun = () => {
    //调用父组件方法
    attrs.onParentFun('我是子组件数据')
}
</script>

Nota

Apabila menggunakan attrs untuk memanggil kaedah komponen induk dalam Vue3 , sebelum kaedah Anda perlu menambah pada; seperti parentFun->onParentFun

provide/inject

provide: ialah objek, atau fungsi yang mengembalikan objek. Ia mengandungi atribut yang akan diberikan kepada generasi akan datang

inject: tatasusunan rentetan atau objek. Dapatkan nilai yang disediakan oleh komponen induk atau komponen peringkat lebih tinggi, yang boleh diperolehi dalam mana-mana komponen turunan melalui suntikan

  • API Pilihan
//父组件
<script>
import Child from './Child'
export default {
  components: {
    Child
  },
  data() {
    return {
      msg1: '子组件msg1',
      msg2: '子组件msg2'
    }
  },
  provide() {
    return {
      msg1: this.msg1,
      msg2: this.msg2
    }
  }
}
</script>

//子组件

<script>
export default {
  inject:['msg1','msg2'],
  created(){
    //获取高层级提供的属性
    console.log(this.msg1) //子组件msg1
    console.log(this.msg2) //子组件msg2
  }
}
</script>
  • Gabungan API
//父组件

<script>
import Child from './Child'
import { ref, defineComponent,provide } from "vue";
export default defineComponent({
  components:{
    Child
  },
  setup() {
    const msg1 = ref('子组件msg1')
    const msg2 = ref('子组件msg2')
    provide("msg1", msg1)
    provide("msg2", msg2)
    return {
      
    }
  },
});
</script>

//子组件

<template>
    <div>
        <button @click="getParentFun">调用父组件方法</button>
    </div>
</template>
<script>
import { inject, defineComponent } from "vue";
export default defineComponent({
    setup() {
        console.log(inject('msg1').value) //子组件msg1
        console.log(inject('msg2').value) //子组件msg2
    },
});
</script>
  • menyediakan gula sintaks
//父组件
<script setup>
import Child from './Child'
import { ref,provide } from "vue";
const msg1 = ref('子组件msg1')
const msg2 = ref('子组件msg2')
provide("msg1",msg1)
provide("msg2",msg2)
</script>

//子组件

<script setup>
import { inject } from "vue";
console.log(inject('msg1').value) //子组件msg1
console.log(inject('msg2').value) //子组件msg2
</script>

penerangan

menyediakan/menyuntik umum Sesuai untuk digunakan dengan sarang komponen dalam. Ia biasanya digunakan dalam pembangunan komponen.

ibu bapa/anak

$parent: Komponen anak memperoleh tika Vue bagi komponen induk, dan boleh mendapatkan atribut dan kaedah komponen induk, dsb.

$children: Parent Komponen memperoleh tika Vue bagi subkomponen, yang merupakan tatasusunan dan koleksi anak langsung, tetapi susunan subkomponen tidak dijamin

  • Vue2
import Child from './Child'
export default {
  components: {
    Child
  },
  created(){
    console.log(this.$children) //[Child实例]
    console.log(this.$parent)//父组件实例
  }
}

Ambil perhatian bahawa yang diperolehi oleh $children komponen induk tidak responsif

expose&ref

$refs boleh terus mendapatkan atribut elemen dan contoh Komponen

  • API Pilihan
//父组件

<template>
  <div>
    <Child ref="child" />
  </div>
</template>
<script>
import Child from './Child'
export default {
  components: {
    Child
  },
  mounted(){
    //获取子组件属性
    console.log(this.$refs.child.msg) //子组件元素

    //调用子组件方法
    this.$refs.child.childFun('父组件信息')
  }
}
</script>

//子组件 

<template>
  <div>
    <div></div>
  </div>
</template>
<script>
export default {
  data(){
    return {
      msg:'子组件元素'
    }
  },
  methods:{
    childFun(val){
      console.log(`子组件方法被调用,值${val}`)
    }
  }
}
</script>
  • API Gabungan
  • <.>
//父组件

<template>
  <div>
    <Child ref="child" />
  </div>
</template>
<script>
import Child from './Child'
import { ref, defineComponent, onMounted } from "vue";
export default defineComponent({
  components: {
    Child
  },

  setup() {
    const child = ref() //注意命名需要和template中ref对应
    onMounted(() => {
      //获取子组件属性
      console.log(child.value.msg) //子组件元素

      //调用子组件方法
      child.value.childFun('父组件信息')
    })
    return {
      child //必须return出去 否则获取不到实例
    }
  },
});
</script>

//子组件

<template>
    <div>
    </div>
</template>
<script>
import { defineComponent, ref } from "vue";
export default defineComponent({
    setup() {
        const msg = ref('子组件元素')
        const childFun = (val) => {
            console.log(`子组件方法被调用,值${val}`)
        }
        return {
            msg,
            childFun
        }
    },
});
</script>
    susun sintaks gula
//父组件

<template>
  <div>
    <Child ref="child" />
  </div>
</template>
<script setup>
import Child from './Child'
import { ref, onMounted } from "vue";
const child = ref() //注意命名需要和template中ref对应
onMounted(() => {
  //获取子组件属性
  console.log(child.value.msg) //子组件元素

  //调用子组件方法
  child.value.childFun('父组件信息')
})
</script>

//子组件

<template>
    <div>
    </div>
</template>
<script setup>
import { ref,defineExpose } from "vue";
const msg = ref('子组件元素')
const childFun = (val) => {
    console.log(`子组件方法被调用,值${val}`)
}
//必须暴露出去父组件才会获取到
defineExpose({
    childFun,
    msg
})
</script>

Nota

Mendapatkan contoh subkomponen melalui ref mesti diperolehi selepas halaman dipasang.

Apabila menggunakan gula sintaks persediaan, komponen anak mesti mendedahkan elemen atau kaedah kepada komponen induk untuk mendapatkan

EventBus/mitt

adik beradik komunikasi komponen Ia boleh dilaksanakan melalui pusat acara EventBus, yang mencipta contoh Vue baharu untuk memantau, mencetus dan memusnahkan acara.

Tiada komunikasi komponen adik-beradik EventBus dalam Vue3, tetapi kini terdapat penyelesaian alternatif

Prinsipnya masih EventBusmitt.js

    API Pilihan
  • <.>
//组件1
<template>
  <div>
    <button @click="sendMsg">传值</button>
  </div>
</template>
<script>
import Bus from './bus.js'
export default {
  data(){
    return {
      msg:'子组件元素'
    }
  },
  methods:{
    sendMsg(){
      Bus.$emit('sendMsg','兄弟的值')
    }
  }
}
</script>

//组件2

<template>
  <div>
    组件2
  </div>
</template>
<script>
import Bus from './bus.js'
export default {
  created(){
   Bus.$on('sendMsg',(val)=>{
    console.log(val);//兄弟的值
   })
  }
}
</script>

//bus.js

import Vue from "vue"
export default new Vue()
API Gabungan
  • Mula-mula pasang sarung tangan

dan kemudian buat fail
npm i mitt -S
baharu

bus.js dalam Vue2 >mitt.jsmitt.js

import mitt from 'mitt'
const Mitt = mitt()
export default Mitt
sediakan gula sintaks
//组件1
<template>
     <button @click="sendMsg">传值</button>
</template>
<script>
import { defineComponent } from "vue";
import Mitt from './mitt.js'
export default defineComponent({
    setup() {
        const sendMsg = () => {
            Mitt.emit('sendMsg','兄弟的值')
        }
        return {
           sendMsg
        }
    },
});
</script>

//组件2
<template>
  <div>
    组件2
  </div>
</template>
<script>
import { defineComponent, onUnmounted } from "vue";
import Mitt from './mitt.js'
export default defineComponent({
  setup() {
    const getMsg = (val) => {
      console.log(val);//兄弟的值
    }
    Mitt.on('sendMsg', getMsg)
    onUnmounted(() => {
      //组件销毁 移除监听
      Mitt.off('sendMsg', getMsg)
    })

  },
});
</script>
ditulis pada penghujung
//组件1

<template>
    <button @click="sendMsg">传值</button>
</template>
<script setup>
import Mitt from './mitt.js'
const sendMsg = () => {
    Mitt.emit('sendMsg', '兄弟的值')
}
</script>

//组件2

<template>
  <div>
    组件2
  </div>
</template>
<script setup>
import { onUnmounted } from "vue";
import Mitt from './mitt.js'
const getMsg = (val) => {
  console.log(val);//兄弟的值
}
Mitt.on('sendMsg', getMsg)
onUnmounted(() => {
  //组件销毁 移除监听
  Mitt.off('sendMsg', getMsg)
})
</script>

Sebenarnya Komponen juga boleh berkomunikasi dengan alat pengurusan keadaan Vuex atau Pinia (tetapi ini biasanya tidak disyorkan untuk komunikasi antara komponen, kerana ini akan menyebabkan masalah bahawa komponen tidak boleh digunakan semula). Untuk penggunaan Vuex dan Pinia, anda boleh merujuk artikel ini Artikel menganalisis Pinia dan Vuex

(Mempelajari perkongsian video: Pembangunan bahagian hadapan web

,

Video pengaturcaraan asas )

Atas ialah kandungan terperinci Bagaimana untuk berkomunikasi antara komponen? Inventori kaedah komunikasi komponen Vue (bernilai dikumpulkan). Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan:
Artikel ini dikembalikan pada:juejin.cn. Jika ada pelanggaran, sila hubungi admin@php.cn Padam