vueJS3 - 如何触发来自兄弟组件的事件的函数
Posted
技术标签:
【中文标题】vueJS3 - 如何触发来自兄弟组件的事件的函数【英文标题】:vueJS3 - How to trigger a function on event from sibling component 【发布时间】:2021-08-01 06:54:06 【问题描述】:我想触发一个函数,只要按下同级组件中的按钮,GET
s 来自组件中的 http 服务器的数据。
SignUpForm.vue有一个按钮触发customSubmit()
customSubmit()
//POST to API
const user =
method: "POST",
headers: "Content-Type": "application/json",
body: JSON.stringify(newUser: this.newUser)
;
fetch("http://localhost:3080/api/user", user)
.then(response => response.json())
.then(data => console.log(data));
this.$emit('refresh', true)
this.clearForm();
父组件如下所示:
<template>
<div>
<SignUpForm @refresh="triggerRefresh($event)" />
<!-- <Exp /> -->
<Datatable :myRefresh="myRefresh" />
</div>
</template>
<script>
import SignUpForm from "./components/SignUpForm.vue";
import Datatable from "./components/Datatable.vue";
import Exp from "./components/exp copy.vue";
export default
name: "App",
components: Datatable, SignUpForm, Exp ,
data()
return
myRefresh: false,
;
,
methods:
triggerRefresh(bool)
this.myRefresh = bool;
console.log(this.myRefresh);
,
,
;
</script>
现在我想要兄弟组件 Datatable.vue
尽快从服务器到fetch
数据,因为this.$emit('refresh', true)
在SignUpForm.vue
中被触发
这是来自Datatable.vue
的脚本
export default
data()
return
//Liste aller User
userData: null,
//temporärer User für das Details-Feld
printUser: [ name: "", email: "", number: "" ],
//Property für den "read-Button"
showDetails: false,
//Property für den "Update-Button"
readOnly: true,
;
,
props: ["myRefresh"],
methods:
pushFunction()
fetch("http://localhost:3080/api/users")
.then((res) => res.json())
.then((data) => (this.userData = data));
,
readData(k)
this.printUser.length = 0;
this.showDetails = true;
this.printUser.push(this.userData[k]);
,
editData(rowUser)
if (!rowUser.readOnly)
rowUser.readOnly = true;
const user =
method: "PATCH",
headers: "Content-Type": "application/json" ,
body: JSON.stringify( userData: this.userData ),
;
fetch("http://localhost:3080/api/users/patch", user)
.then((response) => response.json())
.then((data) => console.log(data));
else
rowUser.readOnly = false;
,
deleteData(k)
fetch("http://localhost:3080/api/users/" + k, method: "DELETE" ).catch(
(err) => console.log(err)
);
this.pushFunction();
,
//blaue Reihen
toggleHighlight(rowUser)
if (rowUser.readOnly === false)
return;
rowUser.isHighlight = !rowUser.isHighlight;
,
scrollDown()
window.scrollTo(0, document.body.scrollHeight);
,
,
mounted()
fetch("http://localhost:3080/api/users")
.then((res) => res.json())
.then((data) => (this.userData = data));
,
;
我真的希望有人可以帮助新手!
【问题讨论】:
您可以将事件推送到父级,然后更新父级中的模型值,然后将其绑定到另一个组件。您通过父级执行此类操作的次数越多,您的应用程序(并绑定在一起)就越复杂。因此,您通常会为这样的事情使用外部状态,您可以在其中推送值并在另一个组件中自动检索它(通过计算值)。在 Vue2 中,您通常会选择 Vuex,但在 Vue3 中引入了一种非常好的新方法:组合 API,它可以让您外包本地状态。 我会看看组合 API,谢谢!您是否也有针对我的代码的特定解决方案? 在 Datatable 中为myRefresh
设置一个观察者,并且不要为该值传递布尔值,而是传递一个生成的值(例如 Math.random()
)。否则,您需要先发出 true,然后等待一个滴答声,然后将其重置为 false。如果值为真,您将需要检查 - 在观察者中。通过设置一个随机值,当值发生变化时,watch 处理程序就会被执行。如果要完全重新加载组件(不仅是重新获取数据),还可以使用组件的 :key=""
属性。一旦这个值改变,组件就会重新渲染。
你没有使用 VueJS3...利用setup
...
【参考方案1】:
两个考虑,有可能吗?和谨慎吗?
有可能吗?
是的,你可以通过几种不同的方式来实现它。
谨慎吗?
没有。
如果你走这条路,很可能架构是无效的。在理想的设置中,您的组件应该只负责管理视图。这意味着用户看到并收集他们的输入。 业务逻辑不应存在于组件中。因此,如果您有诸如 ajax 调用之类的东西并将它们放入您的组件中,那么您已经将逻辑耦合到了视图中。一个可能的问题是,如果由于某种原因重新添加了组件,则任何正在进行的 ajax 调用都可能以意想不到的方式中断。虽然可以处理这种情况,但恕我直言,更大的问题是,当您将业务逻辑与视图层耦合时,您正在创建一个越来越难以推理的应用程序;在兄弟组件之间发送事件时遇到的这个问题只是一个例子。
其他选项
虽然不是唯一的方法,但最常见的处理方法是通过Vuex
使用全局存储。
您可以调用 Vuex 操作,而不是从您的组件初始化 Ajax 请求。
该动作通常会使用单个状态变量(即loadState=STATE.STARTED
)或使用isLoading=true
设置加载状态,除了分配变量之外,vuex 会通过突变来完成,所以store.commit('setLoadState', STATE.LOADING)
。这将更新所有组件的状态,这些组件直接或使用 getter 侦听存储中的更改。然后发出 ajax 请求,完成后再次更新存储,使用store.commit('setLoadState', STATE.ERROR)
或成功时使用store.commit('setLoadState', STATE.DONE)
和store.commit('setUsers', response)
。那么你的组件只需要监听变化,$store.loadState == STATE.LOADING
就可以显示一个spinner
只要后续调用的数据与特定于组件的数据相关(例如特定的用户 ID 或名称),您就可以处理来自组件的下一次调用。您可以让组件watch
vuex 存储或数据以进行更改,而不是通过监视来自同级的事件来触发来自组件的第二个 API 请求。然后当$store.loadState
变为STATE.DONE
时,您可以为另一个API 调用触发另一个动作。我只会这样做,但如果有特定于 API 调用的数据的任何部分,否则如果调用在所有情况下都是正确的,您也可以将其作为同一操作的一部分调用
【讨论】:
以上是关于vueJS3 - 如何触发来自兄弟组件的事件的函数的主要内容,如果未能解决你的问题,请参考以下文章