这是我参与更文挑战的第5天,活动详情查看: 更文挑战。
初衷是为xdm在不暴露个人信息的情况下,对比小金库买房,给女票一个惊喜。首付小工具是以大连市作为模板,欢迎兄弟们PR。
新建项目
Vue3 + TS初始化
执行脚本:
yarn create @vitejs/app <project-name> --template vue-ts
cd <project-name>
yarn
yarn dev
Electron + TS初始化
新建electron目录以及相关文件
mkdir electron
cd electron
touch main.ts
touch preload.ts
touch render.ts
初始化electron相关代码
main.ts
import { app, BrowserWindow } from "electron";
import * as path from "path";
function createWindow() {
const mainWindow = new BrowserWindow({
height: 600,
webPreferences: {
preload: path.join(__dirname, "preload.js"),
},
width: 800,
});
mainWindow.loadFile(path.join(__dirname, "..", "dist/index.html"));
mainWindow.webContents.openDevTools();
}
app.on("ready", () => {
createWindow();
app.on("activate", function () {
if (BrowserWindow.getAllWindows().length === 0) createWindow();
});
});
app.on("window-all-closed", () => {
if (process.platform !== "darwin") {
app.quit();
}
});
preload.ts
window.addEventListener("DOMContentLoaded", () => {
const replaceText = (selector: string, text: string) => {
const element = document.getElementById(selector);
if (element) {
element.innerText = text;
}
};
for (const type of ["chrome", "node", "electron"]) {
replaceText(
`${type}-version`,
process.versions[type as keyof NodeJS.ProcessVersions] as string
);
}
});
配置执行脚本
新建tsconfig.electron.json
{
"extends": "./tsconfig.json",
"compilerOptions": {
"outDir": "build",
"noEmit": false,
"module": "commonjs",
"baseUrl": ".",
"sourceMap": false,
},
"include": ["electron"]
}
修改vite.config.ts
import { defineConfig } from "vite";
import vue from "@vitejs/plugin-vue";
export default defineConfig({
plugins: [vue()],
base: "./",
});
修改package.json
{
main: "build/main.js",
"scripts": {
...
"build": "vite build",
"dist:all": "npm run build && electron-builder --mac --linux --windows",
"dev:electron": "npm run build && tsc -p tsconfig.electron.json && electron ./build/main.js"
},
}
目前这种方式没有支持热更新,如有解决方案会更新。目前貌似有这个解决方案。
首付计算页面
App.vue
<template>
<div>
<div>{{ sumPrice }}</div>
<el-form ref="form" :model="form" :rules="rules">
<el-form-item label="房子所占面积">
<el-input
v-model="form.house_size"
type="'number'"
placeholder="请输入房子所占面积"
controls-position="right"
></el-input>
</el-form-item>
<el-form-item label="房子总价格">
<el-input
v-model="form.house_price"
type="'number'"
placeholder="请输入房产总价格"
controls-position="right"
></el-input>
</el-form-item>
<el-form-item label="需付首付比例" prop="first_rate">
<el-input
v-model.number="form.first_rate"
type="'number'"
placeholder="请输入需付首付比例"
></el-input>
</el-form-item>
<el-form-item label="中介收费占比">
<el-input
v-model="form.mediation_price"
type="'number'"
placeholder="请输入中介收费占比"
></el-input>
</el-form-item>
<el-form-item label="契税">
<el-input
v-model="form.deed_tax"
type="'number'"
placeholder="请输入契税占比"
></el-input>
</el-form-item>
<el-form-item label="贷款方式">
<el-radio-group v-model="form.load_method">
<el-radio label="business">商业贷款</el-radio>
<el-radio label="fund">组合贷款(公积金贷款 + 商业贷款)</el-radio>
</el-radio-group>
</el-form-item>
</el-form>
<el-form ref="fundForm" :model="fundForm" :rules="fundRules" v-if="form.load_method === 'fund'">
<el-form-item label="公积金贷款金额">
<el-input
v-model="form.fund_price"
type="'number'"
placeholder="请输入公积金贷款金额"
></el-input>
</el-form-item>
<el-form-item label="商业贷款金额">
<el-input
v-model="form.business_price"
type="'number'"
placeholder="请输入商业贷款金额"
></el-input>
</el-form-item>
<el-form-item label="商业贷款利率">
<el-input
v-model="form.business_rate"
type="'number'"
placeholder="请输入商业贷款利率"
></el-input>
</el-form-item>
</el-form>
<el-button @click="handleHouseFirstPrice">计算首付</el-button>
</div>
</template>
<script lang="ts">
import { defineComponent } from "vue";
import {
ElForm,
ElFormItem,
ElInput,
ElRadio,
ElRadioGroup,
ElButton,
} from "element-plus";
export default defineComponent({
name: "App",
components: {
ElForm,
ElFormItem,
ElInput,
ElRadio,
ElRadioGroup,
ElButton,
},
data() {
const validateFirstRate = (
rule: any,
value: string,
callback: Function
) => {
const numValue = parseFloat(value);
if (!Number.isInteger(value)) {
callback(new Error("请输入数字值"));
} else if (numValue > 1 || numValue <= 0) {
callback(new Error("请输入数字值满足 ===> 大于0 小于等于1"));
} else {
callback();
}
};
return {
form: {
house_price: undefined,
mediation_price: undefined,
first_rate: undefined,
deed_tax: undefined,
house_size: undefined,
},
fundForm: {
fund_price: undefined,
business_price: undefined,
business_rate: undefined,
fund_safe: 2000
},
rules: {
first_rate: [{ validator: validateFirstRate, trigger: "blur" }],
},
};
},
computed: {
sumPrice() {
const house_price: number = this.$data.form.house_price || 0;
const mediation_price: number = this.$data.form.mediation_price || 0;
const first_rate: number = this.$data.form.first_rate || 0;
const deed_tax: number = this.$data.form.deed_tax || 0;
const firstMoney = house_price * first_rate;
const mediationMoney = house_price * mediation_price;
const deedTaxMoney = house_price * deed_tax;
return firstMoney + mediationMoney + deedTaxMoney;
},
},
methods: {
handleHouseFirstPrice() {
console.log(this.$data.form);
},
},
mounted() {},
});
</script>
<style>
#app {
font-family: Avenir, Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
margin-top: 60px;
}
</style>
打包
安装electron-builder
yarn add electron-builder -D
npm run dist:all
修改package.json
{
"build": {
"appId": "com.zy.www",
"directories": {
"output": "software"
},
"files": [
"build/**/*",
"dist/**/*",
"package.json"
]
}
}