Maison > interface Web > js tutoriel > le corps du texte

Vue2 implémente la liaison bidirectionnelle des accessoires de composants

高洛峰
Libérer: 2017-01-16 11:47:14
original
1802 Les gens l'ont consulté

Vue Study Notes-3 Préface

Par rapport à Vue 1.x, Vue 2.x, en plus de l'implémentation de Virtual-Dom, le plus grand inconfort pour les utilisateurs est la suppression des accessoires des composants Two-. fonction de liaison de manière.
Dans le passé, les modificateurs de liaison twoWay et .sync des accessoires étaient utilisés pour implémenter la fonction de liaison bidirectionnelle des accessoires dans Vue1.

Méthode de communication des accessoires de composant de Vue2

Dans Vue2, le flux de données des accessoires de composant a été modifié pour ne circuler que dans une seule direction, c'est-à-dire qu'il ne peut circuler que depuis l'extérieur du composant (appel du composant côté) via le DOM du composant L'attribut transmet les accessoires au composant. Le composant ne peut recevoir que passivement les données transmises de l'extérieur du composant, et à l'intérieur du composant, les données des accessoires transmises depuis la couche externe ne peuvent pas être modifiées.

Vue2 implémente la liaison bidirectionnelle des accessoires de composants

L'explication officielle de ce changement :

prop est une liaison unidirectionnelle : lorsque les propriétés du composant parent changent, elles seront transmises au sous-composant , mais pas l'inverse. Cela permet d'éviter que les composants enfants ne modifient par inadvertance l'état du composant parent, ce qui rendrait le flux de données de l'application difficile à comprendre.

Bien qu'abandonner la liaison bidirectionnelle des accessoires soit bénéfique et correct pour l'ensemble du projet dans son ensemble, à un moment donné, nous devons modifier les accessoires depuis le composant

Case

Supposons que je veuille créer un bouton de commutation de style iOS. Il n'y a que deux exigences :

Cliquez sur le bouton pour activer/désactiver l'état

Vous pouvez également le modifier en externe sans en cliquant sur le bouton. État du commutateur de commutation de données, tel que le commutateur de liaison en cascade.

Vue2 implémente la liaison bidirectionnelle des accessoires de composants

Le code ressemble à peu près à ceci :

<div id="app">
 <!--开关组件-->
 <switchbtn :result="result"></switchbtn>
 <!--外部控制-->
 <input type="button" value="change" @click="change">
</div>
Copier après la connexion
//开关组件代码
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;
 }
 }
});
Copier après la connexion

Mais dans vue2.0, le code ci-dessus est An Une erreur sera signalée lorsque vous cliquerez sur le commutateur :

[Vue warn] : évitez de muter directement un accessoire car la valeur sera écrasée à chaque nouveau rendu du composant parent. À la place, utilisez des données ou une propriété calculée basée sur le. valeur de prop. Prop en cours de mutation : "résultat" (trouvé dans le composant)

La valeur des accessoires ne peut pas être modifiée dans le composant, et la valeur modifiée ne sera pas synchronisée avec la couche externe du composant, c'est-à-dire , le composant appelant ne connaît pas l'état actuel à l'intérieur du composant. Qu'est-ce que

Dans Vue2.0, comment implémenter la liaison bidirectionnelle des propriétés du composant

1 Créez une copie des accessoires. attribut dans l'objet de données dans le composant

Comme le résultat n'est pas accessible en écriture, vous devez donc créer une copie de la variable myResult dans data La valeur initiale est la valeur du résultat de l'attribut props. , cet objet de données myResult est appelé à tous les endroits du composant qui doivent appeler des accessoires.

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

2. Créez une surveillance pour l'attribut props pour synchroniser la modification des accessoires en dehors du composant

A ce moment, le composant est modifié en dehors du composant. (composant parent) les accessoires seront synchronisés avec les accessoires correspondants dans le composant, mais ne seront pas synchronisés avec la copie que vous venez de créer dans l'objet de données, vous devez donc créer une surveillance (moniteur) pour le résultat de l'attribut props, et quand les props sont modifiés, cela correspondra aux données. La copie de myResult doit également synchroniser les données.

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上
 }
 },
 ......
Copier après la connexion

3. Créer une surveillance pour la copie des accessoires et notifier l'extérieur du composant

A ce moment, la copie des accessoires est modifié au sein du composant myResult, l'état des props dans le composant n'est pas connu en dehors du composant, vous devez donc créer une copie des props myResult, c'est-à-dire une montre correspondant à l'attribut data.
Envoyer des notifications au sein du composant à la couche externe (composant parent) pour notifier les changements de propriétés au sein du composant, puis la couche externe (composant parent) modifie elle-même ses données

Le code final :

<div id="app">
 <switchbtn :result="result" @on-result-change="onResultChange"></switchbtn>
 <input type="button" value="change" @click="change">
</div>
Copier après la connexion
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;//④外层调用组件方注册变更方法,将组件内的数据变更,同步到组件外的数据状态中
 }
 }
});
Copier après la connexion

À ce stade, la liaison bidirectionnelle des données à l'intérieur du composant et des données à l'extérieur du composant est réalisée, et la synchronisation des données à l'intérieur et à l'extérieur du composant est réalisé. En fin de compte, cela se résume à une phrase : si le composant change en interne, il en informe le monde extérieur, et le monde extérieur décide s'il doit le modifier.

Vue2 implémente la liaison bidirectionnelle des accessoires de composants

4. Quels types d'accessoires conviennent à la reliure bidirectionnelle ?

La première chose à déclarer est que les accessoires de liaison bidirectionnelle ne sont certainement pas propices à la gestion de l'état des données entre les composants, en particulier dans les entreprises complexes, utilisez donc le moins possible la liaison bidirectionnelle, trop pour les données complexes. traitement, il est recommandé d'utiliser Vuex (http://vuex.vuejs.org/zh-cn/intro.html)

Cependant, dans notre utilisation quotidienne, il existe effectivement un besoin de liaison bidirectionnelle des accessoires. Personnellement, on considère que les accessoires à liaison bidirectionnelle ne doivent être utilisés que lorsque les conditions suivantes sont remplies.

Les accessoires doivent être modifiés à l'intérieur du composant.

Les composants doivent être contrôlés dynamiquement par l'extérieur au moment de l'exécution, plutôt que simplement initialisés.

L'état externe du composant doit être lu pour le traitement.

Les éléments qui remplissent les conditions ci-dessus incluent le composant de commutation dans cet exemple, qui nécessite un contrôle externe de l'état du commutateur ; un autre exemple est Tab. L'attribut activeIndex du composant multi-onglets doit être capable de contrôler de manière externe la page sur laquelle l'onglet est actuellement ouvert, etc.

Traitement automatisé de liaison bidirectionnelle des accessoires

Composant mixin de Vue - 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
 }
 }
}
Copier après la connexion

调用组件

引入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);
 }
 }
}
Copier après la connexion

更多Vue2 implémente la liaison bidirectionnelle des accessoires de composants相关文章请关注PHP中文网!


Étiquettes associées:
source:php.cn
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