Maison >interface Web >Voir.js >Parlons de la façon d'implémenter la liaison bidirectionnelle dans Vue sans utiliser v-model ?
Comment implémenter une liaison bidirectionnelle dans Vue sans utiliser v-model ? L'article suivant vous présentera comment réaliser une liaison bidirectionnelle sans utiliser v-model. J'espère qu'il vous sera utile !
Certaines personnes disent, avez-vous le culot de poser une question aussi novice ?
Ne me dites pas, quand j'ai appris Vue pour la première fois, j'ai été torturé par ces problèmes, j'ai dû serrer les dents et écrire selon la démo du document du site officiel. Après m'être familiarisé avec celui-ci, j'ai aussi écrit beaucoup de choses. bugs liés au modèle V dans le développement quotidien. Plus tard, après avoir décidé de l'étudier attentivement, j'ai découvert qu'il existe encore de nombreuses façons de le faire. [Recommandation associée : tutoriel vidéo vue.js]
Regardons d'abord la réponse :
<template> <div class="test-v-model"> <p>使用v-model</p> <input v-model="msg" placeholder="edit me" /> <p>{{ msg }}</p> <p>不使用v-model</p> <input :value="msg1" @input="handleInput" placeholder="edit me" /> <p>{{ msg1 }}</p> </div> </template> <script> export default { name: 'test-v-model', data() { return { msg: '', msg1: '' } }, methods: { handleInput(e) { this.msg1 = e.target.value } } } </script>
Si vous n'utilisez pas v-model, vous devez lier la valeur via l'attribut value et la modifier la valeur de liaison via l'événement d'entrée pour obtenir une liaison bidirectionnelle.
En d'autres termes, v-model n'est qu'un raccourci
En fait, l'essence du v-model est du sucre syntaxique. Il est chargé d'écouter les événements d'entrée de l'utilisateur pour mettre à jour les données et d'effectuer un traitement spécial pour certains. scénarios extrêmes. -- Documentation officielle
v-model utilise en interne différentes propriétés et lance différents événements pour différents éléments d'entrée :
- les éléments text et textarea utilisent la propriété
value
et l'entréeévénement ;
value
property 和input
事件;- checkbox 和 radio 使用
checked
property 和change
事件;- select 字段将
value
作为 prop 并将change
作为事件。
问:什么是双向绑定?
双向绑定就是当数据变化之后,视图同步更新,当视图变化之后,数据也会更新。
问:什么是单向数据绑定?
单向数据绑定就是当数据变化之后,视图同步更新,当视图变化之后,数据不会更新。
在vue中是通过指令 v-model 来实现双向绑定,通过 v-bind
la case à cocher et la radio utilisent la propriété checked
et l'événement change
value code> comme accessoire et <code>change
comme événement.
Liaison bidirectionnelle
Liaison de données unidirectionnellevue Flux de données unidirectionnel pour les interactions entre les composants
Q : Qu'est-ce que la liaison bidirectionnelle ?La liaison bidirectionnelle signifie que lorsque les données changent, la vue est mise à jour de manière synchrone, et lorsque la vue change, les données seront également mises à jour.
La liaison de données unidirectionnelle signifie que lorsque les données changent, la vue est mise à jour de manière synchrone. Lorsque la vue change, les données ne seront pas mises à jour.Q : Qu'est-ce que la liaison de données unidirectionnelle ?
Après avoir lu le code suivant et la démonstration gif de ce code en cours d'exécution, vous pourrez comprendre leurs différences.En vue, c'est via la commande v-model pour obtenir une liaison bidirectionnelle et
v-bind
pour obtenir une liaison unidirectionnelle liaison de données
<template> <div> <p>双向绑定</p> <input v-model="msg" placeholder="edit me" /> <p>{{ msg }}</p> <p>单向数据绑定</p> <input v-bind:value="msg1" placeholder="edit me" /> <p>{{ msg1 }}</p> </div> </template> <script> export default { name: 'test-v-model', data() { return { msg: '', msg1: '' } } } </script>Comme vous pouvez le voir sur le gif, en utilisant v-model, lorsque les données changent, la vue est mise à jour de manière synchrone. Lorsque la vue change, les données seront également mises à jour.
En utilisant v-bind, lorsque les données changent, la vue est mise à jour de manière synchrone. Lorsque la vue change, les données ne seront pas mises à jour.
Q : Qu'est-ce que le flux de données unidirectionnel de Vue ?
Un composant enfant ne peut pas modifier l'attribut prop qui lui est transmis par le composant parent. L'approche recommandée consiste à lancer un événement et à notifier au composant parent de modifier lui-même la valeur liée.
Pour résumer, les données diminuent et les événements augmentent. Le document vue met en avant le concept de flux de données unidirectionnel lors de l'introduction de Prop. 🎜Cliquez ici🎜 pour voir la description du flux de données unidirectionnel dans le document vue. 🎜🎜🎜Tous les accessoires forment une 🎜Liaison descendante unidirectionnelle🎜 entre leurs accessoires parent et enfant : les mises à jour des accessoires parent seront transmises vers le bas vers les composants enfants, mais pas l'inverse. Cela empêchera le composant enfant de modifier accidentellement l'état du composant parent, ce qui rendrait le flux de données de votre application difficile à comprendre. 🎜🎜🎜🎜De plus, chaque fois que le composant parent change, tous les accessoires du composant enfant seront actualisés avec les dernières valeurs. Cela signifie que vous 🎜ne devriez pas 🎜 modifier les accessoires à l'intérieur d'un composant enfant. Si vous faites cela, Vue émettra un avertissement dans la console du navigateur. 🎜🎜🎜Regardons l'exemple suivant : 🎜🎜Que se passe-t-il si un sous-composant effectue directement une liaison bidirectionnelle sur la valeur de la prop ? 🎜🎜Code composant parent : 🎜<template> <child-component :value="fatherValue" /> </template> <script> import ChildComponent from './child.vue' export default { name: 'father-component', components: { ChildComponent }, data() { return { fatherValue: '' } } } </script>🎜Code composant enfant : 🎜
<template> <div class="child-component"> <input v-model="value" placeholder="edit me" /> <p>{{ value }}</p> </div> </template> <script> export default { name: 'child-component', props: { value: { type: String, default: '' } } } </script>🎜🎜🎜🎜🎜🎜
可以看到,childComponent中的 prop 值可以实现双向绑定,但是 FatherComponent 中的 data 值并未发生改变,而且控制台抛出了警告:
[Vue warn]: Avoid mutating a prop directly since the value will be overwritten whenever the parent component re-renders. Instead, use a data or computed property based on the prop's value. Prop being mutated: "value"
翻译一下:避免直接改变 prop 值,因为每当父组件重新渲染时,该值将被覆盖。相反,使用基于 prop 值的 data 或 computed。
很显然,直接改变子组件的 prop 值的这种行为被 vue 禁止了。
如何操作传入子组件的 prop 值
但是很多时候,我们确实要操作传入子组件的 prop 值,该怎么办呢?
正如上面的警告所说,有两种办法:
props: { initialCounter: { type: Number, default: 0 }, }, data() { return { counter: this.initialCounter } }
props: { size: { type: String, default: '' } }, computed: { normalizedSize: function () { return this.size.trim().toLowerCase() } }
这样不管怎么操作数据都是操作的子组件数据了,不会影响到父组件数据。
所以,我们想用 prop 传入的数据实现双向绑定,可以这么写:
父组件代码不变
子组件里用 innerValue 来接收传入的 value :
<template> <div class="child-component"> <input v-model="innerValue" placeholder="edit me" /> <p>{{ innerValue }}</p> </div> </template> <script> export default { name: 'child-component', props: { value: { type: String, default: '' } }, data() { return { innerValue: this.value } } } </script>
这里要注意一个问题
在 JavaScript 中对象和数组是通过引用传入的,所以对于一个数组或对象类型的 prop 来说,在子组件中改变变更这个对象或数组本身将会影响到父组件的状态。
还是上面的例子,我们将传入的值改为对象:
父组件代码:
<template> <child-component :obj="fatherObj" /> </template> <script> import ChildComponent from './child.vue' export default { name: 'father-component', components: { ChildComponent }, data() { return { fatherObj: { name: 'lin' } } } } </script>
子组件代码:
<template> <div class="child-component"> <input v-model="innerObj.name" placeholder="edit me" /> <p>{{ innerObj.name }}</p> </div> </template> <script> export default { name: 'child-component', props: { obj: { type: Object, default: () => {} } }, data() { return { innerObj: this.obj } } } </script>
这里的 this.obj
是引用类型,赋值给了 innerObj
,所以 innerObj
实际上还是指向了父组件的数据,对 innerObj.name
的修改依然会影响到父组件
所以,处理这种引用类型数据的时候,需要深拷贝一下
import { clone } from 'xe-utils' export default { name: 'child-component', props: { obj: { type: Object, default: () => {} } }, data() { return { innerObj: clone(this.obj, true) } } }
如上图所示,这样子组件和父组件之间的数据就不会互相影响了。
至此,终于把双向绑定和单向数据流讲清楚了,真的没想到,平时开发时都懂的概念,想讲清楚居然花了这么多篇幅,确实不容易,不过,这也是对自己的一种锻炼吧。
问:v-model是双向绑定吗?
是,但只是语法糖
问:v-model是单向数据流吗?
是,数据向下,事件向上
本题还有一些其他问法,比如:
看完本篇文章,相信不管怎么问,你都能对这两个概念理解透彻了。
更多编程相关知识,请访问:编程入门!!
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!