Comunicação entre os componentes pai e filho em vue (demonstração e explicação do código)

1. Comunicação entre os componentes pai e filho

Os componentes filhos não podem fazer referência aos dados do componente pai ou à instância raiz do Vue.

No entanto, no desenvolvimento, alguns dados precisam ser passados ​​da camada superior para a inferior:

  • Por exemplo, em uma página, solicitamos muitos dados do servidor.
  • Parte dos dados não são exibidos pelos grandes componentes de nossa página inteira, mas pelos seguintes subcomponentes.
  • Neste momento, o componente filho não tem permissão para enviar uma solicitação de rede novamente, mas o componente grande (componente pai) é passado diretamente para o componente pequeno (componente filho).

Como se comunicar entre os componentes pai e filho?

  • Pai para filho: propstransmitindo dados para a submontagem
  • Transmissão pai-filho: $emitenviando o evento para o componente pai
    Insira a descrição da imagem aqui

2. De pai para filho

2.1 Usar adereços

Na submontagem, usando os propsdados recebidos da necessidade de declarar ao componente pai. Onde o componente pai usa o componente filho, use o método v-bind para passar os dados para o componente filho.

Existem duas formas de valorizar os adereços:

  • Método 1: array de strings, o string no array é o nome quando passado.
  • Método 2: Objeto, o objeto pode ser definido com o tipo quando é entregue ou pode ser definido com o valor padrão.

Peça emprestada a imagem do professor codificador por que mostrar o uso específico de adereços em detalhes:

Insira a descrição da imagem aqui

2.2 Demonstração do código

Você pode copiar o código diretamente para o seu computador para teste

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>6</title>
</head>
<body>

<div id="app">
  <cpn1></cpn1>
</div>

<template id="cpn1">
  <div>
    <h2>{
   
   {title}}</h2>
    <h2>我是父组件的内容</h2>
    <h2>-----------------</h2>
    <!-- 父组件传递数据给子组件 -->
    <!-- 使用v-bind语法才会将后边的 title 当做变量去父组件的data中寻找,
    如果没有使用 v-bind,title 就会当做字符串传递给 ctitle -->
    <cpn2 :ctitle="title" :cmovies="movies"></cpn2>
  </div>
</template>

<template id="cpn2">
  <div>
    <h2>{
   
   {ctitle}}</h2>
    <ul>
      <li v-for="item in cmovies">{
   
   {item}}</li>
    </ul>
  </div>
</template>

<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>

  // cpn1 是父组件,父组件中有 title 和 movies 数据
  // cpn2 是子组件,在子组件中定义 props ,
  // props中声明两个属性:ctitle 和 cmovies ,用来接收父组件传递的数据并使用

  Vue.component('cpn1', {
     
     
    template: '#cpn1',
    data() {
     
     
      return {
     
     
        title: '我是标题',
        movies: ['电影1', '电影2', '电影3']
      }
    },
    components: {
     
     
      cpn2: {
     
     
        template: '#cpn2',
        // props: ['ctitle', 'cmovies']
        props: {
     
     
          // ctitle:String,//对数据做一些类型限制
          // cmovies:Array
          ctitle: {
     
     
            type: String, //进行类型限制
            default: '我是默认值',//当父组件没有给子组件传递数据时,就会使用默认值
          },
          cmovies: {
     
     
            type: Array,
            //类型是对象和数组时,默认值必须是一个函数
            default(){
     
     
              return []
            }
          }
        }
      }
    }
  })

  let vm = new Vue({
     
     
    el: "#app",
    data: {
     
     }
  });
</script>

</body>
</html>

O resultado é mostrado na figura:
Insira a descrição da imagem aqui


3. Filho para Pai

3.1 Use $ emit

Quando o componente filho precisa passar dados para o componente pai, é necessário usar eventos personalizados.

O fluxo de eventos personalizados:

  • Em submontagens, $emit()acionando eventos.
  • No componente pai, v-onpara monitorar eventos do subcomponente. V-on pode ser usado não apenas para monitorar eventos DOM, mas também para personalizar eventos entre componentes.

3.2 Demonstração de código

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>8</title>
</head>
<body>

<!--父组件模板-->
<div id="app">
 <!--  此处不是浏览器产生的事件对象,是我们自定义的事件。当不加括号时,会默认传递子组件通过 $emit 发射事件时添加的数据-->
  <cpn @item-click="cpnClick"></cpn>
</div>

<!--子组件模板-->
<template id="cpn">
  <div>
    <!-- 在子组件中的按钮,同时监听点击事件 -->
    <button v-for="item in categories" @click="btnClick(item)">{
   
   {item.name}}</button>
  </div>
</template>

<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
  let cpn = {
     
     
    template: '#cpn',
    data(){
     
     
      return {
     
     
        categories:[
          {
     
     id:'1',name:'手机'},
          {
     
     id:'2',name:'电脑'},
          {
     
     id:'3',name:'书籍'},
          {
     
     id:'4',name:'家电'},
        ],
        data:'data',
        str:'str'
      }
    },
    methods:{
     
     
      btnClick(item){
     
     
        console.log(item);
        //子组件向父组件传递事件,第一个参数是自定义事件名,后边的参数是数据
        this.$emit('item-click',item,'hello')
      }
    }
  }
  let vm = new Vue({
     
     
    el: "#app",
    data: {
     
     },
    components: {
     
     
      cpn
    },
    methods:{
     
     
      cpnClick(data,str){
     
     
        console.log('----',data,str);
      }
    }

  });
</script>

</body>
</html>

Insira a descrição da imagem aqui


4. Assuntos que precisam de atenção

Evite modificar diretamente os dados em props por meio de subcomponentes , o que causará erros.

Motivo: a fonte de dados nos adereços do componente filho é o componente pai, ou seja, quando os dados relacionados no componente pai são alterados, os dados nos acessórios do componente filho também mudam. Se também modificarmos os dados em adereços no subcomponente neste momento, é equivalente a um dado que pode ser modificado em dois lugares, o que não é bom.

<div id="app">
  <cpn :number="num"></cpn>
</div>

<template id="cpn">
  <div>
    <h2>子组件props中的:{
   
   {number}}</h2>
    <!-- 我们通过 v-model 来尝试修改在子组件的 props 中声明的 number   -->
    <input type="text" v-model="number">
  </div>
</template>

<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>

  let cpn = {
     
     
    template: '#cpn',
    props: {
     
     
      number: Number,
    }
  }

  let vm = new Vue({
     
     
    el: "#app",
    data: {
     
     
      num: 1,
    },
    components: {
     
     
      cpn
    }
  });
</script>

Insira a descrição da imagem aqui
O código acima relatará um erro. Para evitar uma apresentação de informações de erro, modifique diretamente os dados nos adereços, mas podem ser dados ou propriedades de computação para alcançar o mesmo efeito no lugar da FIG.

Modificamos ligeiramente o código acima, adicionamos dados ao subcomponente e, ao mesmo tempo, alteramos o modelo v para vincular os dados aos dados

<div id="app">
  <cpn :number="num"></cpn>
</div>

<template id="cpn">
  <div>
    <h2>子组件props中的:{
   
   {number}}</h2>
    <!-- 我们通过 v-model 绑定到 data 中 dataNumber  -->
    <input type="text" v-model="dataNumber">
  </div>
</template>

<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>

  let cpn = {
     
     
    template: '#cpn',
    //加一个 data,数据来源是 props 中的数据
    data(){
     
     
      return {
     
     
        dataNumber:this.number
      }
    },
    props: {
     
     
      number: Number,
    }
  }

  let vm = new Vue({
     
     
    el: "#app",
    data: {
     
     
      num: 1,
    },
    components: {
     
     
      cpn
    }
  });
</script>

Acho que você gosta

Origin blog.csdn.net/weixin_43974265/article/details/112632738
Recomendado
Clasificación