- js事件循环:优先执行同步任务 然后是异步任务 异步任务优先执行宏任务 清空微任务队列 如此循环。
- 需求场景:父组件 子组件 孙子组件 获取用户的信息方法存在vuex里。
暂停思考一下:弹窗a 弹窗b哪个先弹出来?
答案:正常情况下弹窗b会优先弹出 因为$emit父子传值是同步任务会优先执行
而vuex的dispatch默认会返回一个Promise Promise回调函数是微任务会进入任务队列会后执行。 - 需求:业务需求弹窗a优先级高 先弹出来
- 思路:通过async await dispatch 等用户信息更新完成之后再抛全局事件。
- demo代码实现核心:
Parent:
<template> <Son></Son> </template> <script> import { Eventbus } from "@/utils/eventbus"; import Son from "./son.vue"; export default { data() { return {}; }, components: { Son, }, created() { Eventbus.$off("sonemit"); Eventbus.$on("sonemit", this.listSonEvent); }, methods: { listSonEvent() { this.$confirm("子组件发布事件,父组件监听到", "提示", { confirmButtonText: "确定", cancelButtonText: "取消", type: "warning", }) .then(() => { this.$message({ type: "success", message: "已确认", }); }) .catch(() => { this.$message({ type: "info", message: "已取消", }); }); }, }, }; </script> <style scoped lang="scss"></style>
Son:
<template> <Grandson @submit-success="submitSuccess"></Grandson> </template> <script> import Grandson from "./Grandson.vue"; import { Eventbus } from "@/utils/eventbus"; export default { data() { return {}; }, components: { Grandson, }, methods: { async submitSuccess(res) {
//这里不加async await 会呈现两种页面弹窗的效果
await this.$store.dispatch("user/GetUserInfo"); this.$nextTick(() => { Eventbus.$emit("sonemit"); }); }, }, }; </script> <style scoped lang="scss"></style>
GrandSon:
<template> <div> <el-button @click="subMit">孙子提交表单</el-button> </div> </template> <script> import { mapGetters } from "vuex"; import { getProduct } from "@/api"; export default { data() { return {}; }, computed: { ...mapGetters("user", ["userInfo"]), }, watch: { userInfo: { handler(val) { console.log("watch userInfo", val); if (val) { this.openModal(); } }, deep: true, }, }, methods: { openModal() { this.$confirm(`子组件异步修改全局用户信息更改触发的弹窗`, "提示", { confirmButtonText: "确定", cancelButtonText: "取消", type: "success", }) .then(() => { this.$message({ type: "success", message: "已确认", }); }) .catch(() => { this.$message({ type: "info", message: "已取消", }); }); }, async subMit() { try { const res = await getProduct(); console.log(res, ">>>"); if (res.status_code == 200) { this.$emit("submit-success", res.data); } } catch (err) {} }, }, }; </script> <style scoped lang="scss"></style>