Heim  >  Artikel  >  Web-Frontend  >  Vue2 implementiert die bidirektionale Bindung von Komponenten-Requisiten

Vue2 implementiert die bidirektionale Bindung von Komponenten-Requisiten

高洛峰
高洛峰Original
2017-01-16 11:47:141797Durchsuche

Vue Study Notes-3 Vorwort

Im Vergleich zu Vue 1.x und Vue 2.x ist neben der Implementierung von Virtual-Dom das größte Unbehagen für Benutzer das Entfernen von Requisiten der zweiten Komponente -way-Bindungsfunktion.
In der Vergangenheit wurden die Bindungsmodifikatoren twoWay und .sync von Requisiten verwendet, um die bidirektionale Bindungsfunktion von Requisiten in Vue1 zu implementieren.

Vue2s Kommunikationsmethode für Komponenten-Requisiten

In Vue2 wurde der Datenfluss von Komponenten-Requisiten so geändert, dass er nur in eine Richtung fließt, d. h. er kann nur von außerhalb der Komponente (aufrufende Komponente) fließen Seite) über das DOM der Komponente. Das Attribut übergibt Requisiten an die Komponente. Die Komponente kann nur passiv Daten empfangen, die von außerhalb der Komponente übergeben werden, und innerhalb der Komponente können die von der äußeren Ebene übergebenen Requisitendaten nicht geändert werden.

Vue2 implementiert die bidirektionale Bindung von Komponenten-Requisiten

Die offizielle Erklärung für diese Änderung:

prop ist eine unidirektionale Bindung: Wenn sich die Eigenschaften der übergeordneten Komponente ändern, wird sie an die Unterkomponente übertragen , aber nicht umgekehrt. Dadurch soll verhindert werden, dass untergeordnete Komponenten versehentlich den Status der übergeordneten Komponente ändern – was den Datenfluss der Anwendung schwer verständlich machen würde.

Obwohl es für das gesamte Projekt als Ganzes vorteilhaft und richtig ist, auf die bidirektionale Bindung von Requisiten zu verzichten, müssen wir irgendwann Requisiten innerhalb des Komponenten-

Case

ändern

Angenommen, ich möchte eine Umschalttaste im iOS-Stil erstellen. Es gibt nur zwei Anforderungen:

Klicken Sie auf die Schaltfläche, um den Ein-/Ausschaltzustand umzuschalten.

Sie können sie auch extern ändern Klicken Sie auf die Schaltfläche, um den Status des Datenschalters umzuschalten, z. B. Kaskadenverbindungsschalter.

Vue2 implementiert die bidirektionale Bindung von Komponenten-Requisiten

Der Code sieht ungefähr so ​​aus:

<div id="app">
 <!--开关组件-->
 <switchbtn :result="result"></switchbtn>
 <!--外部控制-->
 <input type="button" value="change" @click="change">
</div>
//开关组件代码
Vue.component("switchbtn",{
 template:"<div @click=&#39;change&#39;>{{result?&#39;开&#39;:&#39;关&#39;}}</div>",
 props:["result"],
 methods:{
 change(){
  this.result=!this.result;
 }
 }
});
 
//调用组件
new Vue({
 el: "#app",
 data:{
 result:true//开关状态数据
 },
 methods:{
 change(){
  this.result=!this.result;
 }
 }
});

Aber in vue2.0 ist der obige Code An Beim Klicken auf den Schalter wird ein Fehler gemeldet:

[Vue-Warnung]: Vermeiden Sie die direkte Mutation einer Requisite, da der Wert jedes Mal überschrieben wird, wenn die übergeordnete Komponente erneut gerendert wird. Verwenden Sie stattdessen eine Daten- oder berechnete Eigenschaft basierend auf Prop-Wert. Prop wird mutiert: „result“ (in der Komponente gefunden)

Der Wert von Props kann nicht innerhalb der Komponente geändert werden, und der geänderte Wert wird nicht mit der äußeren Ebene der Komponente synchronisiert , die aufrufende Komponente kennt den aktuellen Status innerhalb der Komponente nicht. Was ist

Wie implementiert man in Vue2.0 die bidirektionale Bindung von Komponenteneigenschaften?

1. Erstellen Sie eine Kopie der Requisiten Attribut im Datenobjekt innerhalb der Komponente

Da result nicht beschreibbar ist, müssen Sie eine Kopie der myResult-Variablen in data erstellen. Der Anfangswert ist gleichzeitig der Wert des props-Attributs result Dieses Datenobjekt myResult wird an allen Stellen in der Komponente aufgerufen, an denen Requisiten aufgerufen werden müssen.

Vue.component("switchbtn", {
 template: "<div @click=&#39;change&#39;>{{myResult?&#39;开&#39;:&#39;关&#39;}}</div>",
 props: ["result"],
 data: function () {
 return {
  myResult: this.result//data中新增字段
 };
 },
 ......
});

2. Erstellen Sie eine Überwachung für das Requisitenattribut, um die Änderung von Requisiten außerhalb der Komponente zu synchronisieren.

Zu diesem Zeitpunkt wird die Komponente außerhalb der Komponente geändert (übergeordnete Komponente) Requisiten werden mit den entsprechenden Requisiten in der Komponente synchronisiert, jedoch nicht mit der Kopie, die Sie gerade im Datenobjekt erstellt haben. Daher müssen Sie eine Überwachung (Überwachung) für das Ergebnis des Requisitenattributs erstellen und festlegen, wann Wenn die Requisiten geändert werden, entsprechen sie den Daten. Die Kopie von myResult muss auch Daten synchronisieren.

Vue.component("switchbtn", {
 template: "<div @click=&#39;change&#39;>{{myResult?&#39;开&#39;:&#39;关&#39;}}</div>",
 props: ["result"],
 data: function () {
 return {
  myResult: this.result
 };
 },
 watch: {
 result(val) {
  this.myResult = val;//新增result的watch,监听变更并同步到myResult上
 }
 },
 ......

3. Erstellen Sie eine Überwachung für die Kopie der Requisiten und benachrichtigen Sie sie außerhalb der Komponente

Zu diesem Zeitpunkt die Kopie der Requisiten Wird innerhalb der Komponente myResult geändert, ist der Status der Requisiten in der Komponente außerhalb der Komponente nicht bekannt. Daher müssen Sie eine Kopie von props myResult erstellen, dh eine Überwachung, die dem Datenattribut entspricht.
Senden Sie Benachrichtigungen innerhalb der Komponente an die äußere Schicht (übergeordnete Komponente), um die Eigenschaftsänderungen innerhalb der Komponente zu benachrichtigen, und dann ändert die äußere Schicht (übergeordnete Komponente) ihre Daten selbst

Der endgültige Code:

<div id="app">
 <switchbtn :result="result" @on-result-change="onResultChange"></switchbtn>
 <input type="button" value="change" @click="change">
</div>
Vue.component("switchbtn", {
 template: "<div @click=&#39;change&#39;>{{myResult?&#39;开&#39;:&#39;关&#39;}}</div>",
 props: ["result"],
 data: function () {
 return {
  myResult: this.result//①创建props属性result的副本--myResult
 };
 },
 watch: {
 result(val) {
  this.myResult = val;//②监听外部对props属性result的变更,并同步到组件内的data属性myResult中
 },
 myResult(val){
  //xxcanghai 小小沧海 博客园
  this.$emit("on-result-change",val);//③组件内对myResult变更后向外部发送事件通知
 }
 },
 methods: {
 change() {
  this.myResult = !this.myResult;
 }
 }
});
 
new Vue({
 el: "#app",
 data: {
 result: true
 },
 methods: {
 change() {
  this.result = !this.result;
 },
 onResultChange(val){
  this.result=val;//④外层调用组件方注册变更方法,将组件内的数据变更,同步到组件外的数据状态中
 }
 }
});

An diesem Punkt wird die bidirektionale Bindung von Daten innerhalb der Komponente und Daten außerhalb der Komponente sowie die Synchronisierung der Daten innerhalb der Komponente erreicht und außerhalb der Komponente erreicht wird. Am Ende läuft es auf einen Satz hinaus: Wenn sich die Komponente intern ändert, teilt sie dies der Außenwelt mit, und die Außenwelt entscheidet, ob sie geändert wird.

Vue2 implementiert die bidirektionale Bindung von Komponenten-Requisiten

4. Welche Requisiten eignen sich für die Zwei-Wege-Bindung?

Das erste, was zu erklären ist, ist, dass bidirektionale Bindungsstützen der Datenstatusverwaltung zwischen Komponenten, insbesondere in komplexen Unternehmen, definitiv nicht förderlich sind. Daher sollte die bidirektionale Bindung so wenig wie möglich und zu oft verwendet werden. Für komplexe Daten Bei der Verarbeitung wird die Verwendung von Vuex (http://vuex.vuejs.org/zh-cn/intro.html) empfohlen.

In unserem täglichen Gebrauch besteht jedoch tatsächlich Bedarf an einer bidirektionalen Bindung von Requisiten Persönlich Es wird davon ausgegangen, dass bidirektionale Requisiten nur verwendet werden sollten, wenn die folgenden Bedingungen erfüllt sind.

Requisiten müssen innerhalb der Komponente geändert werden.

Komponenten müssen zur Laufzeit dynamisch von außen gesteuert und nicht einfach initialisiert werden.

Der externe Zustand der Komponente muss zur Verarbeitung gelesen werden

Zu den Dingen, die die oben genannten Bedingungen erfüllen, gehört in diesem Beispiel die Schalterkomponente, die eine externe Steuerung des Schalterzustands erfordert; Ein weiteres Beispiel ist Tab. Das ActiveIndex-Attribut der Multi-Tab-Komponente muss in der Lage sein, extern zu steuern, auf welcher Seite die Registerkarte gerade geöffnet ist usw.

Automatisierte bidirektionale Bindungsverarbeitung für Requisiten

Vue's Mixin-Komponente – Propsync

通过上例也可以看出在Vue2.0中实现props的双向绑定很麻烦,如果有两个props需要做双向绑定上面的代码就要实现两遍,代码极其冗余。
所以我写了一个mixin来自动化处理props的双向绑定的需求——propsync。

主要功能

实现了在组件内自动创建所有prop对应的data属性,方便组件内修改prop使用。解决了vue2.0中不允许组件内直接修改prop的设计。

实现了组件外修改组件prop,组件内自动同步修改到data属性。

实现了组件内修改了data属性(由prop创建的),自动向组件外发出事件通知有内部prop修改。由组件外决定是否要将修改同步到组件外


propsync的使用方法

编写组件

对于编写组件时,如果需要props双向绑定,则直接引入mixin,并在配置中声明mixin即可: mixins: [propsync]

此mixin会根据prop的名称生成对应的data属性名,默认为在prop属性名前面增加"p_",即若prop中有字段名为active,则自动生成名为p_active的data字段(props到data的名称变更方法可自行修改,详见propsync源码开头配置)

propsync默认会将所有props创建双向绑定,可通过propsync:false来声明此props不需要创建双向绑定。

例:

import propsync from &#39;./mixins/propsync&#39;;//引入mixin文件
export default {
 name: "tab",
 mixins: [propsync],//声明使用propsync的mixin
 props: {
 active: {
 type: [String, Number],//会被propsync自动实现双向绑定,在data中创建p_active变量
 },
 width: {
 type: [Number, String],
 propsync:false//不会被propsync实现双向绑定
 }
 },
 methods: {
 setActive(page, index, e) {
 this.p_active = index;//可以直接使用this.p_active
 }
 }
}

调用组件

引入propsync后,会在内部双向绑定的data变更后触发一个onPropsChange事件。遂在调用组件处,增加一个事件监听 onPropsChange(可修改),当组件内修改了props时propsync会触发此事件,返回参与依次为:修改prop名称,修改后值,修改前值。可以由当前组件调用方(父组件)来决定是否要将组件内的变更同步到调用方
例:

<tab :active="active" @onPropsChange="change"></tab>
  
......略
{
 data:{
 active:0
 },
 methods:{
 change:function(propName,newVal,oldVal){
 this[propName]=newVal;
 console.log("组件tab的" +propName+ "属性变更为" +newVal);
 }
 }
}

更多Vue2 implementiert die bidirektionale Bindung von Komponenten-Requisiten相关文章请关注PHP中文网!


Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn