Go Wails 桌面開發之 Go 與 Preact 如何協作通信?

上一篇文章裏我們簡單的瞭解了 Wails,在本篇文章裏將帶你從 0 開始,藉助 Wails 框架構建一個前後端分離的 Todo 應用,前端用 Preact,後端使用 Go,並講解它們之間的通信機制與數據傳遞方式。閒話少說,開始今天的內容,let's go!!!

Wails 框架如何工作?

在 Wails 中,前端通過 WebView 渲染頁面,後端通過 Go 提供邏輯支持。它的工作流程如下:

通信簡圖如下:

用戶界面 (Preact)
     │
     ▼
JS Bridge (Wails JS Runtime)
     │
     ▼
Go 後端邏輯

構建一個簡單的 Todo 應用

我們使用 wail init 命令初始化一個名爲 todo 的項目 ,命令具體如下所示:

wails init -n todo -t preact-ts

這裏選擇的前端模版是 preact-ts,它比較輕量級,語法上跟 react 可能不太一樣,但是整體相同。

項目創建好之後進入到項目目錄,創建 todo 目錄和 todo.go 文件,具體如下圖所示:

在 todo.go 文件裏,鍵入如下代碼

package todo
type Todo struct {
	ID    int    `json:"id"`
	Title string `json:"title"`
	Done  bool   `json:"done"`
}
type TodoService struct {
	todos  []Todo
	nextID int
}
func NewTodoService() *TodoService {
return &TodoService{
		todos:  []Todo{},
		nextID: 1,
	}
}
func (t *TodoService) GetTodos() []Todo {
return t.todos
}
func (t *TodoService) AddTodo(title string) Todo {
	todo := Todo{
		ID:    t.nextID,
		Title: title,
		Done:  false,
	}
	t.todos = append(t.todos, todo)
	t.nextID++
return todo
}
func (t *TodoService) ToggleTodo(id int) []Todo {
for i, item := range t.todos {
if item.ID == id {
			t.todos[i].Done = !item.Done
break
		}
	}
return t.todos
}

完事之後,我們需要將 todo 中的 NewTodoService 註冊到 wails 中,具體操作如下

package main
import (
     "embed"
     "todo/todo"
     "github.com/wailsapp/wails/v2"
     "github.com/wailsapp/wails/v2/pkg/options"
     "github.com/wailsapp/wails/v2/pkg/options/assetserver"
)
//go:embed all:frontend/dist
var assets embed.FS
func main() {
     // Create an instance of the app structure
     //app := NewApp() // 註釋掉wails生成的app
     server := todo.NewTodoService()
     // Create application with options
     err := wails.Run(&options.App{
          Title:  "todo",
          Width:  1024,
          Height: 768,
          AssetServer: &assetserver.Options{
               Assets: assets,
          },
          BackgroundColour: &options.RGBA{R: 27, G: 38, B: 54, A: 1},
          //OnStartup:        app.startup,
          Bind: []interface{}{
               server, // 將server實例註冊綁定到wails中
          },
     })
     if err != nil {
          println("Error:", err.Error())
     }
}

這時候運行 wails dev 就可以將我們 todo 裏寫的 go 代碼生成 js,用於和前端進行一個綁定,當然了,一般實際開發中並不會使用 wails dev 來生成,而是使用 wails generate module 命令來生成。而生成的代碼都被放在了 wailsjs/go 目錄下,具體如下圖所示:

代碼生成好了之後我們編寫前端代碼,並在裏面調用我們生成的 go 綁定代碼,具體如下所示:

import { h } from 'preact'
import { useEffect, useState } from 'preact/hooks'
import { AddTodo, GetTodos, ToggleTodo } from '../wailsjs/go/todo/TodoService'
interface Todo {
  id: number
  title: string
  done: boolean
}
export default function App() {
  const [todos, setTodos] = useState<Todo[]>([])
  const [input, setInput] = useState('')
  useEffect(() ={
    refreshTodos()
  }, [])
  const refreshTodos = () => {
    GetTodos().then(setTodos)
  }
  const add = () => {
    if (!input) return
    AddTodo(input).then(() ={
      setInput('')
      refreshTodos()
    })
  }
  const toggle = (id: number) => {
    ToggleTodo(id).then(setTodos)
  }
  return (
    <div class>
      <h1 class>📝 Todo List</h1>
      <input
        class
        placeholder="Enter todo"
        value={input}
        onInput={(e: any) => setInput(e.target.value)}
      />
      <button class onClick={add}>Add</button>
      <ul class>
        {todos.map(todo => (
          <li
            key={todo.id}
            className={`cursor-pointer ${todo.done ? 'line-through text-gray-500' : ''}`}
            onClick={() => toggle(todo.id)}
          >
            {todo.title}
          </li>
        ))}
      </ul>
    </div>
  )
}

最後運行 wails dev 命令,讓我們來見證時刻的奇蹟吧!!!

結語

Wails 是前後端集成的利器。通過本文你瞭解了:

看到這,各位帥哥靚女可能都明白了,這東西擺明換湯不換藥,這個跟平常前後端沒啥兩樣的,如同生氣的她,多提醒一下,多喝熱水對身體好。今天的內容到此結束,感謝🙏您的收看🌹🌹🌹,下次再見👋

本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源https://mp.weixin.qq.com/s/WDCV33WkAjNmV6M93xAJ3Q