refactor: refactor templates entirely using TypeScript

reslove: https://github.com/misitebao/wails-template-vue/issues/35
This commit is contained in:
Misite Bao 2022-08-22 19:24:13 +08:00
parent c24040515b
commit e04d43d3d8
108 changed files with 8736 additions and 1723 deletions

15
frontend/.eslintrc.cjs Normal file
View File

@ -0,0 +1,15 @@
/* eslint-env node */
require("@rushstack/eslint-patch/modern-module-resolution");
module.exports = {
root: true,
extends: [
"plugin:vue/vue3-essential",
"eslint:recommended",
"@vue/eslint-config-typescript/recommended",
"@vue/eslint-config-prettier",
],
parserOptions: {
ecmaVersion: "latest",
},
};

27
frontend/.gitignore vendored
View File

@ -1 +1,28 @@
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
lerna-debug.log*
node_modules
.DS_Store
dist
dist-ssr
coverage
*.local
/cypress/videos/
/cypress/screenshots/
# Editor directories and files
.vscode/*
!.vscode/extensions.json
.idea
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?

46
frontend/README.md Normal file
View File

@ -0,0 +1,46 @@
# vue
This template should help get you started developing with Vue 3 in Vite.
## Recommended IDE Setup
[VSCode](https://code.visualstudio.com/) + [Volar](https://marketplace.visualstudio.com/items?itemName=Vue.volar) (and disable Vetur) + [TypeScript Vue Plugin (Volar)](https://marketplace.visualstudio.com/items?itemName=Vue.vscode-typescript-vue-plugin).
## Type Support for `.vue` Imports in TS
TypeScript cannot handle type information for `.vue` imports by default, so we replace the `tsc` CLI with `vue-tsc` for type checking. In editors, we need [TypeScript Vue Plugin (Volar)](https://marketplace.visualstudio.com/items?itemName=Vue.vscode-typescript-vue-plugin) to make the TypeScript language service aware of `.vue` types.
If the standalone TypeScript plugin doesn't feel fast enough to you, Volar has also implemented a [Take Over Mode](https://github.com/johnsoncodehk/volar/discussions/471#discussioncomment-1361669) that is more performant. You can enable it by the following steps:
1. Disable the built-in TypeScript Extension
1) Run `Extensions: Show Built-in Extensions` from VSCode's command palette
2) Find `TypeScript and JavaScript Language Features`, right click and select `Disable (Workspace)`
2. Reload the VSCode window by running `Developer: Reload Window` from the command palette.
## Customize configuration
See [Vite Configuration Reference](https://vitejs.dev/config/).
## Project Setup
```sh
npm install
```
### Compile and Hot-Reload for Development
```sh
npm run dev
```
### Type-Check, Compile and Minify for Production
```sh
npm run build
```
### Lint with [ESLint](https://eslint.org/)
```sh
npm run lint
```

1
frontend/env.d.ts vendored Normal file
View File

@ -0,0 +1 @@
/// <reference types="vite/client" />

View File

@ -4,7 +4,7 @@
<meta charset="UTF-8" />
<link rel="icon" href="/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title><%- title %></title>
<title>{{.ProjectName}}</title>
</head>
<body>
<div id="app"></div>

7892
frontend/package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

35
frontend/package.json Normal file
View File

@ -0,0 +1,35 @@
{
"name": "vue",
"version": "0.0.0",
"private": true,
"scripts": {
"dev": "vite",
"build": "run-p type-check build-only",
"preview": "vite preview --port 4173",
"build-only": "vite build",
"type-check": "vue-tsc --noEmit",
"lint": "eslint . --ext .vue,.js,.jsx,.cjs,.mjs,.ts,.tsx,.cts,.mts --fix --ignore-path .gitignore"
},
"dependencies": {
"pinia": "^2.0.17",
"vue": "^3.2.37",
"vue-i18n": "^9.2.2",
"vue-router": "^4.1.3"
},
"devDependencies": {
"@rushstack/eslint-patch": "^1.1.4",
"@types/node": "^16.11.47",
"@vitejs/plugin-vue": "^3.0.1",
"@vitejs/plugin-vue-jsx": "^2.0.0",
"@vue/eslint-config-prettier": "^7.0.0",
"@vue/eslint-config-typescript": "^11.0.0",
"@vue/tsconfig": "^0.1.3",
"eslint": "^8.21.0",
"eslint-plugin-vue": "^9.3.0",
"npm-run-all": "^4.1.5",
"prettier": "^2.7.1",
"typescript": "~4.7.4",
"vite": "^3.0.4",
"vue-tsc": "^0.39.5"
}
}

View File

@ -1,17 +0,0 @@
{
"name": "{{.ProjectName}}",
"private": true,
"version": "0.1.0",
"description": "A Wails Template",
"main": "",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "{{.AuthorName}}",
"license": "MIT",
"workspaces": ["packages/*"],
"engines": {
"node": ">=15.0.0",
"npm": ">=7.0.0"
}
}

View File

@ -1,5 +0,0 @@
node_modules
.DS_Store
# dist
dist-ssr
*.local

View File

@ -1,3 +0,0 @@
{
"recommendations": ["johnsoncodehk.volar"]
}

View File

@ -1,7 +0,0 @@
# Vue 3 + Vite
This template should help get you started developing with Vue 3 in Vite. The template uses Vue 3 `<script setup>` SFCs, check out the [script setup docs](https://v3.vuejs.org/api/sfc-script-setup.html#sfc-script-setup) to learn more.
## Recommended IDE Setup
- [VSCode](https://code.visualstudio.com/) + [Volar](https://marketplace.visualstudio.com/items?itemName=johnsoncodehk.volar)

View File

@ -1,13 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<link rel="icon" href="/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title><%- title %></title>
</head>
<body>
<div id="app"></div>
<script type="module" src="/src/main.js"></script>
</body>
</html>

View File

@ -1,22 +0,0 @@
{
"name": "js",
"version": "0.1.0",
"scripts": {
"dev": "vite",
"build": "vite build --emptyOutDir",
"build:dev": "vite build --mode development --emptyOutDir",
"build:dev:watch": "vite build --mode development --watch --emptyOutDir",
"preview": "vite preview"
},
"dependencies": {
"vue": "^3.2.31",
"vue-i18n": "^9.1.9",
"vue-router": "^4.0.12"
},
"devDependencies": {
"@vitejs/plugin-vue": "^2.3.1",
"sass": "^1.49.9",
"vite": "^2.9.2",
"vite-plugin-html": "^3.2.0"
}
}

View File

@ -1,203 +0,0 @@
<template>
<!-- Header -->
<!-- 头部 -->
<div class="header" data-wails-drag>
<!-- navigation -->
<!-- 导航 -->
<div class="nav" data-wails-no-drag>
<router-link to="/">{{ t("nav.home") }}</router-link>
<router-link to="/about">{{ t("nav.about") }}</router-link>
</div>
<!-- Menu -->
<!-- 菜单 -->
<div class="menu" data-wails-no-drag>
<div class="language">
<div
v-for="item in languages"
:key="item"
:class="{ active: item === locale }"
@click="onclickLanguageHandle(item)"
class="lang-item"
>
{{ t("languages." + item) }}
</div>
</div>
<div class="bar">
<div class="bar-btn" @click="onclickMinimise">
{{ t("topbar.minimise") }}
</div>
<div class="bar-btn" @click="onclickQuit">{{ t("topbar.quit") }}</div>
</div>
</div>
</div>
<!-- Page -->
<!-- 页面 -->
<div class="view">
<router-view />
</div>
</template>
<script>
import { useI18n } from "vue-i18n";
export default {
setup() {
const { t, availableLocales, locale } = useI18n();
// List of supported languages
//
const languages = availableLocales;
// Click to switch language
//
const onclickLanguageHandle = (item) => {
item !== locale.value ? (locale.value = item) : false;
};
const onclickMinimise = () => {
window.runtime.WindowMinimise();
};
const onclickQuit = () => {
window.runtime.Quit();
};
return {
t,
languages,
locale,
onclickLanguageHandle,
onclickMinimise,
onclickQuit,
};
},
};
</script>
<style lang="scss">
@import url("./assets/css/reset.css");
@import url("./assets/css/font.css");
html {
width: 100%;
height: 100%;
}
body {
width: 100%;
height: 100%;
margin: 0;
padding: 0;
font-family: "JetBrainsMono";
background-color: transparent;
}
#app {
position: relative;
// width: 900px;
// height: 520px;
height: 100%;
background-color: rgba(219, 188, 239, 0.9);
overflow: hidden;
}
.header {
display: flex;
flex-direction: row;
flex-wrap: nowrap;
align-items: center;
justify-content: space-between;
height: 50px;
padding: 0 10px;
background-color: rgba(171, 126, 220, 0.9);
.nav {
a {
display: inline-block;
min-width: 50px;
height: 30px;
line-height: 30px;
padding: 0 5px;
margin-right: 8px;
background-color: #ab7edc;
border-radius: 2px;
text-align: center;
text-decoration: none;
color: #000000;
font-size: 14px;
white-space: nowrap;
&:hover,
&.router-link-exact-active {
background-color: #d7a8d8;
color: #ffffff;
}
}
}
.menu {
display: flex;
flex-direction: row;
flex-wrap: nowrap;
align-items: center;
justify-content: space-between;
.language {
margin-right: 20px;
border-radius: 2px;
background-color: #c3c3c3;
overflow: hidden;
.lang-item {
display: inline-block;
min-width: 50px;
height: 30px;
line-height: 30px;
padding: 0 5px;
background-color: transparent;
text-align: center;
text-decoration: none;
color: #000000;
font-size: 14px;
&:hover {
background-color: #ff050542;
cursor: pointer;
}
&.active {
background-color: #ff050542;
color: #ffffff;
cursor: not-allowed;
}
}
}
.bar {
display: flex;
flex-direction: row;
flex-wrap: nowrap;
align-items: center;
justify-content: flex-end;
min-width: 150px;
.bar-btn {
display: inline-block;
min-width: 80px;
height: 30px;
line-height: 30px;
padding: 0 5px;
margin-left: 8px;
background-color: #ab7edc;
border-radius: 2px;
text-align: center;
text-decoration: none;
color: #000000;
font-size: 14px;
&:hover {
background-color: #d7a8d8;
color: #ffffff;
cursor: pointer;
}
}
}
}
}
.view {
position: absolute;
top: 50px;
left: 0;
right: 0;
bottom: 0;
overflow: hidden;
}
</style>

View File

@ -1,4 +0,0 @@
@font-face {
font-family: "JetBrainsMono";
src: url("../fonts/JetBrainsMono-Medium.woff2");
}

View File

@ -1,124 +0,0 @@
html,
body,
div,
span,
applet,
object,
iframe,
h1,
h2,
h3,
h4,
h5,
h6,
p,
blockquote,
pre,
a,
abbr,
acronym,
address,
big,
cite,
code,
del,
dfn,
em,
img,
ins,
kbd,
q,
s,
samp,
small,
strike,
strong,
sub,
sup,
tt,
var,
b,
u,
i,
center,
dl,
dt,
dd,
ol,
ul,
li,
fieldset,
form,
label,
legend,
table,
caption,
tbody,
tfoot,
thead,
tr,
th,
td,
article,
aside,
canvas,
details,
embed,
figure,
figcaption,
footer,
header,
hgroup,
menu,
nav,
output,
ruby,
section,
summary,
time,
mark,
audio,
video {
margin: 0;
padding: 0;
border: 0;
font-size: 100%;
font: inherit;
vertical-align: baseline;
}
/* HTML5 display-role reset for older browsers */
article,
aside,
details,
figcaption,
figure,
footer,
header,
hgroup,
menu,
nav,
section {
display: block;
}
body {
line-height: 1;
}
ol,
ul {
list-style: none;
}
blockquote,
q {
quotes: none;
}
blockquote:before,
blockquote:after,
q:before,
q:after {
content: "";
content: none;
}
table {
border-collapse: collapse;
border-spacing: 0;
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 94 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

View File

@ -1,23 +0,0 @@
<template>
<div class="hello-world" v-text="msg"></div>
</template>
<script>
export default {
name: "HelloWorld",
props: {
msg: String,
},
};
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
.hello-world {
height: 76px;
line-height: 38px;
margin: 16px 150px;
text-align: center;
font-size: 26px;
}
</style>

View File

@ -1,33 +0,0 @@
<template>
<span class="openlink" @click="onClickhandle">
<slot></slot>
</span>
</template>
<script>
export default {
name: "OpenLink",
props: {
href: String,
},
setup(props) {
const onClickhandle = () => {
// You cannot use the a tag directly, you need to call the Go method here to open the link using the default browser.
// 使aGo使
window.runtime.BrowserOpenURL(props.href);
};
return {
onClickhandle,
};
},
};
</script>
<style lang="scss">
.openlink {
cursor: pointer;
text-decoration: underline;
}
</style>

View File

@ -1,10 +0,0 @@
import OpenLink from "@/components/public/OpenLink.vue";
// Encapsulate global components as plug-ins
// 将全局组件封装为插件
export default {
install(app) {
app.component(OpenLink.name, OpenLink);
},
};

View File

@ -1,18 +0,0 @@
import { createI18n } from "vue-i18n";
import zhHans from "./locales/zh-Hans.json";
import en from "./locales/en.json";
import fr from "./locales/fr.json";
const i18n = createI18n({
locale: "en",
fallbackLocale: "en",
legacy:false,
messages: {
"zh-Hans": zhHans,
en: en,
fr: fr,
},
});
export default i18n;

View File

@ -1,32 +0,0 @@
{
"nav": {
"home": "Home",
"about": "About"
},
"languages": {
"en": "English",
"zh-Hans": "简体中文",
"fr": "Français"
},
"topbar": {
"minimise": "Minimise",
"quit": "Quit"
},
"homepage": {
"welcome": "Welcome to use Wails program developed based on Vue",
"getting-started": "Getting Started",
"star-me": "Github"
},
"aboutpage": {
"title": "Wails Template Vue",
"project-repository": "Project Repository",
"author": "Author",
"misitebao": "Misitebao",
"wails-repository": "Wails Repository",
"thanks": "Thank you all for your support🙏!"
},
"global": {
"not-supported": "Because it is a beta version, it can't be done for the time being, it will be completed later.",
"click-link": "The currently clicked link is: "
}
}

View File

@ -1,32 +0,0 @@
{
"nav": {
"home": "Page d'accueil",
"about": "À propos"
},
"languages": {
"en": "English",
"zh-Hans": "简体中文",
"fr": "Français"
},
"topbar": {
"minimise": "Minimiser",
"quit": "Quitter"
},
"homepage": {
"welcome": "Bienvenue à utiliser le programme Wails développé sur la base de Vue",
"getting-started": "Commencer",
"star-me": "Github"
},
"aboutpage": {
"title": "Wails Template Vue",
"project-repository": "Référentiel de projets",
"author": "Auteur",
"misitebao": "Misitebao",
"wails-repository": "Wails Dépôt",
"thanks": "Merci à tous pour votre soutien🙏!"
},
"global": {
"not-supported": "Parce qu'il s'agit d'une version bêta, cela ne peut pas être fait pour le moment, il sera complété plus tard.",
"click-link": "Le lien actuellement cliqué est: "
}
}

View File

@ -1,32 +0,0 @@
{
"nav": {
"home": "主页",
"about": "关于"
},
"languages": {
"en": "English",
"zh-Hans": "简体中文",
"fr": "Français"
},
"topbar": {
"minimise": "最小化",
"quit": "退出"
},
"homepage": {
"welcome": "欢迎使用基于Vue开发的Wails程序",
"getting-started": "快速入门",
"star-me": "Github"
},
"aboutpage": {
"title": "Wails Template Vue",
"project-repository": "项目仓库",
"author": "作者",
"misitebao": "米司特包",
"wails-repository": "Wails 仓库",
"thanks": "感谢各位大佬的支持🙏!"
},
"global": {
"not-supported": "由于是测试版,所以暂时做不了,后续会完成它。",
"click-link": "当前点击的链接是: "
}
}

View File

@ -1,14 +0,0 @@
import { createApp } from "vue";
import App from "./App.vue";
import router from "@/router";
import i18n from "@/i18n";
// Register global common components
// 注册全局通用组件
import publicComponents from "@/components/public";
const app = createApp(App);
app.use(publicComponents);
app.use(router).use(i18n).mount("#app");

View File

@ -1,27 +0,0 @@
import { createRouter, createWebHashHistory } from "vue-router";
import Home from "@/views/Home.vue";
const routes = [
{
path: "/",
name: "Home",
component: Home,
},
{
path: "/about",
name: "About",
// route level code-splitting
// this generates a separate chunk (about.[hash].js) for this route
// which is lazy-loaded when the route is visited.
component: function () {
return import(/* webpackChunkName: "about" */ "../views/About.vue");
},
},
];
const router = createRouter({
history: createWebHashHistory(),
routes,
});
export default router;

View File

@ -1,103 +0,0 @@
<template>
<div class="about">
<!-- Title -->
<div class="title">{{ t("aboutpage.title") }}</div>
<!-- Information -->
<!-- 信息 -->
<div class="content">
<div class="comeon">
<img :src="comeonGif" alt="Gif" />
</div>
<ul class="info">
<li class="info-item">
<div class="name">{{ t("aboutpage.project-repository") }}</div>
<OpenLink
class="link"
href="https://github.com/misitebao/wails-template-vue"
>https://github.com/misitebao/wails-template-vue</OpenLink
>
</li>
<li class="info-item">
<div class="name">{{ t("aboutpage.wails-repository") }}</div>
<OpenLink class="link" href="https://github.com/wailsapp/wails"
>https://github.com/wailsapp/wails</OpenLink
>
</li>
<li class="info-item">
<div class="name">{{ t("aboutpage.author") }}</div>
<OpenLink class="link" href="https://github.com/misitebao">{{
t("aboutpage.misitebao")
}}</OpenLink>
</li>
</ul>
</div>
<!-- Thanks -->
<!-- 谢语 -->
<div class="thank">{{ t("aboutpage.thanks") }}</div>
</div>
</template>
<script>
import { useI18n } from "vue-i18n";
import comeonGif from "@/assets/images/comeon.gif";
export default {
setup() {
const { t } = useI18n();
return {
t,
comeonGif,
};
},
};
</script>
<style lang="scss">
.about {
.title {
margin: 30px auto 10px;
font-size: 38px;
color: #a150b5;
text-align: center;
}
.content {
position: relative;
margin: 36px 20px;
.comeon {
position: absolute;
left: 26px;
top: 38px;
max-width: 66%;
img {
width: 220px;
height: 180px;
}
}
.info {
margin: 0 0 0 33%;
font-size: 24px;
text-align: left;
.info-item {
margin-bottom: 10px;
.name {
line-height: 40px;
font-size: 28px;
color: #6d6363;
}
.link {
line-height: 30px;
font-size: 20px;
color: #5f6c86;
}
}
}
}
.thank {
height: 68px;
line-height: 68px;
margin: 36px auto;
text-align: center;
font-size: 40px;
}
}
</style>

View File

@ -1,86 +0,0 @@
<template>
<div class="home">
<!-- Logo -->
<img class="logo" alt="Vue logo" src="../assets/logo.png" />
<HelloWorld :msg="t('homepage.welcome')" />
<!-- Bottom button -->
<!-- 底部按钮 -->
<div class="link">
<OpenLink
href="https://wails.io/docs/gettingstarted/installation"
class="btn start"
>{{ t("homepage.getting-started") }}</OpenLink
>
<OpenLink
href="https://github.com/misitebao/wails-template-vue"
class="btn star"
>{{ t("homepage.star-me") }}</OpenLink
>
</div>
</div>
</template>
<script>
import { useI18n } from "vue-i18n";
import HelloWorld from "@/components/HelloWorld.vue";
export default {
name: "Home",
components: {
HelloWorld,
},
setup() {
const { t } = useI18n();
return {
t,
};
},
};
</script>
<style lang="scss">
.home {
.logo {
display: block;
width: 620px;
height: 280px;
margin: 10px auto 10px;
}
.link {
display: flex;
flex-direction: row;
flex-wrap: nowrap;
align-items: center;
justify-content: center;
margin: 18px auto;
.btn {
display: block;
width: 150px;
height: 50px;
line-height: 50px;
padding: 0 5px;
margin: 0 30px;
border-radius: 8px;
text-align: center;
font-weight: 700;
font-size: 16px;
white-space: nowrap;
text-decoration: none;
cursor: pointer;
&.start {
background-color: #fd0404;
color: #ffffff;
&:hover {
background-color: #ec2e2e;
}
}
&.star {
background-color: #ffffff;
color: #fd0404;
&:hover {
background-color: #f3f3f3;
}
}
}
}
}
</style>

View File

@ -1,37 +0,0 @@
import { defineConfig } from "vite";
import vue from "@vitejs/plugin-vue";
import path from "path";
import pkg from "../../package.json";
import { createHtmlPlugin } from "vite-plugin-html";
// https://vitejs.dev/config/
export default defineConfig({
plugins: [
vue(),
createHtmlPlugin({
minify: false,
// entry: "src/main.js",
template: "index.html",
inject: {
data: {
title: `${pkg.name}`,
},
},
}),
],
resolve: {
alias: {
"@": path.resolve(__dirname, "src"),
},
},
build: {
outDir: "../../dist",
rollupOptions: {
output: {
entryFileNames: `assets/[name].js`,
chunkFileNames: `assets/[name].js`,
assetFileNames: `assets/[name].[ext]`,
},
},
},
});

View File

@ -1,5 +0,0 @@
node_modules
.DS_Store
dist
dist-ssr
*.local

View File

@ -1,3 +0,0 @@
{
"recommendations": ["johnsoncodehk.volar"]
}

View File

@ -1,11 +0,0 @@
# Vue 3 + Typescript + Vite
This template should help get you started developing with Vue 3 and Typescript in Vite. The template uses Vue 3 `<script setup>` SFCs, check out the [script setup docs](https://v3.vuejs.org/api/sfc-script-setup.html#sfc-script-setup) to learn more.
## Recommended IDE Setup
- [VSCode](https://code.visualstudio.com/) + [Volar](https://marketplace.visualstudio.com/items?itemName=johnsoncodehk.volar)
## Type Support For `.vue` Imports in TS
Since TypeScript cannot handle type information for `.vue` imports, they are shimmed to be a generic Vue component type by default. In most cases this is fine if you don't really care about component prop types outside of templates. However, if you wish to get actual prop types in `.vue` imports (for example to get props validation when using manual `h(...)` calls), you can enable Volar's `.vue` type support plugin by running `Volar: Switch TS Plugin on/off` from VSCode command palette.

View File

@ -1,22 +0,0 @@
{
"name": "ts",
"private": true,
"version": "0.1.0",
"scripts": {
"dev": "vite",
"build":"vite build --emptyOutDir",
"preview": "vite preview"
},
"dependencies": {
"vue": "^3.2.31",
"vue-router": "^4.0.12"
},
"devDependencies": {
"@vitejs/plugin-vue": "^2.3.1",
"sass": "^1.49.9",
"typescript": "^4.5.4",
"vite": "^2.9.2",
"vue-tsc": "^0.28.10",
"vite-plugin-html": "^3.2.0"
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.2 KiB

View File

@ -1,211 +0,0 @@
<template>
<!-- Header -->
<!-- 头部 -->
<div class="header" data-wails-drag>
<!-- navigation -->
<!-- 导航 -->
<div class="nav" data-wails-no-drag>
<router-link to="/">{{ t("nav.home") }}</router-link>
<router-link to="/about">{{ t("nav.about") }}</router-link>
</div>
<!-- Menu -->
<!-- 菜单 -->
<div class="menu" data-wails-no-drag>
<div class="language">
<div v-for="item in languages" :key="item" :class="{ active: item === locale }"
@click="onclickLanguageHandle(item)" class="lang-item">
{{ t("languages." + item) }}
</div>
</div>
<div class="bar">
<div class="bar-btn" @click="onclickMinimise">
{{ t("topbar.minimise") }}
</div>
<div class="bar-btn" @click="onclickQuit">{{ t("topbar.quit") }}</div>
</div>
</div>
</div>
<!-- Page -->
<!-- 页面 -->
<div class="view">
<router-view />
</div>
</template>
<script lang="ts">
import { defineComponent } from "vue";
import { useI18n } from "vue-i18n";
import { WindowMinimise, Quit } from "../../../wailsjs/runtime";
export default defineComponent({
setup() {
const { t, availableLocales, locale } = useI18n({ useScope: "global" });
// List of supported languages
//
const languages = availableLocales;
// Click to switch language
//
const onclickLanguageHandle = (item: string) => {
item !== locale.value ? (locale.value = item) : false;
};
const onclickMinimise = () => {
WindowMinimise();
};
const onclickQuit = () => {
Quit();
};
return {
t,
languages,
locale,
onclickLanguageHandle,
onclickMinimise,
onclickQuit,
};
},
});
</script>
<style lang="scss">
@import url("./assets/css/reset.css");
@import url("./assets/css/font.css");
html {
width: 100%;
height: 100%;
}
body {
width: 100%;
height: 100%;
margin: 0;
padding: 0;
font-family: "JetBrainsMono";
background-color: transparent;
}
#app {
position: relative;
// width: 900px;
// height: 520px;
height: 100%;
background-color: rgba(219, 188, 239, 0.9);
overflow: hidden;
}
.header {
display: flex;
flex-direction: row;
flex-wrap: nowrap;
align-items: center;
justify-content: space-between;
height: 50px;
padding: 0 10px;
background-color: rgba(171, 126, 220, 0.9);
.nav {
a {
display: inline-block;
min-width: 50px;
height: 30px;
line-height: 30px;
padding: 0 5px;
margin-right: 8px;
background-color: #ab7edc;
border-radius: 2px;
text-align: center;
text-decoration: none;
color: #000000;
font-size: 14px;
white-space: nowrap;
&:hover,
&.router-link-exact-active {
background-color: #d7a8d8;
color: #ffffff;
}
}
}
.menu {
display: flex;
flex-direction: row;
flex-wrap: nowrap;
align-items: center;
justify-content: space-between;
.language {
margin-right: 20px;
border-radius: 2px;
background-color: #c3c3c3;
overflow: hidden;
.lang-item {
display: inline-block;
min-width: 50px;
height: 30px;
line-height: 30px;
padding: 0 5px;
background-color: transparent;
text-align: center;
text-decoration: none;
color: #000000;
font-size: 14px;
&:hover {
background-color: #ff050542;
cursor: pointer;
}
&.active {
background-color: #ff050542;
color: #ffffff;
cursor: not-allowed;
}
}
}
.bar {
display: flex;
flex-direction: row;
flex-wrap: nowrap;
align-items: center;
justify-content: flex-end;
min-width: 150px;
.bar-btn {
display: inline-block;
min-width: 80px;
height: 30px;
line-height: 30px;
padding: 0 5px;
margin-left: 8px;
background-color: #ab7edc;
border-radius: 2px;
text-align: center;
text-decoration: none;
color: #000000;
font-size: 14px;
&:hover {
background-color: #d7a8d8;
color: #ffffff;
cursor: pointer;
}
}
}
}
}
.view {
position: absolute;
top: 50px;
left: 0;
right: 0;
bottom: 0;
overflow: hidden;
}
</style>

View File

@ -1,4 +0,0 @@
@font-face {
font-family: "JetBrainsMono";
src: url("../fonts/JetBrainsMono-Medium.woff2");
}

View File

@ -1,124 +0,0 @@
html,
body,
div,
span,
applet,
object,
iframe,
h1,
h2,
h3,
h4,
h5,
h6,
p,
blockquote,
pre,
a,
abbr,
acronym,
address,
big,
cite,
code,
del,
dfn,
em,
img,
ins,
kbd,
q,
s,
samp,
small,
strike,
strong,
sub,
sup,
tt,
var,
b,
u,
i,
center,
dl,
dt,
dd,
ol,
ul,
li,
fieldset,
form,
label,
legend,
table,
caption,
tbody,
tfoot,
thead,
tr,
th,
td,
article,
aside,
canvas,
details,
embed,
figure,
figcaption,
footer,
header,
hgroup,
menu,
nav,
output,
ruby,
section,
summary,
time,
mark,
audio,
video {
margin: 0;
padding: 0;
border: 0;
font-size: 100%;
font: inherit;
vertical-align: baseline;
}
/* HTML5 display-role reset for older browsers */
article,
aside,
details,
figcaption,
figure,
footer,
header,
hgroup,
menu,
nav,
section {
display: block;
}
body {
line-height: 1;
}
ol,
ul {
list-style: none;
}
blockquote,
q {
quotes: none;
}
blockquote:before,
blockquote:after,
q:before,
q:after {
content: "";
content: none;
}
table {
border-collapse: collapse;
border-spacing: 0;
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 94 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

View File

@ -1,25 +0,0 @@
<template>
<div class="hello-world" v-text="msg"></div>
</template>
<script lang="ts">
import { defineComponent } from "vue";
export default defineComponent({
name: "HelloWorld",
props: {
msg: String,
},
});
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
.hello-world {
height: 76px;
line-height: 38px;
margin: 16px 150px;
text-align: center;
font-size: 26px;
}
</style>

View File

@ -1,35 +0,0 @@
<template>
<span class="openlink" @click="onClickhandle">
<slot></slot>
</span>
</template>
<script lang="ts">
import { defineComponent } from "vue";
import { BrowserOpenURL } from "../../../../../wailsjs/runtime";
export default defineComponent({
name: "OpenLink",
props: {
href: String,
},
setup(props) {
const onClickhandle = () => {
// You cannot use the a tag directly, you need to call the Go method here to open the link using the default browser.
// 使aGo使
BrowserOpenURL(props.href);
};
return {
onClickhandle,
};
},
});
</script>
<style lang="scss">
.openlink {
cursor: pointer;
text-decoration: underline;
}
</style>

View File

@ -1,11 +0,0 @@
import { App } from "vue";
import OpenLink from "@/components/public/OpenLink.vue";
// Encapsulate global components as plug-ins
// 将全局组件封装为插件
export default {
install(app: App) {
app.component(OpenLink.name, OpenLink);
},
};

View File

@ -1,8 +0,0 @@
/// <reference types="vite/client" />
declare module '*.vue' {
import { DefineComponent } from 'vue'
// eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/ban-types
const component: DefineComponent<{}, {}, any>
export default component
}

View File

@ -1,32 +0,0 @@
{
"nav": {
"home": "Home",
"about": "About"
},
"languages": {
"en": "English",
"zh-Hans": "简体中文",
"fr": "Français"
},
"topbar": {
"minimise": "Minimise",
"quit": "Quit"
},
"homepage": {
"welcome": "Welcome to use Wails program developed based on Vue",
"getting-started": "Getting Started",
"star-me": "Github"
},
"aboutpage": {
"title": "Wails Template Vue",
"project-repository": "Project Repository",
"author": "Author",
"misitebao": "Misitebao",
"wails-repository": "Wails Repository",
"thanks": "Thank you all for your support🙏!"
},
"global": {
"not-supported": "Because it is a beta version, it can't be done for the time being, it will be completed later.",
"click-link": "The currently clicked link is: "
}
}

View File

@ -1,32 +0,0 @@
{
"nav": {
"home": "Page d'accueil",
"about": "À propos"
},
"languages": {
"en": "English",
"zh-Hans": "简体中文",
"fr": "Français"
},
"topbar": {
"minimise": "Minimiser",
"quit": "Quitter"
},
"homepage": {
"welcome": "Bienvenue à utiliser le programme Wails développé sur la base de Vue",
"getting-started": "Commencer",
"star-me": "Github"
},
"aboutpage": {
"title": "Wails Template Vue",
"project-repository": "Référentiel de projets",
"author": "Auteur",
"misitebao": "Misitebao",
"wails-repository": "Wails Dépôt",
"thanks": "Merci à tous pour votre soutien🙏!"
},
"global": {
"not-supported": "Parce qu'il s'agit d'une version bêta, cela ne peut pas être fait pour le moment, il sera complété plus tard.",
"click-link": "Le lien actuellement cliqué est: "
}
}

View File

@ -1,32 +0,0 @@
{
"nav": {
"home": "主页",
"about": "关于"
},
"languages": {
"en": "English",
"zh-Hans": "简体中文",
"fr": "Français"
},
"topbar": {
"minimise": "最小化",
"quit": "退出"
},
"homepage": {
"welcome": "欢迎使用基于Vue开发的Wails程序",
"getting-started": "快速入门",
"star-me": "Github"
},
"aboutpage": {
"title": "Wails Template Vue",
"project-repository": "项目仓库",
"author": "作者",
"misitebao": "米司特包",
"wails-repository": "Wails 仓库",
"thanks": "感谢各位大佬的支持🙏!"
},
"global": {
"not-supported": "由于是测试版,所以暂时做不了,后续会完成它。",
"click-link": "当前点击的链接是: "
}
}

View File

@ -1,14 +0,0 @@
import { createApp } from "vue";
import App from "./App.vue";
import router from "./router";
import i18n from "./i18n";
// Register global common components
// 注册全局通用组件
import publicComponents from "./components/public/";
const app = createApp(App);
app.use(publicComponents);
app.use(router).use(i18n).mount("#app");

View File

@ -1,27 +0,0 @@
import { createRouter, createWebHashHistory, RouteRecordRaw} from "vue-router";
import Home from "@/views/Home.vue";
const routes:Array<RouteRecordRaw> = [
{
path: "/",
name: "Home",
component: Home,
},
{
path: "/about",
name: "About",
// route level code-splitting
// this generates a separate chunk (about.[hash].js) for this route
// which is lazy-loaded when the route is visited.
component: function () {
return import(/* webpackChunkName: "about" */ "../views/About.vue");
},
},
];
const router = createRouter({
history: createWebHashHistory(),
routes,
});
export default router;

View File

@ -1,104 +0,0 @@
<template>
<div class="about">
<!-- Title -->
<div class="title">{{ t("aboutpage.title") }}</div>
<!-- Information -->
<!-- 信息 -->
<div class="content">
<div class="comeon">
<img :src="comeonGif" alt="Gif" />
</div>
<ul class="info">
<li class="info-item">
<div class="name">{{ t("aboutpage.project-repository") }}</div>
<OpenLink
class="link"
href="https://github.com/misitebao/wails-template-vue"
>https://github.com/misitebao/wails-template-vue</OpenLink
>
</li>
<li class="info-item">
<div class="name">{{ t("aboutpage.wails-repository") }}</div>
<OpenLink class="link" href="https://github.com/wailsapp/wails"
>https://github.com/wailsapp/wails</OpenLink
>
</li>
<li class="info-item">
<div class="name">{{ t("aboutpage.author") }}</div>
<OpenLink class="link" href="https://github.com/misitebao">{{
t("aboutpage.misitebao")
}}</OpenLink>
</li>
</ul>
</div>
<!-- Thanks -->
<!-- 谢语 -->
<div class="thank">{{ t("aboutpage.thanks") }}</div>
</div>
</template>
<script lang="ts">
import { defineComponent } from "vue";
import { useI18n } from "vue-i18n";
import comeonGif from "@/assets/images/comeon.gif";
export default defineComponent({
setup() {
const { t } = useI18n({ useScope: "global" });
return {
t,
comeonGif,
};
},
});
</script>
<style lang="scss">
.about {
.title {
margin: 30px auto 10px;
font-size: 38px;
color: #a150b5;
text-align: center;
}
.content {
position: relative;
margin: 36px 20px;
.comeon {
position: absolute;
left: 26px;
top: 38px;
max-width: 66%;
img {
width: 220px;
height: 180px;
}
}
.info {
margin: 0 0 0 33%;
font-size: 24px;
text-align: left;
.info-item {
margin-bottom: 10px;
.name {
line-height: 40px;
font-size: 28px;
color: #6d6363;
}
.link {
line-height: 30px;
font-size: 20px;
color: #5f6c86;
}
}
}
}
.thank {
height: 68px;
line-height: 68px;
margin: 36px auto;
text-align: center;
font-size: 40px;
}
}
</style>

View File

@ -1,87 +0,0 @@
<template>
<div class="home">
<!-- Logo -->
<img class="logo" alt="Vue logo" src="../assets/logo.png" />
<HelloWorld :msg="t('homepage.welcome')" />
<!-- Bottom button -->
<!-- 底部按钮 -->
<div class="link">
<OpenLink
href="https://wails.io/docs/gettingstarted/installation"
class="btn start"
>{{ "Getting Started" }}</OpenLink
>
<OpenLink
href="https://github.com/misitebao/wails-template-vue"
class="btn star"
>{{ "Star Me" }}</OpenLink
>
</div>
</div>
</template>
<script lang="ts">
import { defineComponent } from "vue";
import { useI18n } from "vue-i18n";
import HelloWorld from "@/components/HelloWorld.vue";
export default defineComponent({
name: "Home",
components: {
HelloWorld,
},
setup() {
const { t } = useI18n({ useScope: "global" });
return {
t,
};
},
});
</script>
<style lang="scss">
.home {
.logo {
display: block;
width: 620px;
height: 280px;
margin: 10px auto 10px;
}
.link {
display: flex;
flex-direction: row;
flex-wrap: nowrap;
align-items: center;
justify-content: center;
margin: 18px auto;
.btn {
display: block;
width: 150px;
height: 50px;
line-height: 50px;
padding: 0 5px;
margin: 0 30px;
border-radius: 8px;
text-align: center;
font-weight: 700;
font-size: 16px;
white-space: nowrap;
text-decoration: none;
cursor: pointer;
&.start {
background-color: #fd0404;
color: #ffffff;
&:hover {
background-color: #ec2e2e;
}
}
&.star {
background-color: #ffffff;
color: #fd0404;
&:hover {
background-color: #f3f3f3;
}
}
}
}
}
</style>

View File

@ -1,15 +0,0 @@
{
"compilerOptions": {
"target": "esnext",
"useDefineForClassFields": true,
"module": "esnext",
"moduleResolution": "node",
"strict": true,
"jsx": "preserve",
"sourceMap": true,
"resolveJsonModule": true,
"esModuleInterop": true,
"lib": ["esnext", "dom"]
},
"include": ["src/**/*.ts", "src/**/*.d.ts", "src/**/*.tsx", "src/**/*.vue"]
}

View File

@ -1,37 +0,0 @@
import { defineConfig } from "vite";
import vue from "@vitejs/plugin-vue";
import path from "path";
import pkg from "../../package.json";
import { createHtmlPlugin } from "vite-plugin-html";
// https://vitejs.dev/config/
export default defineConfig({
plugins: [
vue(),
createHtmlPlugin({
minify: false,
// entry: "src/main.js",
template: "index.html",
inject: {
data: {
title: `${pkg.name}`,
},
},
}),
],
resolve: {
alias: {
"@": path.resolve(__dirname, "src"),
},
},
build: {
outDir: "../../dist",
rollupOptions: {
output: {
entryFileNames: `assets/[name].js`,
chunkFileNames: `assets/[name].js`,
assetFileNames: `assets/[name].[ext]`,
},
},
},
});

View File

Before

Width:  |  Height:  |  Size: 4.2 KiB

After

Width:  |  Height:  |  Size: 4.2 KiB

17
frontend/src/App.vue Normal file
View File

@ -0,0 +1,17 @@
<script setup lang="ts">
import { RouterLink, RouterView } from "vue-router";
</script>
<template>
<header>
<nav>
<RouterLink to="/">Home</RouterLink>
<RouterLink to="/about">About</RouterLink>
</nav>
</header>
<br />
<RouterView />
</template>
<style scoped></style>

View File

@ -0,0 +1,74 @@
/* color palette from <https://github.com/vuejs/theme> */
:root {
--vt-c-white: #ffffff;
--vt-c-white-soft: #f8f8f8;
--vt-c-white-mute: #f2f2f2;
--vt-c-black: #181818;
--vt-c-black-soft: #222222;
--vt-c-black-mute: #282828;
--vt-c-indigo: #2c3e50;
--vt-c-divider-light-1: rgba(60, 60, 60, 0.29);
--vt-c-divider-light-2: rgba(60, 60, 60, 0.12);
--vt-c-divider-dark-1: rgba(84, 84, 84, 0.65);
--vt-c-divider-dark-2: rgba(84, 84, 84, 0.48);
--vt-c-text-light-1: var(--vt-c-indigo);
--vt-c-text-light-2: rgba(60, 60, 60, 0.66);
--vt-c-text-dark-1: var(--vt-c-white);
--vt-c-text-dark-2: rgba(235, 235, 235, 0.64);
}
/* semantic color variables for this project */
:root {
--color-background: var(--vt-c-white);
--color-background-soft: var(--vt-c-white-soft);
--color-background-mute: var(--vt-c-white-mute);
--color-border: var(--vt-c-divider-light-2);
--color-border-hover: var(--vt-c-divider-light-1);
--color-heading: var(--vt-c-text-light-1);
--color-text: var(--vt-c-text-light-1);
--section-gap: 160px;
}
@media (prefers-color-scheme: dark) {
:root {
--color-background: var(--vt-c-black);
--color-background-soft: var(--vt-c-black-soft);
--color-background-mute: var(--vt-c-black-mute);
--color-border: var(--vt-c-divider-dark-2);
--color-border-hover: var(--vt-c-divider-dark-1);
--color-heading: var(--vt-c-text-dark-1);
--color-text: var(--vt-c-text-dark-2);
}
}
*,
*::before,
*::after {
box-sizing: border-box;
margin: 0;
position: relative;
font-weight: normal;
}
body {
min-height: 100vh;
color: var(--color-text);
background: var(--color-background);
transition: color 0.5s, background-color 0.5s;
line-height: 1.6;
font-family: Inter, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu,
Cantarell, 'Fira Sans', 'Droid Sans', 'Helvetica Neue', sans-serif;
font-size: 15px;
text-rendering: optimizeLegibility;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}

View File

@ -0,0 +1,35 @@
@import "./base.css";
#app {
max-width: 1280px;
margin: 0 auto;
padding: 2rem;
font-weight: normal;
}
a,
.green {
text-decoration: none;
color: hsla(160, 100%, 37%, 1);
transition: 0.4s;
}
@media (hover: hover) {
a:hover {
background-color: hsla(160, 100%, 37%, 0.2);
}
}
@media (min-width: 1024px) {
body {
display: flex;
place-items: center;
}
#app {
display: grid;
grid-template-columns: 1fr 1fr;
padding: 0 2rem;
}
}

View File

@ -1,17 +1,15 @@
import { createI18n } from "vue-i18n";
import zhHans from "./locales/zh-Hans.json";
import en from "./locales/en.json";
import fr from "./locales/fr.json";
import zhHans from "./locales/zh-Hans.json";
const i18n = createI18n({
locale: "en",
locale: "ja",
fallbackLocale: "en",
legacy: false,
messages: {
en,
"zh-Hans": zhHans,
en: en,
fr: fr,
},
});

View File

@ -0,0 +1,3 @@
{
"hello": "hello world"
}

View File

@ -0,0 +1,3 @@
{
"hello": "hello world"
}

14
frontend/src/main.ts Normal file
View File

@ -0,0 +1,14 @@
import { createApp } from "vue";
import { createPinia } from "pinia";
import App from "./App.vue";
import router from "./router";
import "./assets/main.css";
const app = createApp(App);
app.use(createPinia());
app.use(router);
app.mount("#app");

View File

@ -0,0 +1,23 @@
import { createRouter, createWebHashHistory } from "vue-router";
import HomeView from "../views/HomeView.vue";
const router = createRouter({
history: createWebHashHistory(import.meta.env.BASE_URL),
routes: [
{
path: "/",
name: "home",
component: HomeView,
},
{
path: "/about",
name: "about",
// route level code-splitting
// this generates a separate chunk (About.[hash].js) for this route
// which is lazy-loaded when the route is visited.
component: () => import("../views/AboutView.vue"),
},
],
});
export default router;

View File

@ -0,0 +1,16 @@
import { defineStore } from "pinia";
export const useCounterStore = defineStore({
id: "counter",
state: () => ({
counter: 0,
}),
getters: {
doubleCount: (state) => state.counter * 2,
},
actions: {
increment() {
this.counter++;
},
},
});

View File

@ -0,0 +1,5 @@
<template>
<div class="about">About</div>
</template>
<style></style>

View File

@ -0,0 +1,5 @@
<script setup lang="ts"></script>
<template>
<div class="home">Home</div>
</template>

View File

@ -0,0 +1,8 @@
{
"extends": "@vue/tsconfig/tsconfig.node.json",
"include": ["vite.config.*", "vitest.config.*", "cypress.config.*"],
"compilerOptions": {
"composite": true,
"types": ["node"]
}
}

21
frontend/tsconfig.json Normal file
View File

@ -0,0 +1,21 @@
{
"extends": "@vue/tsconfig/tsconfig.web.json",
"include": [
"env.d.ts",
"src/**/*",
"src/**/*.vue"
],
"compilerOptions": {
"baseUrl": ".",
"paths": {
"@/*": [
"./src/*"
]
}
},
"references": [
{
"path": "./tsconfig.config.json"
}
]
}

25
frontend/vite.config.ts Normal file
View File

@ -0,0 +1,25 @@
import { fileURLToPath, URL } from "node:url";
import { defineConfig } from "vite";
import vue from "@vitejs/plugin-vue";
import vueJsx from "@vitejs/plugin-vue-jsx";
// https://vitejs.dev/config/
export default defineConfig({
plugins: [vue(), vueJsx()],
resolve: {
alias: {
"@": fileURLToPath(new URL("./src", import.meta.url)),
},
},
build: {
outDir: "./dist",
rollupOptions: {
output: {
entryFileNames: `assets/[name].js`,
chunkFileNames: `assets/[name].js`,
assetFileNames: `assets/[name].[ext]`,
},
},
},
});

Some files were not shown because too many files have changed in this diff Show More