Skip to content

Commit a075fd3

Browse files
authored
fix(v-model): create non-existent properties as reactive (#80)
2 parents 4a45b37 + 05b9b3a commit a075fd3

File tree

2 files changed

+35
-29
lines changed

2 files changed

+35
-29
lines changed

packages/babel-sugar-v-model/src/index.js

+12-6
Original file line numberDiff line numberDiff line change
@@ -181,12 +181,18 @@ const addProp = (t, path, propName, expression, unshift = false) => {
181181
* @param valueExpression Expression
182182
*/
183183
const genAssignmentCode = (t, valuePath, valueExpression) => {
184-
if (t.isMemberExpression(valuePath) && valuePath.node.computed) {
185-
return t.callExpression(t.memberExpression(t.thisExpression(), t.identifier('$set')), [
186-
valuePath.get('object').node,
187-
valuePath.get('property').node,
188-
valueExpression,
189-
])
184+
let obj
185+
if (t.isMemberExpression(valuePath) && !t.isThisExpression(obj = valuePath.get('object').node)) {
186+
return t.callExpression(
187+
t.memberExpression(t.thisExpression(), t.identifier('$set')),
188+
[
189+
obj,
190+
valuePath.node.computed
191+
? valuePath.get('property').node
192+
: t.stringLiteral(valuePath.get('property.name').node),
193+
valueExpression
194+
]
195+
);
190196
} else {
191197
return t.assignmentExpression('=', valuePath.node, valueExpression)
192198
}

packages/babel-sugar-v-model/test/snapshot.js

+23-23
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ const tests = [
3030
to: `const A = <MyComponent model={{
3131
value: a.b,
3232
callback: $$v => {
33-
a.b = $$v;
33+
this.$set(a, "b", $$v);
3434
}
3535
}} />;`,
3636
},
@@ -40,7 +40,7 @@ const tests = [
4040
to: `const A = <my-component model={{
4141
value: a.b,
4242
callback: $$v => {
43-
a.b = $$v;
43+
this.$set(a, "b", $$v);
4444
}
4545
}} />;`,
4646
},
@@ -50,7 +50,7 @@ const tests = [
5050
to: `const A = <a.b model={{
5151
value: a.b,
5252
callback: $$v => {
53-
a.b = $$v;
53+
this.$set(a, "b", $$v);
5454
}
5555
}} />;`,
5656
},
@@ -60,7 +60,7 @@ const tests = [
6060
to: `const A = <MyComponent model={{
6161
value: a.b,
6262
callback: $$v => {
63-
a.b = this._n($$v);
63+
this.$set(a, "b", this._n($$v));
6464
}
6565
}} />;`,
6666
},
@@ -70,7 +70,7 @@ const tests = [
7070
to: `const A = <MyComponent model={{
7171
value: a.b,
7272
callback: $$v => {
73-
a.b = typeof $$v === "string" ? $$v.trim() : $$v;
73+
this.$set(a, "b", typeof $$v === "string" ? $$v.trim() : $$v);
7474
}
7575
}} />;`,
7676
},
@@ -80,7 +80,7 @@ const tests = [
8080
to: `const A = <MyComponent model={{
8181
value: a.b,
8282
callback: $$v => {
83-
a.b = this._n(typeof $$v === "string" ? $$v.trim() : $$v);
83+
this.$set(a, "b", this._n(typeof $$v === "string" ? $$v.trim() : $$v));
8484
}
8585
}} />;`,
8686
},
@@ -99,7 +99,7 @@ const tests = [
9999
from: `const A = <select vModel={a.b} />`,
100100
to: `const A = <select on-change={$event => {
101101
const $$selectedVal = Array.prototype.filter.call($event.target.options, o => o.selected).map(o => "_value" in o ? o._value : o.value);
102-
a.b = $event.target.multiple ? $$selectedVal : $$selectedVal[0];
102+
this.$set(a, "b", $event.target.multiple ? $$selectedVal : $$selectedVal[0]);
103103
}} {...{
104104
directives: [{
105105
name: "model",
@@ -113,7 +113,7 @@ const tests = [
113113
from: `const A = <select vModel_number={a.b} />`,
114114
to: `const A = <select on-change={$event => {
115115
const $$selectedVal = Array.prototype.filter.call($event.target.options, o => o.selected).map(o => this._n("_value" in o ? o._value : o.value));
116-
a.b = $event.target.multiple ? $$selectedVal : $$selectedVal[0];
116+
this.$set(a, "b", $event.target.multiple ? $$selectedVal : $$selectedVal[0]);
117117
}} {...{
118118
directives: [{
119119
name: "model",
@@ -137,12 +137,12 @@ const tests = [
137137
$$i = this._i($$a, $$v);
138138
139139
if ($$el.checked) {
140-
$$i < 0 && (a.b = $$a.concat([$$v]));
140+
$$i < 0 && this.$set(a, "b", $$a.concat([$$v]));
141141
} else {
142-
$$i > -1 && (a.b = $$a.slice(0, $$i).concat($$a.slice($$i + 1)));
142+
$$i > -1 && this.$set(a, "b", $$a.slice(0, $$i).concat($$a.slice($$i + 1)));
143143
}
144144
} else {
145-
a.b = $$c;
145+
this.$set(a, "b", $$c);
146146
}
147147
}} type="checkbox" domProps-checked={Array.isArray(a.b) ? this._i(a.b, null) > -1 : a.b} {...{
148148
directives: [{
@@ -165,12 +165,12 @@ const tests = [
165165
$$i = this._i($$a, $$v);
166166
167167
if ($$el.checked) {
168-
$$i < 0 && (a.b = $$a.concat([$$v]));
168+
$$i < 0 && this.$set(a, "b", $$a.concat([$$v]));
169169
} else {
170-
$$i > -1 && (a.b = $$a.slice(0, $$i).concat($$a.slice($$i + 1)));
170+
$$i > -1 && this.$set(a, "b", $$a.slice(0, $$i).concat($$a.slice($$i + 1)));
171171
}
172172
} else {
173-
a.b = $$c;
173+
this.$set(a, "b", $$c);
174174
}
175175
}} type="checkbox" domProps-checked={Array.isArray(a.b) ? this._i(a.b, null) > -1 : a.b} {...{
176176
directives: [{
@@ -195,12 +195,12 @@ const tests = [
195195
$$i = this._i($$a, $$v);
196196
197197
if ($$el.checked) {
198-
$$i < 0 && (a.b = $$a.concat([$$v]));
198+
$$i < 0 && this.$set(a, "b", $$a.concat([$$v]));
199199
} else {
200-
$$i > -1 && (a.b = $$a.slice(0, $$i).concat($$a.slice($$i + 1)));
200+
$$i > -1 && this.$set(a, "b", $$a.slice(0, $$i).concat($$a.slice($$i + 1)));
201201
}
202202
} else {
203-
a.b = $$c;
203+
this.$set(a, "b", $$c);
204204
}
205205
}} type="checkbox" domProps-checked={Array.isArray(a.b) ? this._i(a.b, "abc") > -1 : this._q(a.b, trueVal)} {...{
206206
directives: [{
@@ -214,7 +214,7 @@ const tests = [
214214
name: 'Generic input[type="radio"] vModel',
215215
from: `const A = <input type="radio" vModel={a.b} />`,
216216
to: `const A = <input on-change={$event => {
217-
a.b = null;
217+
this.$set(a, "b", null);
218218
}} type="radio" domProps-checked={this._q(a.b, null)} {...{
219219
directives: [{
220220
name: "model",
@@ -227,7 +227,7 @@ const tests = [
227227
name: 'input[type="radio"] vModel_number',
228228
from: `const A = <input type="radio" vModel_number={a.b} value="10" />`,
229229
to: `const A = <input on-change={$event => {
230-
a.b = this._n("10");
230+
this.$set(a, "b", this._n("10"));
231231
}} type="radio" domProps-checked={this._q(a.b, this._n("10"))} {...{
232232
directives: [{
233233
name: "model",
@@ -243,7 +243,7 @@ const tests = [
243243
from: `const A = <input type="text" vModel={a.b} />`,
244244
to: `const A = <input on-input={$event => {
245245
if ($event.target.composing) return;
246-
a.b = $event.target.value;
246+
this.$set(a, "b", $event.target.value);
247247
}} type="text" domProps-value={a.b} {...{
248248
directives: [{
249249
name: "model",
@@ -257,7 +257,7 @@ const tests = [
257257
from: `const A = <textarea vModel={a.b} />`,
258258
to: `const A = <textarea on-input={$event => {
259259
if ($event.target.composing) return;
260-
a.b = $event.target.value;
260+
this.$set(a, "b", $event.target.value);
261261
}} domProps-value={a.b} {...{
262262
directives: [{
263263
name: "model",
@@ -272,7 +272,7 @@ const tests = [
272272
to: `const A = <input on-blur={$event => {
273273
this.$forceUpdate();
274274
}} on-change={$event => {
275-
a.b = this._n($event.target.value.trim());
275+
this.$set(a, "b", this._n($event.target.value.trim()));
276276
}} type="text" domProps-value={a.b} {...{
277277
directives: [{
278278
name: "model",
@@ -289,7 +289,7 @@ const tests = [
289289
name: 'input[type="range"] vModel',
290290
from: `const A = <input type="range" vModel={a.b} />`,
291291
to: `const A = <input on-__r={$event => {
292-
a.b = $event.target.value;
292+
this.$set(a, "b", $event.target.value);
293293
}} type="range" domProps-value={a.b} {...{
294294
directives: [{
295295
name: "model",

0 commit comments

Comments
 (0)