JS + Vue3:模态对话框:调用函数返回的参数化函数
JS + Vue3: Modal dialog: call parameterized function returned by function
首先,我不确定这是一个 Vue 问题还是只是一个 JavaScript 相关问题。
我写了一些代码终于可以工作了,但我不知道为什么。或许你能赐教。
我创建了一个“对话框 window”组件。这是一个简单的(模态)对话框,它将函数作为参数。如果用户单击“确定”,则调用该函数——例如“您真的要删除该文件吗?”取消或确定。
我传递给组件的函数有时本身就有一个参数。
所以我想将已经 参数化的函数 作为参数传递给我的组件。
我通过将函数包装在箭头函数中来实现这一点,箭头函数 returns 然后可以调用参数化函数。
这个概念在纯JS中的思路是这样的:
//the function to be finally executed
function say(message) {
document.getElementById("output").innerHTML = message;
}
//the parameterized function inside of an arrow function (as a variable)
const sayhelloworld = () => say("hello world");
//finally I call the arrow function which
//returns the parameterized function and calls this one as well
function start() {
sayhelloworld()(); //this is the core of my question: the double brackets!
}
所以我需要双括号。第一个()returns里面的函数,第二个()调用它。
它确实像这样工作:
https://codepen.io/keztur/pen/powaLJN
现在让我们转向vue:
我用事件总线打开我的对话框组件(对此感到抱歉)并传递一个包含函数参数的参数对象。
(我使用 Vue 3 - 所以在我的 EventBus 对象后面实际上是 'mitt' 库:https://github.com/developit/mitt)
//component calling the dialog and passing the function parameter
//(as a part of a parameter object)
EventBus.emit("OpenDialog", {
header: "Delete file",
body: "Do you really want to delete that file?",
function: () => this.Delete(file_id)
});
模态组件:
data() {
return {
show: false,
ModalProps: {
header: "",
body: "",
function: ""
}
};
},
//inside of the modal component this function is called
//if the user clicks any of the two buttons (cancel or OK)
methods: {
clicked(button) {
if (button === 'ok' && typeof this.ModalProps.function === 'function') {
this.ModalProps.function(); //why does this work ...
//this.ModalProps.function()(); //...but not this?
//the second line does call the function but also throws an error afterwards
}
this.show = false; //modal is closed
}
},
... etc.
所以起初我在上面的 JS 示例中使用了双括号。该函数被正确调用,但第二个“执行”backets 显然抛出了一个错误:
[Vue warn]: Unhandled error during execution of native event handler
at <Modal>
at <App>
但是由于我删除了第二个括号,所以一切正常。
所以我的问题是:为什么在 Vue 中我的箭头函数中的函数会立即被调用而不只是通过引用返回?
您的第一个示例不起作用。它应该只是 sayhelloworld();
。在 运行 时打开(浏览器或代码笔)控制台。它会说:
TypeError: sayhelloworld() is not a function
它只是看起来有效,因为错误之后没有更多的事情要做。例如,尝试在 sayhelloworld()();
之后添加 alert("Done")
,您会注意到永远不会显示警报。
Vue 的区别在于 Vue 捕获并显示错误。
sayhelloworld
(以及您的 Vue 示例中的 this.ModalProps.function
)只是普通(引用)函数,没有 return 任何内容。
之间没有(*)区别
const sayhelloworld = () => say("hello world");
和
const sayhelloworld = function() {
say("hello world");
}
和
function sayhelloworld() {
say("hello world");
}
如果函数 return 本身就是一个函数,您将使用 ()()
,例如:
function sayhelloworld() {
const innerFunction = function () {
say("hello world");
}
return innerFunction;
}
或
function sayhelloworld() {
return () => say("hello world");
}
甚至
const sayhelloworld = () => () => say("hello world");
这些示例再次做同样的事情(*)。
(*) 它们并不完全相同,主要是关于 hoisting 以及如何在函数内部处理 this
,但这与此处无关。
首先,我不确定这是一个 Vue 问题还是只是一个 JavaScript 相关问题。 我写了一些代码终于可以工作了,但我不知道为什么。或许你能赐教。
我创建了一个“对话框 window”组件。这是一个简单的(模态)对话框,它将函数作为参数。如果用户单击“确定”,则调用该函数——例如“您真的要删除该文件吗?”取消或确定。
我传递给组件的函数有时本身就有一个参数。 所以我想将已经 参数化的函数 作为参数传递给我的组件。 我通过将函数包装在箭头函数中来实现这一点,箭头函数 returns 然后可以调用参数化函数。
这个概念在纯JS中的思路是这样的:
//the function to be finally executed
function say(message) {
document.getElementById("output").innerHTML = message;
}
//the parameterized function inside of an arrow function (as a variable)
const sayhelloworld = () => say("hello world");
//finally I call the arrow function which
//returns the parameterized function and calls this one as well
function start() {
sayhelloworld()(); //this is the core of my question: the double brackets!
}
所以我需要双括号。第一个()returns里面的函数,第二个()调用它。 它确实像这样工作: https://codepen.io/keztur/pen/powaLJN
现在让我们转向vue:
我用事件总线打开我的对话框组件(对此感到抱歉)并传递一个包含函数参数的参数对象。 (我使用 Vue 3 - 所以在我的 EventBus 对象后面实际上是 'mitt' 库:https://github.com/developit/mitt)
//component calling the dialog and passing the function parameter
//(as a part of a parameter object)
EventBus.emit("OpenDialog", {
header: "Delete file",
body: "Do you really want to delete that file?",
function: () => this.Delete(file_id)
});
模态组件:
data() {
return {
show: false,
ModalProps: {
header: "",
body: "",
function: ""
}
};
},
//inside of the modal component this function is called
//if the user clicks any of the two buttons (cancel or OK)
methods: {
clicked(button) {
if (button === 'ok' && typeof this.ModalProps.function === 'function') {
this.ModalProps.function(); //why does this work ...
//this.ModalProps.function()(); //...but not this?
//the second line does call the function but also throws an error afterwards
}
this.show = false; //modal is closed
}
},
... etc.
所以起初我在上面的 JS 示例中使用了双括号。该函数被正确调用,但第二个“执行”backets 显然抛出了一个错误:
[Vue warn]: Unhandled error during execution of native event handler
at <Modal>
at <App>
但是由于我删除了第二个括号,所以一切正常。
所以我的问题是:为什么在 Vue 中我的箭头函数中的函数会立即被调用而不只是通过引用返回?
您的第一个示例不起作用。它应该只是 sayhelloworld();
。在 运行 时打开(浏览器或代码笔)控制台。它会说:
TypeError: sayhelloworld() is not a function
它只是看起来有效,因为错误之后没有更多的事情要做。例如,尝试在 sayhelloworld()();
之后添加 alert("Done")
,您会注意到永远不会显示警报。
Vue 的区别在于 Vue 捕获并显示错误。
sayhelloworld
(以及您的 Vue 示例中的 this.ModalProps.function
)只是普通(引用)函数,没有 return 任何内容。
const sayhelloworld = () => say("hello world");
和
const sayhelloworld = function() {
say("hello world");
}
和
function sayhelloworld() {
say("hello world");
}
如果函数 return 本身就是一个函数,您将使用 ()()
,例如:
function sayhelloworld() {
const innerFunction = function () {
say("hello world");
}
return innerFunction;
}
或
function sayhelloworld() {
return () => say("hello world");
}
甚至
const sayhelloworld = () => () => say("hello world");
这些示例再次做同样的事情(*)。
(*) 它们并不完全相同,主要是关于 hoisting 以及如何在函数内部处理 this
,但这与此处无关。