Maison > interface Web > Voir.js > Explication détaillée des 8 méthodes de communication des composants Vue, venez la récupérer !

Explication détaillée des 8 méthodes de communication des composants Vue, venez la récupérer !

青灯夜游
Libérer: 2022-05-17 09:50:52
avant
3434 Les gens l'ont consulté

Cet article vous donnera une compréhension détaillée des 8 méthodes de communication composantes de vue. Il a une certaine valeur de référence. Les amis dans le besoin peuvent s'y référer. J'espère qu'il sera utile à tout le monde.

Explication détaillée des 8 méthodes de communication des composants Vue, venez la récupérer !

vue est un framework pour les mises à jour de vues basées sur les données, donc la communication de données entre les composants est très importante pour vue, alors comment la communication de données se produit-elle entre les composants ?

Tout d'abord, nous devons savoir quel type de relation existe entre les composants en vue, afin qu'il soit plus facile de comprendre leur méthode de communication. C'est comme rentrer à la maison pendant le Nouvel An et s'asseoir. une pièce remplie d'étrangers qui se parlent. Comment les appelez-vous ? À ce moment-là, vous devez d'abord savoir quel type de relation vous entretenez avec eux. (Partage vidéo d'apprentissage : tutoriel vidéo vue)

Description de la relation dans les composants vue :

Explication détaillée des 8 méthodes de communication des composants Vue, venez la récupérer !

Comme indiqué ci-dessus Comme indiqué, la relation entre les composants A et B, A et C, B et D, C et E est la relation père-enfant ; la relation entre B et C est la relation entre A et D, A et E ; est la relation générationnelle ; la relation entre D et E est une relation de cousin (parent non direct)
Nous classons les relations ci-dessus comme :

  • Communication entre les composants parent et enfant
  • Communication entre les composants non parents et enfants (composants frères et sœurs, composants de relations intergénérationnelles, etc.)

Cet article présentera 8 modes de communication entre les composants comme indiqué dans la table des matières ci-dessous : et présentez comment choisir des moyens efficaces de mettre en œuvre la communication entre les composants dans différents scénarios. J'espère que cela pourra aider les amis à mieux comprendre la communication entre les composants.

Explication détaillée des 8 méthodes de communication des composants Vue, venez la récupérer !

1. props / $emit


Le composant parent transmet la méthode props au composant enfant Transmettez les données et les composants enfants peuvent communiquer avec les composants parents via $emit.

1. Le composant parent transmet la valeur au composant enfant

Ce qui suit utilise un exemple pour illustrer comment le composant parent transmet les données au composant enfant : dans l'enfant composant article.vue Comment obtenir les données dans le composant parent section.vuearticles:['红楼梦', '西游记','三国演义']

// section父组件
<template>
  <div class="section">
    <com-article :articles="articleList"></com-article>
  </div>
</template>

<script>
import comArticle from &#39;./test/article.vue&#39;
export default {
  name: &#39;HelloWorld&#39;,
  components: { comArticle },
  data() {
    return {
      articleList: [&#39;红楼梦&#39;, &#39;西游记&#39;, &#39;三国演义&#39;]
    }
  }
}
</script>
Copier après la connexion
// 子组件 article.vue
<template>
  <div>
    <span v-for="(item, index) in articles" :key="index">{{item}}</span>
  </div>
</template>

<script>
export default {
  props: [&#39;articles&#39;]
}
</script>
Copier après la connexion
Résumé : les accessoires ne peuvent être transmis que du composant de niveau supérieur au composant de niveau inférieur (composant parent-enfant ), c'est ce qu'on appelle le flux de données unidirectionnel. De plus, prop est en lecture seule et ne peut pas être modifié. Toutes les modifications seront invalides et un avertissement sera émis.

2. Le composant enfant transmet la valeur au composant parent

Pour $emit, ma propre compréhension est la suivante : $emitLier un événement personnalisé, lorsque Lorsque cette instruction est exécuté, le paramètre arg sera transmis au composant parent, et le composant parent écoute et reçoit les paramètres via v-on. À travers un exemple, expliquez comment un composant enfant transmet des données à un composant parent.
Sur la base de l'exemple précédent, cliquez sur le ariticle du item rendu par la page, et l'indice

// 父组件中
<template>
  <div class="section">
    <com-article :articles="articleList" @onEmitIndex="onEmitIndex"></com-article>
    <p>{{currentIndex}}</p>
  </div>
</template>

<script>
import comArticle from &#39;./test/article.vue&#39;
export default {
  name: &#39;HelloWorld&#39;,
  components: { comArticle },
  data() {
    return {
      currentIndex: -1,
      articleList: [&#39;红楼梦&#39;, &#39;西游记&#39;, &#39;三国演义&#39;]
    }
  },
  methods: {
    onEmitIndex(idx) {
      this.currentIndex = idx
    }
  }
}
</script>
Copier après la connexion
<template>
  <div>
    <div v-for="(item, index) in articles" :key="index" @click="emitIndex(index)">{{item}}</div>
  </div>
</template>

<script>
export default {
  props: [&#39;articles&#39;],
  methods: {
    emitIndex(index) {
      this.$emit(&#39;onEmitIndex&#39;, index)
    }
  }
}
</script>
Copier après la connexion

affiché dans le tableau du composant parent 2. $children / $parent


Explication détaillée des 8 méthodes de communication des composants Vue, venez la récupérer !

L'image ci-dessus est l'explication officielle de vue , vous pouvez accéder à l'instance du composant via $parent et $children Que signifie obtenir l'instance ? Délégue l'accès à toutes les méthodes et data de ce composant. L'étape suivante consiste à savoir comment obtenir l'instance du composant spécifié.

L'utilisation de la méthode

// 父组件中
<template>
  <div class="hello_world">
    <div>{{msg}}</div>
    <com-a></com-a>
    <button @click="changeA">点击改变子组件值</button>
  </div>
</template>

<script>
import ComA from &#39;./test/comA.vue&#39;
export default {
  name: &#39;HelloWorld&#39;,
  components: { ComA },
  data() {
    return {
      msg: &#39;Welcome&#39;
    }
  },

  methods: {
    changeA() {
      // 获取到子组件A
      this.$children[0].messageA = &#39;this is new value&#39;
    }
  }
}
</script>
Copier après la connexion
rrree
doit faire attention aux conditions aux limites. Par exemple, si vous prenez #app sur $parent, vous obtiendrez une instance de <. 🎜>. Ensuite, utilisez à nouveau cette instance. Si vous prenez new Vue(), vous obtiendrez $parent, et si vous prenez undefined au sous-composant inférieur, ce sera un tableau vide. Notez également que les valeurs de $children et $parent sont différentes. La valeur de $children est un tableau, tandis que $children est un objet $parent
Résumé

Le. ci-dessus, deux méthodes sont utilisées pour la communication entre les composants parent et enfant, tandis que l'utilisation d'accessoires pour la communication entre composants parent-enfant est plus courante ;

3. / provideinject


Concept :

/ provide est la nouvelle API de inject En termes simples, les variables sont fournies via vue2.2.0 dans le composant parent, puis les variables sont injectées via provide dans le composant enfant. inject

注意: 这里不论子组件嵌套有多深, 只要调用了inject 那么就可以注入provide中的数据,而不局限于只能从当前父组件的props属性中回去数据

举例验证

接下来就用一个例子来验证上面的描述:
假设有三个组件: A.vue、B.vue、C.vue 其中 C是B的子组件,B是A的子组件

// A.vue

<template>
  <div>
    <comB></comB>
  </div>
</template>

<script>
  import comB from &#39;../components/test/comB.vue&#39;
  export default {
    name: "A",
    provide: {
      for: "demo"
    },
    components:{
      comB
    }
  }
</script>
Copier après la connexion
// B.vue

<template>
  <div>
    {{demo}}
    <comC></comC>
  </div>
</template>

<script>
  import comC from &#39;../components/test/comC.vue&#39;
  export default {
    name: "B",
    inject: [&#39;for&#39;],
    data() {
      return {
        demo: this.for
      }
    },
    components: {
      comC
    }
  }
</script>
Copier après la connexion
// C.vue
<template>
  <div>
    {{demo}}
  </div>
</template>

<script>
  export default {
    name: "C",
    inject: [&#39;for&#39;],
    data() {
      return {
        demo: this.for
      }
    }
  }
</script>
Copier après la connexion

四、ref / refs


ref:如果在普通的 DOM 元素上使用,引用指向的就是 DOM 元素;如果用在子组件上,引用就指向组件实例,可以通过实例直接调用组件的方法或访问数据, 我们看一个ref 来访问组件的例子:

// 子组件 A.vue

export default {
  data () {
    return {
      name: &#39;Vue.js&#39;
    }
  },
  methods: {
    sayHello () {
      console.log(&#39;hello&#39;)
    }
  }
}
Copier après la connexion
// 父组件 app.vue

<template>
  <component-a ref="comA"></component-a>
</template>
<script>
  export default {
    mounted () {
      const comA = this.$refs.comA;
      console.log(comA.name);  // Vue.js
      comA.sayHello();  // hello
    }
  }
</script>
Copier après la connexion

五、eventBus


eventBus 又称为事件总线,在vue中可以使用它来作为沟通桥梁的概念, 就像是所有组件共用相同的事件中心,可以向该中心注册发送事件或接收事件, 所以组件都可以通知其他组件。

eventBus也有不方便之处, 当项目较大,就容易造成难以维护的灾难

在Vue的项目中怎么使用eventBus来实现组件之间的数据通信呢?具体通过下面几个步骤

1. 初始化

首先需要创建一个事件总线并将其导出, 以便其他模块可以使用或者监听它.

// event-bus.js

import Vue from &#39;vue&#39;
export const EventBus = new Vue()
Copier après la connexion

2. 发送事件

假设你有两个组件: additionNumshowNum, 这两个组件可以是兄弟组件也可以是父子组件;这里我们以兄弟组件为例:

<template>
  <div>
    <show-num-com></show-num-com>
    <addition-num-com></addition-num-com>
  </div>
</template>

<script>
import showNumCom from &#39;./showNum.vue&#39;
import additionNumCom from &#39;./additionNum.vue&#39;
export default {
  components: { showNumCom, additionNumCom }
}
</script>
Copier après la connexion
// addtionNum.vue 中发送事件

<template>
  <div>
    <button @click="additionHandle">+加法器</button>    
  </div>
</template>

<script>
import {EventBus} from &#39;./event-bus.js&#39;
console.log(EventBus)
export default {
  data(){
    return{
      num:1
    }
  },

  methods:{
    additionHandle(){
      EventBus.$emit(&#39;addition&#39;, {
        num:this.num++
      })
    }
  }
}
</script>
Copier après la connexion

3. 接收事件

// showNum.vue 中接收事件

<template>
  <div>计算和: {{count}}</div>
</template>

<script>
import { EventBus } from &#39;./event-bus.js&#39;
export default {
  data() {
    return {
      count: 0
    }
  },

  mounted() {
    EventBus.$on(&#39;addition&#39;, param => {
      this.count = this.count + param.num;
    })
  }
}
</script>
Copier après la connexion

这样就实现了在组件addtionNum.vue中点击相加按钮, 在showNum.vue中利用传递来的 num 展示求和的结果.

4. 移除事件监听者

如果想移除事件的监听, 可以像下面这样操作:

import { eventBus } from &#39;event-bus.js&#39;
EventBus.$off(&#39;addition&#39;, {})
Copier après la connexion

六、Vuex


1. Vuex介绍

Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化.
Vuex 解决了多个视图依赖于同一状态来自不同视图的行为需要变更同一状态的问题,将开发者的精力聚焦于数据的更新而不是数据在组件之间的传递上

2. Vuex各个模块

  • state:用于数据的存储,是store中的唯一数据源

  • getters:如vue中的计算属性一样,基于state数据的二次包装,常用于数据的筛选和多个数据的相关性计算

  • mutations:类似函数,改变state数据的唯一途径,且不能用于处理异步事件

  • actions:类似于mutation,用于提交mutation来改变状态,而不直接变更状态,可以包含任意异步操作

  • modules:类似于命名空间,用于项目中将各个模块的状态分开定义和操作,便于维护

3. Vuex实例应用

// 父组件

<template>
  <div id="app">
    <ChildA/>
    <ChildB/>
  </div>
</template>

<script>
  import ChildA from &#39;./components/ChildA&#39; // 导入A组件
  import ChildB from &#39;./components/ChildB&#39; // 导入B组件

  export default {
    name: &#39;App&#39;,
    components: {ChildA, ChildB} // 注册A、B组件
  }
</script>
Copier après la connexion
// 子组件childA

<template>
  <div id="childA">
    <h1>我是A组件</h1>
    <button @click="transform">点我让B组件接收到数据</button>
    <p>因为你点了B,所以我的信息发生了变化:{{BMessage}}</p>
  </div>
</template>

<script>
  export default {
    data() {
      return {
        AMessage: &#39;Hello,B组件,我是A组件&#39;
      }
    },
    computed: {
      BMessage() {
        // 这里存储从store里获取的B组件的数据
        return this.$store.state.BMsg
      }
    },
    methods: {
      transform() {
        // 触发receiveAMsg,将A组件的数据存放到store里去
        this.$store.commit(&#39;receiveAMsg&#39;, {
          AMsg: this.AMessage
        })
      }
    }
  }
</script>
Copier après la connexion
// 子组件 childB

<template>
  <div id="childB">
    <h1>我是B组件</h1>
    <button @click="transform">点我让A组件接收到数据</button>
    <p>因为你点了A,所以我的信息发生了变化:{{AMessage}}</p>
  </div>
</template>

<script>
  export default {
    data() {
      return {
        BMessage: &#39;Hello,A组件,我是B组件&#39;
      }
    },
    computed: {
      AMessage() {
        // 这里存储从store里获取的A组件的数据
        return this.$store.state.AMsg
      }
    },
    methods: {
      transform() {
        // 触发receiveBMsg,将B组件的数据存放到store里去
        this.$store.commit(&#39;receiveBMsg&#39;, {
          BMsg: this.BMessage
        })
      }
    }
  }
</script>
Copier après la connexion

vuex的store,js

import Vue from &#39;vue&#39;
import Vuex from &#39;vuex&#39;
Vue.use(Vuex)
const state = {
  // 初始化A和B组件的数据,等待获取
  AMsg: &#39;&#39;,
  BMsg: &#39;&#39;
}

const mutations = {
  receiveAMsg(state, payload) {
    // 将A组件的数据存放于state
    state.AMsg = payload.AMsg
  },
  receiveBMsg(state, payload) {
    // 将B组件的数据存放于state
    state.BMsg = payload.BMsg
  }
}

export default new Vuex.Store({
  state,
  mutations
})
Copier après la connexion

七、 localStorage / sessionStorage


这种通信比较简单,缺点是数据和状态比较混乱,不太容易维护。

通过window.localStorage.getItem(key) 获取数据

通过window.localStorage.setItem(key,value) 存储数据

注意用JSON.parse() / JSON.stringify() 做数据格式转换
localStorage / sessionStorage可以结合vuex, 实现数据的持久保存,同时使用vuex解决数据和状态混乱问题.

$attrs$listeners


现在我们来讨论一种情况, 我们一开始给出的组件关系图中A组件与D组件是隔代关系, 那它们之前进行通信有哪些方式呢?

  • 使用props绑定来进行一级一级的信息传递, 如果D组件中状态改变需要传递数据给A, 使用事件系统一级级往上传递

  • 使用eventBus,这种情况下还是比较适合使用, 但是碰到多人合作开发时, 代码维护性较低, 可读性也低

  • 使用Vuex来进行数据管理, 但是如果仅仅是传递数据, 而不做中间处理,使用Vuex处理感觉有点大材小用了.

vue2.4中,为了解决该需求,引入了$attrs$listeners , 新增了inheritAttrs 选项。 在版本2.4以前,默认情况下,父作用域中不作为 prop 被识别 (且获取) 的特性绑定 (class 和 style 除外),将会“回退”且作为普通的HTML特性应用在子组件的根元素上。接下来看一个跨级通信的例子:

// app.vue
// index.vue

<template>
  <div>
    <child-com1
      :name="name"
      :age="age"
      :gender="gender"
      :height="height"
      title="程序员成长指北"
    ></child-com1>
  </div>
</template>
<script>
const childCom1 = () => import("./childCom1.vue");
export default {
  components: { childCom1 },
  data() {
    return {
      name: "zhang",
      age: "18",
      gender: "女",
      height: "158"
    };
  }
};
</script>
Copier après la connexion
// childCom1.vue

<template class="border">
  <div>
    <p>name: {{ name}}</p>
    <p>childCom1的$attrs: {{ $attrs }}</p>
    <child-com2 v-bind="$attrs"></child-com2>
  </div>
</template>
<script>
const childCom2 = () => import("./childCom2.vue");
export default {
  components: {
    childCom2
  },
  inheritAttrs: false, // 可以关闭自动挂载到组件根元素上的没有在props声明的属性
  props: {
    name: String // name作为props属性绑定
  },
  created() {
    console.log(this.$attrs);
     // { "age": "18", "gender": "女", "height": "158", "title": "程序员成长指北" }
  }
};
</script>
Copier après la connexion
// childCom2.vue

<template>
  <div class="border">
    <p>age: {{ age}}</p>
    <p>childCom2: {{ $attrs }}</p>
  </div>
</template>
<script>

export default {
  inheritAttrs: false,
  props: {
    age: String
  },
  created() {
    console.log(this.$attrs); 
    // { "gender": "女", "height": "158", "title": "程序员成长指北" }
  }
};
</script>
Copier après la connexion

更多编程相关知识,请访问:编程视频!!

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Étiquettes associées:
source:segmentfault.com
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal