var render = function () {
var _vm = this
var _h = _vm.$createElement
var _c = _vm._self._c || _h
return _c("div", {
on: {
click: function click($event) {
var _vm$handler, _vm
;(_vm$handler = (_vm = _vm).handler) === null || _vm$handler === void 0
? void 0
: _vm$handler.call(_vm)
},
},
})
}
Inside function click, babel transforms optional function call expression using a temporary variable _vm, which collides with the _vm declaration outside. So the inner _vm will be undefined, leading to a reading property of undefined error.
Note: this error only occurs in event handler, because in Vue2 if event handler is not a single identifier, the expression will be wrapped with a function, which may lose this.
Expected behavior
Work as intended.
Usage
Extra
If we use babel repl, we can see _vm.a?.() will be transformed into:
Babel used a different identifier _vm2 to avoid collision. But in this project, when using parseWithStatementToVm, babel behaves differently.
After debugging, I found babel will go through a crawling process on the original source code when transformSync is called, during which the _vm will be added to the current scope as global identifier:
So when babel knows _vm can't be used as a temporary variable. But in this project, _vm. is prepended to handler by the custom plugin on the run (and the _vm declaration is inserted after all the transforms), which missed the crawling process.
So maybe we should call addGlobal manually to fix this?
(Or we should insert var _vm = this before all the transformation happens?)
Current behavior
will be transformed to:
Inside
function click
, babel transforms optional function call expression using a temporary variable_vm
, which collides with the_vm
declaration outside. So the inner_vm
will be undefined, leading to areading property of undefined
error.Note: this error only occurs in event handler, because in Vue2 if event handler is not a single identifier, the expression will be wrapped with a function, which may lose
this
.Expected behavior
Work as intended.
Usage
Extra
If we use babel repl, we can see
_vm.a?.()
will be transformed into:Babel used a different identifier
_vm2
to avoid collision. But in this project, when usingparseWithStatementToVm
, babel behaves differently.After debugging, I found babel will go through a
crawling
process on the original source code whentransformSync
is called, during which the_vm
will be added to the current scope as global identifier:So when babel knows
_vm
can't be used as a temporary variable. But in this project,_vm.
is prepended tohandler
by the custom plugin on the run (and the_vm
declaration is inserted after all the transforms), which missed thecrawling
process.So maybe we should call
addGlobal
manually to fix this? (Or we should insertvar _vm = this
before all the transformation happens?)I will create a PR soon.