Heim  >  Artikel  >  Web-Frontend  >  Sechs Möglichkeiten zur Kommunikation mit Vue-Komponenten

Sechs Möglichkeiten zur Kommunikation mit Vue-Komponenten

hzc
hzcnach vorne
2020-06-18 09:44:073220Durchsuche

Im normalen Entwicklungsprozess wird es definitiv zu einer Kommunikation zwischen Vater- und Sohn-/Geschwisterkomponenten kommen. Daher finden Sie hier eine Zusammenfassung der Kommunikationsstützen von 6 Vue-Komponenten / $e$emit / Vuex$attrs / $ Listeners

  1. $Eltern / $Kinder mit Ref

  2. bereitstellen / injizieren

Vorwort

Sechs Möglichkeiten zur Kommunikation mit Vue-Komponenten

Wie in der Abbildung oben gezeigt, sind die Komponenten A/B, B/C und B/D Eltern-Kind-Beziehungen und C/ D ist eine Bruderbeziehung. Wie wählt man also je nach Nutzungsszenario unterschiedliche Kommunikationsmethoden aus? Die Voraussetzung ist also, dass wir die Funktionen und Unterschiede verschiedener Kommunikationsmethoden verstehen müssen.

1. props / $emit

Dies ist eine der Methoden, die wir normalerweise häufiger verwenden. Die übergeordnete Komponente A übergibt Daten über den props-Parameter an die untergeordnete Komponente B. Komponente B sendet über $emit ein Ereignis (mit Parameterdaten) an Komponente A. Komponente A hört auf das von $emit ausgelöste Ereignis und erhält die von B an A gesendeten Daten. Lassen Sie uns die Implementierungsschritte im Detail erklären:

1: Übergeordnete Komponente übergibt Wert an untergeordnete Komponente

// App.vue 父组件
<template>
    <a-compontent></a-compontent>
</template>
<script>
import aCompontent from &#39;./components/A.vue&#39;;
export default {
    name: &#39;app&#39;,
    compontent: { aCompontent },    
    data () {        
        return {
         dataA: &#39;dataA数据&#39;
       }
    }
}
// aCompontent 子组件
<template>
    <p>{{dataA}} // 在子组件中把父组件传递过来的值显示出来

<script>export default {
    name: &#39;aCompontent&#39;,
    props: {
        dataA: {           
              //这个就是父组件中子标签自定义名字            
              type: String,
            required: true  // 或者false
        }
    }
}
</script>

2: Untergeordnete Komponente übergibt Wert an übergeordnete Komponente (Durch Ereignisse)

// 子组件
<template>
    <p>点击向父组件传递数据</p>
</template>
<script>export default {
    name: &#39;child&#39;,
    methods:{        
        changeTitle() {
              // 自定义事件,会触发父组件的监听事件,并将数据以参数的形式传递
            this.$emit(&#39;sendDataToParent&#39;,&#39;这是子组件向父组件传递的数据&#39;); 
        }
    }
}

// 父组件
<template>
    <child @sendDataToParent="getChildData">

<script>
import child from &#39;./components/child.vue&#39;;
    export default {
    name: &#39;child&#39;,
    methods:{
        getChildData(data) {
            console.log(data); // 这里的得到了子组件的值
        }
    }
}
</script>

2. $emit / $on

Diese Methode verwendet eine Instanz wie App.vue als Modul Event Center, verwenden Sie es zum Auslösen und auf Ereignisse warten. Wenn Sie es in App.vue einfügen, können Sie die Kommunikation in jeder Komponente implementieren. Diese Methode ist jedoch nicht einfach zu warten, wenn das Projekt relativ groß ist.

Zum Beispiel: Angenommen, es gibt jetzt 4 Komponenten, Home.vue und A/B/C-Komponenten. Diese drei Komponenten AB sind Geschwisterkomponenten, die der übergeordneten Komponente entsprechen, die eine leere Vue-Instanz erstellt. Montieren Sie das Kommunikationsereignis auf der Instanz -

D.js
import Vue from 'vue'export default new Vue()
// 我们可以在router-view中监听change事件,也可以在mounted方法中监听
// home.vue<template>  <p>    <child-a></child-a>    <child-b></child-b>    <child-c></child-c>  </p></template>
// A组件
<template>
  <p>将A组件的数据发送给C组件 - {{name}}</p>
</template>
<script>
import Event from "./D";export default {  data() {    return {
      name: &#39;Echo&#39;
    }
  },
  components: { Event },
  methods: {    dataA() {
      Event.$emit(&#39;data-a&#39;, this.name);
    }
  }
}
</script>
// B组件
<template>
  <p>将B组件的数据发送给C组件 - {{age}}</p>
</template>
<script>
import Event from "./D";export default {  data() {    return {
      age: &#39;18&#39;
    }
  },
  components: { Event },
  methods: {    dataB() {
      Event.$emit(&#39;data-b&#39;, this.age);
    }
  }
}
</script>
// C组件
<template>
  <p>C组件得到的数据 {{name}} {{age}}</p>
</template>
<script>
import Event from "./D";export default {  data() {    return {
      name: &#39;&#39;,
      age: &#39;&#39;
    }
  },
  components: { Event },  mounted() {
    // 在模板编译完成后执行
    Event.$on(&#39;data-a&#39;, name => {
      this.name = name;
    })
    Event.$on(&#39;data-b&#39;, age => {
      this.age = age;
    })
  }
}
</script>

Aus dem Obigen können wir erkennen, dass das $emit-Ereignis von A/B im montierten Ereignis der C-Komponente überwacht wird und die von ihm übergebenen Parameter abgerufen werden ( Da Wir sind uns nicht sicher, wann das Ereignis ausgelöst wird, wir hören normalerweise zu (montiert/erstellt)

Vuex

Vuex ist ein Zustandsverwaltungsmodell. Es verwendet einen zentralen Speicher, um den Status aller Komponenten der Anwendung zu verwalten, und stellt mithilfe entsprechender Regeln sicher, dass sich der Status auf vorhersehbare Weise ändert. Der Kern der Vuex-Anwendung ist der Store (Lager, ein Container).

Dieser Teil wird nicht im Detail vorgestellt. vuejs .org/zh/guide/st…

IV. $attrs / $listeners

Wie im Bild oben gezeigt Dies ist eine mehrstufige Komponentenverschachtelung. Wie kommunizieren die A/C-Komponenten? Wir können uns jetzt die folgenden Lösungen vorstellen:

  1. Verwenden Sie Vuex für die Datenverwaltung, aber das Problem bei der Verwendung von Vuex besteht darin, dass Sie Vuex verwenden, wenn das Projekt relativ klein ist und es weniger gemeinsame Zustände zwischen Komponenten gibt ist, als würde man ein Huhn mit einem Messer töten.
  2. Verwenden Sie B-Komponente als Übertragungsstation. Wenn A-Komponente Informationen an C-Komponente weitergeben muss, akzeptiert B die Informationen von A-Komponente und übergibt sie dann mithilfe von Requisiten an C-Komponente Dies führt zu umständlichem Code und schwieriger Codewartung. Wenn Statusänderungen in C an A weitergeleitet werden müssen, muss das Ereignissystem verwendet werden, um sie jeweils eine Ebene nach oben weiterzugeben.

Um diese Anforderung zu lösen, wurden in Vue2.4 Attrs und Listener eingeführt und die Option inheritAttrs hinzugefügt. (Wie im Bild unten gezeigt)

Die Rolle von $attrs, in einigen Fällen muss es in Verbindung mit inheritAttrs

verwendet werden, besteht aus 4 Komponenten : App.vue / child1.vue / child2.vue / child3.vue, diese vier Komponenten sind nacheinander verschachtelt.

// App.vue
<template>
  <p>
    </p>
<p>App.vue</p>
<hr>
    // 这里我们可以看到,app.vue向下一集的child1组件传递了5个参数,分别是name / age / job / sayHi / title
    <child1></child1>
  
</template>
<script>
const child1 = () => import("./components/child1.vue");
export default {
  name: &#39;app&#39;,
  components: { child1 },  data() {    return {
      name: "Echo",
      age: "18",
      job: "FE",
      say: "this is Hi~"
    };
  }
};
</script>
// child1.vue
<template>
  <p>
    </p>
<p>child1.vue</p>
    <p>name: {{ name }}</p>
    <p>childCom1的$attrs: {{ $attrs }}</p>
    <p>可以看到,$attrs这个对象集合中的值 = 所有传值过来的参数 - props中显示定义的参数</p>
    <hr>
    <child2></child2>
  
</template>
<script>
const child2 = () => import("./child2.vue");
export default {
  components: {
    child2
  },
  // 这个inheritAttrs默认值为true,不定义这个参数值就是true,可手动设置为false
  // inheritAttrs的意义在用,可以在从父组件获得参数的子组件根节点上,将所有的$attrs以dom属性的方式显示
  inheritAttrs: true, // 可以关闭自动挂载到组件根元素上的没有在props声明的属性
  props: {
    name: String // name作为props属性绑定
  },  created() {
    // 这里的$attrs就是所有从父组件传递过来的所有参数 然后 除去props中显式定义的参数后剩下的所有参数!!!
    console.log(this.$attrs); //  输出{age: "18", job: "FE", say-Hi: "this is Hi~", title: "App.vue的title"}
  }
};
</script>
// child2.vue
<template>
  <p>
    </p>
<p>child2.vue</p>
    <p>age: {{ age }}</p>
    <p>childCom2: {{ $attrs }}</p>
    <hr>
    <child3></child3>
  
</template>
<script>
const child3 = () => import("./child3.vue");
export default {
  components: {
    child3
  },
  // 将inheritAttrs设置为false之后,将关闭自动挂载到组件根元素上的没有在props声明的属性
  inheritAttrs: false,
  props: {
    age: String
  },  created() {
    // 同理和上面一样,$attrs这个对象集合中的值 = 所有传值过来的参数 - props中显示定义的参数
    console.log(this.$attrs);
  }
};
</script>
// child3.vue
<template>
  <p>
    </p>
<p>child3.vue</p>
    <p>job: {{job}}</p>
    <p>title: {{title}}</p>
    <p>childCom3: {{ $attrs }}</p>
  
</template>
<script>export default {
  inheritAttrs: true,
  props: {
    job: String,
    title: String
  }
};
</script>

Schauen wir uns den spezifischen Anzeigeeffekt an:

Und wie verwendet man $listeners? Im offiziellen Dokument heißt es: Enthält den Inhalt im übergeordneten Element Scope (ohne .native Decorator) v-on-Ereignis-Listener. Es kann über v-on="$listeners" an innere Komponenten übergeben werden – sehr nützlich beim Erstellen von Komponenten auf höherer Ebene! Aus der wörtlichen Bedeutung sollte es sein, der übergeordneten Komponente ein Überwachungsereignis hinzuzufügen, das den Wert akzeptieren muss? Es gibt nicht viel zu sagen, der Code

besteht immer noch aus 3 nacheinander verschachtelten Komponenten

<template>
  <p>
    <child2></child2>
  </p>
</template>
<script>
const child2 = () => import("./child2.vue");
export default {
  components: {
    child2
  },
  methods: {    reciveRocket() {
      console.log("reciveRocket success");
    }
  }
};
</script>复制代码
<template>
  <p>
    <child3></child3>
  </p>
</template>
<script>
const child3 = () => import("./child3.vue");
export default {
  components: {
    child3
  },  created() {
    this.$emit(&#39;child2&#39;, &#39;child2-data&#39;);
  }
};
</script>复制代码
// child3.vue
<template>
  <p>
    </p>
<p>child3</p>
  
</template>
<script>
export default {
  methods: {    startUpRocket() {
      this.$emit("upRocket");
      console.log("startUpRocket");
    }
  }
};
</script>复制代码

这里的结果是,当我们点击 child3 组件的 child3 文字,触发 startUpRocket 事件,child1 组件就可以接收到,并触发 reciveRocket 打印结果如下:

> reciveRocket success
> startUpRocket

五. $parent / $children 与 ref

  • ref:如果在普通的 DOM 元素上使用,引用指向的就是 DOM 元素;如果用在子组件上,引用就指向组件实例
  • $parent / $children:访问父 / 子实例

这两种方式都是直接得到组件实例,使用后可以直接调用组件的方法或访问数据。

我们先来看个用 ref 来访问组件的:

// child1子组件
export default {  
        data() {    
            return {
      title: 'Vue.js'
    };
  },
  methods: {    
      sayHello() {
      console.log('child1!!');
    }
  }
};
// 父组件
<template>
  <child1></child1>
</template>
<script>  
export default {
    methods: {      
        sayHi () {
        const child1 = this.$refs.child1;
        console.log(child1.title);  // Vue.js
        child1.sayHello();  // 弹窗
      }
    }
  }
</script>

六. provide/inject

provide/inject 是 Vue2.2.0 新增 API,这对选项需要一起使用,以允许一个祖先组件向其所有子孙后代注入一个依赖,不论组件层次有多深,并在起上下游关系成立的时间里始终生效。如果你熟悉 React,这与 React 的上下文特性很相似。

provide 和 inject 主要为高阶插件/组件库提供用例。并不推荐直接用于应用程序代码中。

由于自己对这部分的内容理解不是很深刻,所以感兴趣的可以前往官方文档查看: cn.vuejs.org/v2/api/#pro…

总结

常见使用场景可以分为三类:

  1. 父子通信:props / $emit;$parent / $children;$attrs/$listeners;provide / inject API; ref
  2. 兄弟通信:Vuex
  3. 跨级通信:Vuex;$attrs/$listeners;provide / inject API
    4.接下来我还会在我的裙里用视频讲解的方式给大家讲解【以下图中的内容有兴趣的可以来我的扣扣裙 519293536 免费交流学习,我都会尽力帮大家哦

推荐教程:《JS教程

Das obige ist der detaillierte Inhalt vonSechs Möglichkeiten zur Kommunikation mit Vue-Komponenten. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Dieser Artikel ist reproduziert unter:cnblogs.com. Bei Verstößen wenden Sie sich bitte an admin@php.cn löschen