uni-app uses $on $emit for cross-page information transfer, with Vue23 writing.
Recently, I saw a user on the ask community asking how to correctly use the $emit
$on
methods to achieve communication between uni-app program pages. Some users found that they couldn't receive messages using $on
, so I'm trying to summarize the best practices here for users who have similar confusion.
Who needs to read this article#
Application-level cross-page communication, for various reasons, decides to use $on/$emit
for data transmission in the usage scenario.
Common problem scenarios#
When jumping from page A to page B, you need to carry a part of complex object information. Define $emit
on page A and $on
on page B. After jumping to the page, it is found that page B cannot receive the event. It can be received by returning to the page and jumping again. And some users found that they can use setTimeout
after a delay.
This method is not reliable. After all, when the event is sent from page A, page B has not been initialized yet, so naturally it cannot receive the relevant event.
Here are two solutions for users with different business needs.
Solution 1: Shake hands before sending#
Demo code address: https://gitcode.net/xiurensha5731/uni-app-questions/-/tree/q/api-emit/src/pages
Observe the index page and about page.
On the index page, which is the page1 page, register the $on
event first, and send the specific data when the callback function is called.
// This is a demonstration. When jumping from index to about, pass the information
const go = () => {
uni.navigateTo({
url: "/pages/about/index?msg=hello",
});
};
onLoad(() => {
// The idea is to register the listener first and then send the information. At this time, it is page2
// After the jump, the page will be activated and the on event will be received
uni.$on("page2Ready", function (data) {
console.log("page1 received the information sent by page2", data);
uni.$emit("update", { msg: "Page updated" });
});
});
onUnload(() => {
uni.$off("page2Ready");
});
On the about page, which is the page2 page. Register the event first, and then notify page1 to accept the information.
const message = ref("");
onLoad(() => {
uni.$on("update", function (data) {
console.log("page2 listens to the event from update, with the parameter msg as: " + data.msg);
message.value = data.msg;
});
uni.$emit("page2Ready", { msg: "page2 is ready, you can send it" });
});
onUnload(() => {
uni.$off("update");
});
Refer to the above link for the complete code.
Solution 2: Use uni.navigateTo
events#
Official documentation address: https://uniapp.dcloud.net.cn/api/router.html#navigateto
Search for the keyword "events" to locate the usage.
Here is also the online running address, git address to observe the index page and about page.
On the index page, which is the page1 page
// This is a demonstration. When jumping from index to about, pass the information
const go = () => {
uni.navigateTo({
url: "/pages/about/index?msg=hello",
events: {
// Can receive notifications from the next page
page1: function (data) {
console.log(444, data);
},
},
success: function (res) {
// Send data to the opened page through eventChannel
res.eventChannel.emit("page2", { data: "Information sent by page1" });
},
});
};
On the about page, which is the page2 page, here are two writing methods: option and composition.
// Vue 3 setup writing method
const message = ref("");
// Vue 3 setup writing method
onLoad(() => {
const { proxy } = getCurrentInstance();
const eventChannel = proxy.getOpenerEventChannel();
eventChannel.emit("page1", { data: "data from test page" });
// Listen for the acceptDataFromOpenerPage event to get the data transmitted from the previous page to the current page through eventChannel
eventChannel.on("page2", (data) => {
console.log(222, data.data);
message.value = data.data;
});
});
// Vue 2 writing method
// export default {
// data() {
// return { message: "" };
// },
// onLoad(option) {
// const _this = this;
// const eventChannel = this.getOpenerEventChannel();
// eventChannel.emit("page1", { data: "data from test page" });
// // Listen for the acceptDataFromOpenerPage event to get the data transmitted from the previous page to the current page through eventChannel
// eventChannel.on("page2", (data) => {
// console.log(222, data.data);
// _this.message = data.data;
// });
// },
// };
Technical Summary#
Both of the above solutions can use emit and on to achieve page information transmission, which can be referred to by users who encounter similar problems.