Resumen de los métodos de comunicación de los componentes de vue3

Resumen de los métodos de comunicación de los componentes de vue3

1. props (de padre a hijo)

El componente principal pasa valores al componente secundario y el componente secundario obtiene los datos pasados ​​por el componente principal a través de defineProps.
componente principal

<template>
   <Child info="小心" :money="money"></Child>
</template>

<script setup lang="ts">
import Child from "./Child.vue";
import {
    
     ref } from "vue";
let money = ref(10000);
</script>

Subensamblaje

<template>
   <p>{
    
    {
    
     info }}</p>
   <p>{
    
    {
    
     money }}</p>
</template>
<script setup lang="ts">
//使用defineProps方法接受父组件传递过来的数据
const props = defineProps(["info", "money"]); //数组写法
// const props = defineProps({  //对象写法
//   info: String,
//   money: Number,
// });
</script>
  • Nota: la forma de escribir en vue2
//props:['name'] 	//方式1
//props:{name:String}	//方式2
props:{
    
    	//方式3
	name:{
    
    
        type:String, //类型
      ​  required:true, //必要性default:'老王' //默认值
    }
}

2.emit (de hijo a padre)

El paso del elemento secundario al elemento principal se realiza a través de eventos personalizados, y los eventos personalizados se activan mediante la emisión en componentes secundarios.
componente padre

<template>
  <!-- 绑定自定义事件xxx:实现子组件给父组件传递数据 -->
  <Child @xxx="handler"></Child>
</template>
<script setup lang="ts">
import Child from "./Child.vue";
const handler = (param1: any, param2: any) => {
    
    
  console.log(param1, param2); //小,心
};
</script>

Subensamblaje

<template>
  <button @click="handler">子传父</button>
</template>
<script setup lang="ts">
//利用defineEmits方法返回函数触发自定义事件
let emit = defineEmits(["xxx"]);
const handler = () => {
    
    
  emit("xxx", "小", "心");
};
</script>
  • Nota: la forma de escribir en vue2 se activa directamente a través del objeto de instancia de vue
this.$emit('xxx',数据);

Complemento 3.mitt (bus de eventos global)

El bus de eventos global puede realizar la comunicación de componentes arbitrarios. El eventBus se elimina en Vue 3, pero se puede realizar utilizando el complemento mitt. Instalación del sitio web oficial del guante
de referencia de uso

npm install --save mitt

Utilice
inserte la descripción de la imagen aquí
el método emit para distribuir eventos personalizados y el método on para enlazar detectores de eventos personalizados.

  • Nota: Escrito en vue2
 new Vue({
    
    
    ......
    beforeCreate() {
    
    
        Vue.prototype.$bus = this //安装全局事件总线
    },
    ......
}) 
this.$bus.$on('xxxx',this.demo)	//需要接受数据的组件中给$bus绑定自定义事件
this.$bus.$emit('xxxx',数据)	//另一个组件中提供数据

4.v-model (sincronización de datos de componentes padre-hijo)

v-model puede realizar un enlace bidireccional de datos de formulario.
Además, v-model también puede realizar la sincronización de datos de componentes padre-hijo, que es similar al azúcar sintáctico de xxxx.sync en vue2.
Requisito: haga clic en el botón y los datos del componente padre-hijo cambiarán sincrónicamente.
inserte la descripción de la imagen aquí
inserte la descripción de la imagen aquí

  • Método 1: use accesorios y emita para realizar la sincronización de componentes padre-hijo

Componente principal: Pase los datos de dinero al componente secundario y acepte los datos de actualización de dinero pasados ​​por el componente secundario en el evento personalizado update:modelValue.
inserte la descripción de la imagen aquí
Componente secundario: acepte el dinero pasado por el componente principal a través de accesorios y active un evento personalizado a través de emit para actualizar los datos del componente principal.
inserte la descripción de la imagen aquí

  • Método 2: use el modelo v para simplificar

inserte la descripción de la imagen aquí
La esencia de v-model se realiza mediante el uso de accesorios [modelValue] y eventos personalizados [update: modelValue]. Es equivalente a pasar props[modelValue] al componente secundario Child y vincular un evento personalizado update:modelValue, que se
puede ver a través de la herramienta de desarrollo.
inserte la descripción de la imagen aquí
Al mismo tiempo, se puede realizar una sincronización de datos múltiple entre los componentes principal y secundario mediante usando múltiples modelos v.

<!-- 相当于给组件Child传递两个props分别是pageOne与pageTwo,以及绑定两个自定义事件update:pageOne与update:pageTwo实现父子数据同步 -->
<Child v-model:pageOne="msg1" v-model:pageTwo="msg2"></Child>

Suplemento: la paginación en elementPlus también usa v-model.inserte la descripción de la imagen aquí

  • Nota: uso de .async en vue2

:money.async representa el componente principal para pasar la cadena props[money] al componente secundario y vincular un evento personalizado al componente secundario actual (update:money)

<template>
    <Money :money.sync="money"/>
    <!--等价于 -->
    <Money :money="money" @update:money="money=$event">
</template>

5. useAttrs (padre e hijo)

En Vue3, puede usar el método useAttrs para obtener los atributos y eventos del componente principal (incluidos los eventos DOM nativos y los eventos personalizados). De forma similar a los accesorios, puede aceptar propiedades y valores de propiedad que pasan los componentes principales.
Caso: use el botón para encapsular un componente para que tenga una función de solicitud. Componente
principal Componente secundario Obtenga las propiedades y eventos del componente a través de métodos. Además, el método de escritura se puede usar en el-button , pero esto es demasiado engorroso. Si el nombre del atributo pasado es consistente con el nombre del atributo de la etiqueta enlazada, use la forma de: = "$attrs" directamente.inserte la descripción de la imagen aquí

useAttrs
type=”$attrs.type“ size="$attrs.size"......

<template>
  <div :title="title">
    <el-button :="$attrs"></el-button>
  </div>
</template>
<script setup lang="ts">
//引入useAttrs方法:获取组件标签身上属性与事件
import {
    
     useAttrs } from "vue";
let $attrs = useAttrs();
let props = defineProps(["title"]);
console.log($attrs);
</script>

inserte la descripción de la imagen aquí
inserte la descripción de la imagen aquí

  • punto importante:

Si defineProps acepta un atributo, el objeto devuelto por el método useAttrs no tiene el atributo ni el valor de atributo correspondientes. Aquí el título se ha aceptado con accesorios y el método useAttrs no puede obtener el título.
inserte la descripción de la imagen aquí
inserte la descripción de la imagen aquí

  • Nota: Escrito en Vue2: use $attrsatributos y$listeners

$attrsEs una propiedad de la instancia del componente, que puede hacer que el componente principal pase los datos de accesorios; $listenerses una propiedad de la instancia del componente, que puede hacer que el componente principal pase el evento personalizado al componente secundario;
de manera similar, si el propiedad recibida por el componente hijo a través de props, en la propiedad $attrs es inobtenible entre ellos.
componente principal:

<template>
    <ElButton type="success" icon="el-icon-delete" size="mini" title="按钮" @click="handler"/>
</template>

Subensamblaje

<template>
  <a :title="title">
      <el-button v-bind="$attrs" v-on="$listeners"></el-button>
  </a>
</template>
<script>
export default {
    
    
    props:['title'],
    mounted(){
    
    
        console.log(this.$attrs);
    }
}
</script>

6.ref/$parent (comunicación de componente padre-hijo)

referencia 6.1

ref se utiliza para registrar referencias de elementos o subcomponentes, es decir, se pueden obtener instancias de elementos y subcomponentes DOM.
Luego, puede pasar el elemento secundario al elemento principal a través de la referencia y usar los datos y métodos del componente secundario en el componente principal.

  • 1. Al utilizar la opción API, la referencia quedará registrada en el objeto this.$refs del componente:
<!-- 存储为 this.$refs.p -->
<p ref="p">hello</p>
  • 2. Al usar la API compuesta, la referencia se almacenará en la referencia que coincida con el nombre:

inserte la descripción de la imagen aquí
Si se usa en un elemento DOM normal, la referencia será el elemento mismo; si se usa en un subcomponente, la referencia será la instancia del subcomponente.

  • punto importante:

Los componentes que utilizan la configuración de secuencias de comandos en vue3 están cerrados de forma predeterminada y no se puede acceder a ellos desde el exterior. Si desea que el componente principal obtenga los datos o métodos del componente secundario, debe especificar las propiedades que deben exponerse al mundo exterior a través de defineExpose en el componente hijo.
Ejemplo:
componente padre
inserte la descripción de la imagen aquí
componente hijo
inserte la descripción de la imagen aquí

6.2 $padre

$parent puede obtener la instancia del componente principal del componente actual, por lo que los datos y métodos del componente principal se pueden obtener en el componente secundario.
componente padre. Los datos y métodos del componente principal deben exponerse externamente a través del método defineExpose

<template>
    <Child></Child>
</template>

<script setup lang="ts">
import Child from "./Child.vue";
import {
    
     ref } from "vue";
let yourMoney = ref(666);
let myMoney = ref(10);
defineExpose({
    
    
  yourMoney,
  myMoney,
});
</script>

Subensamblaje. Obtenga la instancia del componente principal cuando se haga clic en el botón dentro del componente secundario.

<template>
  <div class="dau">
    <button @click="handler($parent)">点击获取父组件实例</button>
  </div>
</template>
<script setup lang="ts">
const handler = ($parent) => {
    
    
  console.log($parent.yourMoney); //666
  console.log($parent.myMoney); //10
};
</script>
  • Nota: Escrito en vue2

Vue2 también se puede usar $childrenpara obtener todas las instancias de todos los subcomponentes del componente actual. Se eliminó
en vue3 y se reemplazó por $refs.$children

7.proporcionar/inyectar (comunicación entre los componentes ancestro y descendiente)

Vue3 proporciona dos métodos, proporcionar e inyectar, sin importar qué tan profundo sea el nivel, la API puede realizar la transferencia de datos del componente principal al componente descendiente.

7.1 proporcionar (proporcionar)

provide se usa para proporcionar valores que pueden ser inyectados por componentes descendientes.
inserte la descripción de la imagen aquí
componente padre

<script setup lang="ts">
import Child from "./Child.vue";
import {
    
     ref, provide } from "vue";
let car = ref("小星星");
//祖先组件给后代组件提供数据
//第一个参数就是提供的数据key
//第二个参数是提供的数据
provide("TOKEN", star);
</script>

7.2 inyectar (inyección)

Los componentes descendientes pueden obtener datos a través del método de inyección y obtener valores almacenados a través de la clave.
Subensamblaje

<template>
  <div class="child1">
    <h1>孙子组件</h1>
    <p>{
    
    {
    
     star }}</p>
    <button @click="updateCar">更新数据</button>
  </div>
</template>

<script setup lang="ts">
import {
    
     inject } from "vue";
//注入祖先组件提供数据
//需要参数:即为祖先提供数据的key
let star = inject("TOKEN");
console.log(star.value);	//小星星
//后代组件可以修改注入的值,祖先组件提供的值也会跟着变
const updateCar = () => {
    
    
  star.value = "摘下月亮";	
};
</script>
</script>

Nota: los componentes descendientes pueden modificar el valor inyectado, y el valor proporcionado por el componente antecesor también cambiará.
Efecto
inserte la descripción de la imagen aquí
inserte la descripción de la imagen aquí

8. ranura (comunicación de componente padre-hijo)

Ranuras: divididas en ranuras predeterminadas, ranuras con nombre y ranuras con ámbito, que pueden realizar la comunicación entre componentes padre-hijo.

8.1 Ranuras predeterminadas

Use la etiqueta del componente global de la ranura dentro del componente secundario

<template>
  <div>
    <slot></slot>
  </div>
</template>
<script setup lang="ts">
</script>
<style scoped>
</style>

componente padre. Todo es un subcomponente, y la estructura de escritura interna de la etiqueta doble se pasa al subcomponente.

<Todo>
  <h1>我是默认插槽填充的结构</h1>
</Todo>

8.2 Ranuras con nombre

Deje varias ranuras con nombre dentro del componente con un nombre
Componente secundario con dos ranuras con nombre

<template>
  <div>
    <h1>todo</h1>
    <slot name="a"></slot>
    <slot name="b"></slot>
  </div>
</template>
<script setup lang="ts">
</script>

<style scoped>
</style>

Componente principal
El componente principal pasa internamente la estructura a la ranura con nombre especificada. Use la ranura en V: , que se puede reemplazar con #.

<template>
  <div>
    <h1>slot</h1>
    <Todo>
      <template v-slot:a>  //可以用#a替换
        <div>填入组件A部分的结构</div>
      </template>
      <template #b>//可以用#b替换
        <div>填入组件B部分的结构</div>
      </template>
    </Todo>
  </div>
</template>

<script setup lang="ts">
import Todo from "./Todo.vue";
</script>
<style scoped>
</style>

8.3 Espacios delimitados

Ranura de alcance: es una ranura que puede transferir datos . El componente secundario puede pasar los datos al componente principal , y el componente principal puede decidir qué estructura o apariencia deben mostrarse los datos devueltos dentro del componente secundario.
En el siguiente ejemplo, el componente principal pasa los datos de todos al componente secundario, el componente secundario acepta el valor del componente principal y envía los datos de regreso al componente principal a través de la ranura de alcance, y el componente principal establece el estilo para los datos.
componente padre
inserte la descripción de la imagen aquí
componente hijo
inserte la descripción de la imagen aquí

Efecto
inserte la descripción de la imagen aquí

  • Nota: El componente principal en vue2 obtiene los datos del componente secundario a través del valor del atributo de alcance
<template scope="scopeData">
     <ul>
         <li v-for="g in scopeData.games" :key="g">{
   
   {g}}</li>
     </ul>
 </template>

9. pinia/vuex (comunicación de componentes arbitrarios)

Vue3 puede usar Pinia y Vuex4 , dos contenedores de estado de administración centralizados, para lograr la comunicación de componentes arbitrarios .

  • Conceptos básicos de Vuex: estado, mutaciones, acciones, getters, módulos
  • Conceptos básicos de Pinia: estado, acciones, captadores. No hay mutaciones y módulos.

Referencia de uso: sitio web oficial de Pinia , sitio web oficial de Vuex

  • Nota: Vuex3 se usa en vue2 y también se puede usar Pinia.

Supongo que te gusta

Origin blog.csdn.net/weixin_43288600/article/details/130765494
Recomendado
Clasificación