Índice
- Resumo dos métodos de comunicação dos componentes vue3
-
- 1. adereços (de pai para filho)
- 2.emitir (de filho para pai)
- plug-in 3.mitt (barramento de evento global)
- 4.v-model (sincronização de dados do componente pai-filho)
- 5. useAttrs (pai e filho)
- 6.ref/$parent (comunicação do componente pai-filho)
- 7.provide/inject (comunicação entre componentes ancestrais e descendentes)
- 8. slot (comunicação do componente pai-filho)
- 9. pinia/vuex (comunicação de componente arbitrário)
Resumo dos métodos de comunicação dos componentes vue3
1. adereços (de pai para filho)
O componente pai passa valores para o componente filho, e o componente filho obtém os dados passados pelo componente pai através do defineProps.
componente pai
<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>
Submontagem
<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: a maneira de escrever em vue2
//props:['name'] //方式1
//props:{name:String} //方式2
props:{
//方式3
name:{
type:String, //类型
required:true, //必要性
default:'老王' //默认值
}
}
2.emitir (de filho para pai)
A passagem de filho para pai é realizada por meio de eventos personalizados, e eventos personalizados são acionados por meio de emissão em componentes filho.
componente pai
<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>
Submontagem
<template>
<button @click="handler">子传父</button>
</template>
<script setup lang="ts">
//利用defineEmits方法返回函数触发自定义事件
let emit = defineEmits(["xxx"]);
const handler = () => {
emit("xxx", "小", "心");
};
</script>
- Obs: A forma de escrever em vue2 é acionada diretamente através do objeto instância vue
this.$emit('xxx',数据);
plug-in 3.mitt (barramento de evento global)
O barramento de evento global pode realizar comunicação arbitrária de componentes. O eventBus foi removido no Vue 3, mas pode ser realizado usando o plug-in mitt.
Referência de uso da instalação do site oficial da luva
npm install --save mitt
Use
o método emit para distribuir eventos personalizados e o método on para vincular ouvintes de eventos personalizados.
- Nota: Escrito em vue2
new Vue({
......
beforeCreate() {
Vue.prototype.$bus = this //安装全局事件总线
},
......
})
this.$bus.$on('xxxx',this.demo) //需要接受数据的组件中给$bus绑定自定义事件
this.$bus.$emit('xxxx',数据) //另一个组件中提供数据
4.v-model (sincronização de dados do componente pai-filho)
v-model pode realizar ligação bidirecional de dados de formulário.
Além disso, o v-model também pode realizar a sincronização de dados do componente pai-filho, que é semelhante ao açúcar sintático de xxxx.sync no vue2.
Requisito: Clique no botão e os dados do componente pai-filho mudarão de forma síncrona.
- Método 1: Use props e emit para realizar a sincronização do componente pai-filho
Componente pai: passe os dados monetários para o componente filho e aceite os dados atualizados monetários passados pelo componente filho no evento customizado update:modelValue.
Componente filho: Aceite o dinheiro passado pelo componente pai por meio de props e acione um evento personalizado por meio de emissão para atualizar os dados do componente pai.
- Método 2: Use v-model para simplificar
A essência do v-model é realizada usando props[modelValue] e evento personalizado [update:modelValue]. É equivalente a passar um props[modelValue] para o componente filho Child e vincular um evento personalizado update:modelValue, que
pode ser visto por meio da ferramenta do desenvolvedor.
Ao mesmo tempo, várias sincronizações de dados entre os componentes pai e filho podem ser realizadas por usando vários modelos v.
<!-- 相当于给组件Child传递两个props分别是pageOne与pageTwo,以及绑定两个自定义事件update:pageOne与update:pageTwo实现父子数据同步 -->
<Child v-model:pageOne="msg1" v-model:pageTwo="msg2"></Child>
Suplemento: paginação em elementPlus também usa v-model.
- Observação: uso de .async em vue2
:money.async representa o componente pai para passar a string props[money] para o componente filho e vincular um evento personalizado (update:money) ao componente filho atual
<template>
<Money :money.sync="money"/>
<!--等价于 -->
<Money :money="money" @update:money="money=$event">
</template>
5. useAttrs (pai e filho)
No Vue3, você pode usar o método useAttrs para obter os atributos e eventos do componente pai (incluindo eventos DOM nativos e eventos personalizados). Semelhante aos props, ele pode aceitar propriedades e valores de propriedades passados por componentes pais.
Caso: Use o botão el para encapsular um componente para que ele tenha uma função de prompt. Componente pai Componente
filho Obtenha as propriedades e eventos do componente por meio de métodos. Além disso, o método de escrita pode ser usado em el-button , mas isso é muito complicado. Se o nome do atributo passado for consistente com o nome do atributo da tag vinculada, use a forma de: = "$attrs" diretamente.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>
- ponto importante:
Se defineProps aceitar um atributo, o objeto retornado pelo método useAttrs não possui o atributo correspondente e o valor do atributo. Aqui, o título foi aceito com props e o método useAttrs não pode obter o título.
- Nota: Escrito em Vue2: use
$attrs
atributos e$listeners
$attrs
É uma propriedade da instância do componente, que pode obter os dados props passados pelo componente pai; $listeners
é uma propriedade da instância do componente, que pode obter o evento personalizado passado pelo componente pai para o componente filho;
da mesma forma, se o propriedade recebida pelo componente filho por meio de props, na propriedade $attrs É inalcançável entre eles.
componente pai:
<template>
<ElButton type="success" icon="el-icon-delete" size="mini" title="按钮" @click="handler"/>
</template>
Submontagem
<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 (comunicação do componente pai-filho)
6.1 referência
ref é usado para registrar referências de elementos ou subcomponentes, ou seja, instâncias de elementos e subcomponentes DOM podem ser obtidas.
Em seguida, você pode passar o filho para o pai por meio de ref e usar os dados e métodos do componente filho no componente pai.
- 1. Ao utilizar a opção API, a referência será registrada no objeto this.$refs do componente:
<!-- 存储为 this.$refs.p -->
<p ref="p">hello</p>
- 2. Ao usar a API composta, a referência será armazenada no ref correspondente ao nome:
Se usado em um elemento DOM normal, a referência será o próprio elemento; se usado em um subcomponente, a referência será a instância do subcomponente.
- ponto importante:
Os componentes que usam a configuração do script em vue3 são fechados por padrão e não podem ser acessados externamente. Se você deseja que o componente pai obtenha os dados ou métodos do componente filho, é necessário especificar as propriedades que precisam ser expostas ao mundo externo por meio do defineExpose no componente filho.
Exemplo:
componente pai
componente filho
6.2 $pai
$parent pode obter a instância do componente pai do componente atual, portanto, os dados e métodos do componente pai podem ser obtidos no componente filho.
componente pai. Os dados e métodos do componente pai precisam ser expostos externamente através do 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>
Submontagem. Obtenha a instância do componente pai quando o botão dentro do componente filho for clicado.
<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 em vue2
O Vue2 também pode ser usado $children
para obter todas as instâncias de todos os subcomponentes do componente atual. Ele foi removido
no vue3 e substituído por $refs.$children
7.provide/inject (comunicação entre componentes ancestrais e descendentes)
O Vue3 fornece dois métodos fornecer e injetar, não importa quão profundo seja o nível, a API pode realizar a transferência de dados do componente pai para o componente descendente.
7.1 fornecer (fornecer)
provide é usado para fornecer valores que podem ser injetados por componentes descendentes.
componente pai
<script setup lang="ts">
import Child from "./Child.vue";
import {
ref, provide } from "vue";
let car = ref("小星星");
//祖先组件给后代组件提供数据
//第一个参数就是提供的数据key
//第二个参数是提供的数据
provide("TOKEN", star);
</script>
7.2 injetar (injeção)
Os componentes descendentes podem obter dados por meio do método de injeção e obter valores armazenados por meio da chave.
Submontagem
<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>
Observação: os componentes descendentes podem modificar o valor injetado e o valor fornecido pelo componente ancestral também será alterado.
Efeito
8. slot (comunicação do componente pai-filho)
Slots: divididos em slots padrão, slots nomeados e slots com escopo, que podem realizar comunicação de componente pai-filho.
8.1 Slots padrão
Use a tag de componente global do slot dentro do componente filho
<template>
<div>
<slot></slot>
</div>
</template>
<script setup lang="ts">
</script>
<style scoped>
</style>
componente pai. Todo é um subcomponente e a estrutura de escrita interna do rótulo duplo é passada para o subcomponente.
<Todo>
<h1>我是默认插槽填充的结构</h1>
</Todo>
8.2 Slots nomeados
Deixe vários slots nomeados dentro do componente com um nome
Componente filho com dois slots nomeados
<template>
<div>
<h1>todo</h1>
<slot name="a"></slot>
<slot name="b"></slot>
</div>
</template>
<script setup lang="ts">
</script>
<style scoped>
</style>
Componente pai
O componente pai passa internamente a estrutura para o slot nomeado especificado. Use v-slot: , que pode ser substituído por #.
<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 Slots com escopo
Slot de escopo: É um slot que pode transferir dados.O componente filho pode passar os dados para o componente pai , e o componente pai pode decidir qual estrutura ou aparência os dados retornados devem ser exibidos dentro do componente filho.
No exemplo a seguir, o componente pai passa os dados de todos para o componente filho, o componente filho aceita o valor do componente pai e envia os dados de volta ao componente pai por meio do slot de escopo, e o componente pai define o estilo para os dados.
componente pai
componente filho
Efeito
- Observação: o componente pai em vue2 obtém os dados do componente filho por meio do valor do atributo do escopo
<template scope="scopeData">
<ul>
<li v-for="g in scopeData.games" :key="g">{
{g}}</li>
</ul>
</template>
9. pinia/vuex (comunicação de componente arbitrário)
Vue3 pode usar Pinia e Vuex4 , dois contêineres de estado de gerenciamento centralizado, para obter comunicação arbitrária de componentes .
- Conceitos principais do Vuex: estado, mutações, ações, getters, módulos
- Conceitos principais do Pinia: estado, ações, getters. Não há mutações e módulos.
Referência de uso: site oficial Pinia , site oficial Vuex
- Observação: Vuex3 é usado em vue2 e Pinia também pode ser usado.