I want to develop a small program that includes the following features:
- The initial Vue component named "Start.vue" should open a new window upon clicking a button
- The new window should consist of another component called "Playboard.vue"
- "Start.vue" should also send initialization parameters, input by users, to "Playboard.vue"
I am using Tauri's emit and listen API. Despite extensive console logging, I discovered that even though "Start.vue" emitted the "parameter-init" event, the other side failed to capture it, leading to the loading process of "Playboard.vue" getting stuck.
The code is presented below:
"Start.vue"
<script setup lang="ts">
import { ref } from "vue";
import { winConfig, Windows } from "./Window";
import { emit, listen } from "@tauri-apps/api/event";
import { parameterConfig } from "./Parameters";
const displayWindow: winConfig = {
label: 'playBoard',
others: {
// some window parameters
}
}
const w = ref("");
const h = ref("");
const m = ref("");
var windows: Windows = new Windows();
windows.listen();
async function start() {
const params: parameterConfig = {
width: w.value,
height: h.value,
}
await emit("tauri-win-create", displayWindow)
await emit("parameter-init", params)
}
</script>
<template>
<div class = "container" id="startarea">
<div class = "container" id="inputarea">
<p><input id="greet-input" v-model="w" placeholder="Width" /></p>
<p><input id="greet-input" v-model="h" placeholder="height" /></p>
<p><input id="greet-input" v-model="m" placeholder="number of mines" /></p>
</div>
<div id="clickarea">
<button type="button" @click="start" >Start</button>
</div>
</div>
</template>
Playboard.vue
<script setup lang="ts">
import Display from "./components/Display.vue";
import { listen, emit } from "@tauri-apps/api/event";
import { Parameter } from "./components/Parameters";
var params: Parameter = new Parameter();
params.listen();
</script>
<template>
<div class="container">
<div>
<Display :width="params.width" :height="params.height"/>
</div>
</div>
</template>
Window.ts
import { WebviewWindow, appWindow, getAll, WindowOptions } from '@tauri-apps/api/window'
import { emit, listen } from '@tauri-apps/api/event'
export type winConfig = {
label: string,
others: WindowOptions
}
export class Windows {
mainWin!: WebviewWindow;
getWin(label: string) {
return WebviewWindow.getByLabel(label)
}
getAllWin() {
return getAll()
}
async createWin(options: winConfig) {
let label = options.label
let args: WindowOptions = options.others
console.log(args)
const existWin = getAll().find(w => w.label == label)
if(existWin) {
if(existWin.label.indexOf('main') == -1) {
await existWin?.unminimize()
await existWin?.setFocus()
return
}
await existWin?.close()
}
let win = new WebviewWindow(label, args)
win.once('tauri://created', async() => {
console.log('window create success!')
})
win.once('tauri://error', async() => {
console.log('window create error!')
})
}
async listen() {
await listen<winConfig>('tauri-win-create', (event) => {
console.log(event)
this.createWin(event.payload)
})
}
}
Parameters.ts
import { listen } from '@tauri-apps/api/event'
import { event } from '@tauri-apps/api'
export type parameterConfig = {
width: string,
height: string
}
export class Parameter {
width: number = 0
height: number = 0
init(p: parameterConfig) {
this.width = Number(p.width)
this.height = Number(p.height)
}
async listen() {
await listen<parameterConfig>('parameter-init', (event) => {
console.log(event.payload)
this.init(event.payload)
})
}
}
- One approach I attempted was to emit from "Parameters.ts" and then wait for "Start.vue" to receive the signal before emitting. However, being new to this, I am struggling with understanding the async/await operations.
- I also experimented with removing the listen function in "Playboard.vue" and instead used static binding for root props, which seemed to solve the issue. I suspect the problem lies in how async/await and emit/listen are being handled.
What is the root cause of this issue? And what would be the best practice to achieve this functionality seamlessly?