前言
H5 项目基于 Web 技术,可以在智能手机、平板电脑等移动设备上的浏览器中运行,无需下载和安装任何应用程序,且H5 项目的代码和资源可以集中在服务器端进行管理,只需更新服务器上的代码,即可让所有顾客访问到最新的系统版本。
本系列将以肯德基自助点餐页面为模板,搭建一款自助点餐系统,第一次开发移动端h5项目,免不了有所差错和不足,欢迎各位大佬指正。
项目代码正在gitee同步更新中,项目地址:https://gitee.com/airheaven/kfg-vue,学习前请大家给个star哦🌟
技术栈
Vue3.2 + Vite + TS + Vant + Pinia + Node.js
一、起始准备
1.1、安装nvm
nvm 全英文也叫 node.js version management,是一个 nodejs 的版本管理工具,用于管理nodejs。
首先进入github链接:https://github.com/coreybutler/nvm-windows/releases 下载 nvm-setup.zip,随后安装。
安装完成后输入nvm version
显示版本号就是安装成功了,我这里用的是1.1.10版本。
PS E:\MyVueWorkspace> nvm version
1.1.10
1.2、利用nvm安装node和npm
nvm install 版本号 安装指定的版本的 nodejs,我这里输入:nvm install 16.16.0
安装16.16.0版本
nvm会自动帮你安装好node和npm,显示如下信息就是成功了:
Downloading node.js version 16.16.0 (64-bit)...
Extracting node and npm...
Complete
npm v8.11.0 installed successfully.
Installation complete. If you want to use this version, type
nvm use 16.16.0
如果之前安装过,可以使用nvm ls查看已经安装过的node版本。
安装好node和npm后,需要使用nvm use 16.16.0
启用该版本。
1.3、利用npm安装Vite
既然是新项目,且用的是Vue3.2,那么我们必须用上现在嘎嘎香 嘎嘎快的Vite,Vite是新一代的前端开发与构建工具,具有开箱即用、高度的可扩展性和完整的类型支持。
使用npm install -g vite
安装最新版的Vite,然后使用vite -v
查看版本(我的是4.1.4)
added 14 packages, and audited 16 packages in 13s
found 0 vulnerabilities
npm notice
npm notice New major version of npm available! 8.11.0 -> 9.5.1
npm notice Changelog: https://github.com/npm/cli/releases/tag/v9.5.1
npm notice Run npm install -g npm@9.5.1 to update!
npm notice
PS E:\MyVueWorkspace> vite -v
vite/4.1.4 win32-x64 node-v16.16.0
1.4、VsCode插件安装
在VsCode中找到扩展,需要安装的扩展插件有:
ESlint:开源的JavaScript验证工具,可以让代码更加规范:
Prettier:前端代码格式工具,可以让代码保持风格一致:
Vue Language Features(Volar):针对Vue3的vscode插件:
二、项目初始化
输入npm create vite@latest
使用Vite初始化项目,填写项目名称(KFG-vue),选择Vue作为框架,语言选择TypeScript,如下所示:
Need to install the following packages:
create-vite@latest
Ok to proceed? (y) y
√ Project name: ... KFG-vue
√ Package name: ... kfg-vue
√ Select a framework: » Vue
√ Select a variant: » TypeScript
然后cd进入KFG-vue项目目录,输入:npm install
安装项目所需的基本依赖:
added 46 packages, and audited 47 packages in 37s
5 packages are looking for funding
run `npm fund` for details
found 0 vulnerabilities
输入npm run dev
运行项目,控制台会输出网址,如http://127.0.0.1:5173/即可以查看初始化好的项目:
> kfg-vue@0.0.0 dev
> vite
VITE v4.1.4 ready in 261 ms
➜ Local: http://127.0.0.1:5173/
➜ Network: use --host to expose
然后我们需要删除一些初始化项目中不需要的东西,删除public里的vite.svg,删除assets里面的vue.svg,删除components里面的HelloWorld.vue,清空style.css,清空App.vue里的内容(仅仅保留最基本的vue3模板):
由于vue中ts无法识别引入的vue文件,引入模块后会提示打不到module,但是编译可能成功,运行也不报错,为了我的强迫症我选择在src文件夹下新增一个env.d.ts
文件解决这个问题:
// src/env.d.ts
declare module "*.vue" {
import type { DefineComponent } from "vue";
// eslint-disable-next-line @typescript-eslint/ban-types
const vueComponent: DefineComponent<{}, {}, any>;
export default vueComponent;
}
三、代码规范配置(可选)
插件拿来不一定能够完全适用,需要提供了一些额外的适用于 ts 和vue语法的规则,配置以下项:
ESlint配置:输入npx eslint --init
,选择如下:
√ How would you like to use ESLint? · problems(第二个)
√ What type of modules does your project use? · esm(第一个)
√ Which framework does your project use? · vue
√ Does your project use TypeScript? · No / Yes
√ Where does your code run? · browser, node(两个都勾选)
√ What format do you want your config file to be in? · JavaScript
Prettier配置:输入npm i prettier eslint-config-prettier eslint-plugin-prettier -D
:
创建prettier.cjs
文件,文件中输入:
// prettier.cjs
module.exports = {
printWidth: 100,
tabWidth: 2,
useTabs: false, // 是否使用tab进行缩进,默认为false
singleQuote: true, // 是否使用单引号代替双引号,默认为false
semi: true, // 行尾是否使用分号,默认为true
arrowParens: 'always',
endOfLine: 'auto',
vueIndentScriptAndStyle: true,
htmlWhitespaceSensitivity: 'strict',
};
配置eslintrc文件,将文件.eslintrc.cjs改为:
// eslintrc.cjs
module.exports = {
root: true, // 停止向上查找父级目录中的配置文件
env: {
browser: true,
es2021: true,
node: true,
},
extends: [
'eslint:recommended',
'plugin:vue/vue3-essential',
'plugin:@typescript-eslint/recommended',
'plugin:prettier/recommended',
'prettier', // eslint-config-prettier 的缩写
],
parser: 'vue-eslint-parser', // 指定要使用的解析器
// 给解析器传入一些其他的配置参数
parserOptions: {
ecmaVersion: 'latest', // 支持的es版本
parser: '@typescript-eslint/parser',
sourceType: 'module', // 模块类型,默认为script,我们设置为module
},
plugins: ['vue', '@typescript-eslint', 'prettier'], // eslint-plugin- 可以省略
rules: {
'vue/multi-word-component-names': 'off',
'@typescript-eslint/no-var-requires': 'off',
},
};
配置保存文件自动格式化:在项目的.vscode中新建一个setting.json文件,
文件中配置如下,使程序能够保存时自动使用eslint格式化(懒人福音),setting.json配置 如下所示:
// .vscode/setting.json
{
"editor.codeActionsOnSave": {
"source.fixAll.eslint": true
},
// #每次保存的时候自动格式化
"editor.formatOnSave": true,
"editor.formatOnType": true,
// #每次保存的时候将代码按eslint格式进行修复
"eslint.autoFixOnSave": true,
"eslint.format.enable": true,
}
添加lint命令(可选):package.json中进行配置,可以运行npm run lint
检查代码:
// package.json
// 可以运行`npm run lint`检查代码
"lint": "eslint --ext .js,.vue,.ts src --fix"
四、项目搭建
4.1、清除默认样式
在网上找一个reset.css文件,放入到src/styles文件夹(可能需要新建)中,从而清除默认样式:
/* src/styles */
/* 清除内外边距 */
body, h1, h2, h3, h4, h5, h6, hr, p, blockquote,
dl, dt, dd, ul, ol, li,
pre,
fieldset, lengend, button, input, textarea,
th, td {
margin: 0;
padding: 0;
}
/* 设置默认字体 */
body,
button, input, select, textarea { /* for ie */
/*font: 12px/1 Tahoma, Helvetica, Arial, "宋体", sans-serif;*/
font: 12px/1.3 "Microsoft YaHei",Tahoma, Helvetica, Arial, "\5b8b\4f53", sans-serif; /* 用 ascii 字符表示,使得在任何编码下都无问题 */
color: #333;
}
h1 { font-size: 18px; /* 18px / 12px = 1.5 */ }
h2 { font-size: 16px; }
h3 { font-size: 14px; }
h4, h5, h6 { font-size: 100%; }
address, cite, dfn, em, var, i{ font-style: normal; } /* 将斜体扶正 */
b, strong{ font-weight: normal; } /* 将粗体扶细 */
code, kbd, pre, samp, tt { font-family: "Courier New", Courier, monospace; } /* 统一等宽字体 */
small { font-size: 12px; } /* 小于 12px 的中文很难阅读,让 small 正常化 */
/* 重置列表元素 */
ul, ol { list-style: none; }
/* 重置文本格式元素 */
a { text-decoration: none; color: #666;}
/* 重置表单元素 */
legend { color: #000; } /* for ie6 */
fieldset, img { border: none; }
button, input, select, textarea {
font-size: 100%; /* 使得表单元素在 ie 下能继承字体大小 */
}
/* 重置表格元素 */
table {
border-collapse: collapse;
border-spacing: 0;
}
/* 重置 hr */
hr {
border: none;
height: 1px;
}
.clearFix::after{
content:"";
display: block;
clear:both;
}
/* 让非ie浏览器默认也显示垂直滚动条,防止因滚动条引起的闪烁 */
html { overflow-y: scroll; }
a:link:hover{
color : rgb(79, 76, 212) !important;
text-decoration: underline;
}
/* 清除浮动 */
.clearfix::after {
display: block;
height: 0;
content: "";
clear: both;
visibility: hidden;
}
在index.html中引入:
<link rel="stylesheet" href="./styles/reset.css">
4.2、路径别名配置
路径别名配置:在vite.config.ts, 加入以下内容(resolve的alias),设置别名@:
// vite.config.ts
import { defineConfig } from "vite";
import vue from "@vitejs/plugin-vue";
// 设置路径
import { resolve } from "path";
// Vant声明和按需引入
import Component from "unplugin-vue-components/vite";
import { VantResolver } from "unplugin-vue-components/resolvers";
// vw方案,将px转为vw
import postcsspxtoviewport from "postcss-px-to-viewport";
// https://vitejs.dev/config/
export default defineConfig({
plugins: [
vue(),
Component({
resolvers: [VantResolver()],
}),
],
css: {
postcss: {
plugins: [
postcsspxtoviewport({
unitToConvert: "px", // 要转化的单位
viewportWidth: 750, // UI设计稿的宽度,一般写 320
// 下面的不常用,上面的常用
unitPrecision: 6, // 转换后的精度,即小数点位数
propList: ["*"], // 指定转换的css属性的单位,*代表全部css属性的单位都进行转换
viewportUnit: "vw", // 指定需要转换成的视窗单位,默认vw
fontViewportUnit: "vw", // 指定字体需要转换成的视窗单位,默认vw
selectorBlackList: ["ignore-"], // 指定不转换为视窗单位的类名,
minPixelValue: 1, // 默认值1,小于或等于1px则不进行转换
mediaQuery: true, // 是否在媒体查询的css代码中也进行转换,默认false
replace: true, // 是否转换后直接更换属性值
landscape: false, // 是否处理横屏情况
}),
],
},
},
resolve: {
alias: {
"@": resolve(__dirname, "./src"),
"*": resolve(""),
},
},
});
然后在tsconfig.json,加入以下内容(baseUrl和paths):
{
"compilerOptions": {
"target": "ESNext",
"useDefineForClassFields": true,
"module": "ESNext",
"moduleResolution": "Node",
"strict": true,
"jsx": "preserve",
"resolveJsonModule": true,
"isolatedModules": true,
"esModuleInterop": true,
"lib": ["ESNext", "DOM"],
"skipLibCheck": true,
"noEmit": true,
"baseUrl": ".",
// 用于设置解析非相对模块名称的基本目录,相对模块不会受到baseUrl的影响
"paths": {
"@/*": ["src/*"]
}
},
"include": ["src/**/*.ts", "src/**/*.d.ts", "src/**/*.tsx", "src/**/*.vue"],
"references": [{ "path": "./tsconfig.node.json" }]
}
4.3、项目搭建
1️⃣ Less: CSS预处理器
我选用了less作为CSS预处理器,需要安装相应的预处理器依赖:npm i less -D
如果需要规定全局样式的话,可以配置一下在src/asserts/less文件夹下新建一个global.less,然后在vite.config.ts的css中写入:
// vite.config.ts
css: {
preprocessorOptions: {
less: {
modifyVars: {
hack: `true; @import (reference) "${resolve(
"src/assets/less/global.less"
)}";`,
},
javascriptEnabled: true,
},
},
//....
}
2️⃣ Vant: 轻量可定制的移动端组件库
选用移动端最常用的Vant作为组件库,输入npm i vant
安装Vant。
然后安装按需引入插件,输入npm i unplugin-vue-components -D
安装插件,它可以自动引入组件,并按需引入组件的样式。相比于常规用法,这种方式可以按需引入组件的 CSS 样式,从而减少一部分代码体积,但使用起来会变得繁琐一些。
配置Vant的按需引入,在 vite.config.js 文件中配置插件:
// vite.config.ts
import vue from '@vitejs/plugin-vue';
import Components from 'unplugin-vue-components/vite';
import { VantResolver } from 'unplugin-vue-components/resolvers';
export default {
plugins: [
vue(),
Components({
resolvers: [VantResolver()],
}),
],
};
完成以上两步,就可以直接在模板中使用 Vant 组件了,unplugin-vue-components 会解析模板并自动注册对应的组件。
可以试试在App.vue中写入:
<script setup lang="ts"></script>
<template>
<van-button type="primary">Hello World</van-button>
</template>
<style scoped></style>
显示如下则成功引入Vant并自动注册了组件:
3️⃣ vw/vh方案:移动端适配
移动端适配通常使用的有rem方案和vw/vh方案,我选用的是vw方案,首先输入npm install postcss-px-to-viewport -D
安装插件,将 px 转化成 vw,安装完成后,修改 vite.config.ts
声明插件(由于 vite 中已经内联了 postcss,所以无需创建 postcss.config.js文件来声明插件):
// vite.config.ts
import { defineConfig } from "vite";
import vue from "@vitejs/plugin-vue";
// 设置路径
import { resolve } from "path";
// Vant声明和按需引入
import Component from "unplugin-vue-components/vite";
import { VantResolver } from "unplugin-vue-components/resolvers";
// vw方案,将px转为vw
import postcsspxtoviewport from "postcss-px-to-viewport";
// https://vitejs.dev/config/
export default defineConfig({
plugins: [
vue(),
Component({
resolvers: [VantResolver()],
}),
],
css: {
postcss: {
plugins: [
postcsspxtoviewport({
unitToConvert: "px", // 要转化的单位
viewportWidth: 750, // UI设计稿的宽度,一般写 320
// 下面的不常用,上面的常用
unitPrecision: 6, // 转换后的精度,即小数点位数
propList: ["*"], // 指定转换的css属性的单位,*代表全部css属性的单位都进行转换
viewportUnit: "vw", // 指定需要转换成的视窗单位,默认vw
fontViewportUnit: "vw", // 指定字体需要转换成的视窗单位,默认vw
selectorBlackList: ["ignore-"], // 指定不转换为视窗单位的类名,
minPixelValue: 1, // 默认值1,小于或等于1px则不进行转换
mediaQuery: true, // 是否在媒体查询的css代码中也进行转换,默认false
replace: true, // 是否转换后直接更换属性值
landscape: false, // 是否处理横屏情况
}),
],
},
},
resolve: {
alias: {
"@": resolve(__dirname, "./src"),
"*": resolve(""),
},
},
});
然后运行项目,即可发现支持了移动端适配,且自适应的调整高度,成功配置
4️⃣ Vue Router:路由配置
部分参考自:https://blog.csdn.net/jason_renyu/article/details/123261823
Vue Router是Vue.js 的官方路由,非常方便好用,在控制台输入:npm i vue-router@4
安装Vue Router,新建router文件夹,新建router/index.ts
,配置如下:
/**
* createRouter 这个为创建路由的方法
* createWebHashHistory 这个就是vue2中路由的模式,
* 这里的是hash模式,这个还可以是createWebHistory等
* RouteRecordRaw 这个为要添加的路由记录,也可以说是routes的ts类型
*/
import { createRouter, createWebHashHistory, RouteRecordRaw } from "vue-router";
// 路由记录,这个跟vue2中用法一致,就不做过多解释了
const routes: Array<RouteRecordRaw> = [
{
path: "/",
name: "todolist",
component: () => import("@/components/TodoList.vue"),
alias: "/todolist",
meta: {
title: "todolist页面",
},
},
{
path: "/father",
name: "father",
component: () => import("@/components/Father.vue"),
meta: {
title: "father页面",
},
},
];
const router = createRouter({
history: createWebHashHistory(),
routes,
});
export default router;
测试一下,在compnents文件下下新建Father.vue和TodoList.vue,内容如下:
Father.vue:
<!-- compnents/Father.vue -->
<template>
<div>
<h2>这是Father组件</h2>
<h3>路由传入的参数为:{{ route.query.msg }}</h3>
</div>
</template>
<script setup lang="ts">
import { ref } from "vue";
// 路由接收参数
import { useRoute } from "vue-router";
const route = useRoute();
// 接收路由传入的参数
let routeMsg = ref("");
if (route.query.msg) {
routeMsg.value = route.query.msg as string;
}
</script>
<style scoped></style>
TodoList.vue:
<!-- compnents/TodoList.vue -->
<template>
<div>
<h2>这是TodoList组件</h2>
</div>
</template>
<script setup lang="ts"></script>
<style scoped></style>
在App.vue中测试调用:
<!-- App.vue -->
<script setup lang="ts">
// useRouter的使用
import { useRouter } from "vue-router";
const router = useRouter();
const jumpFather = () => {
// 编程式跳转和传参
router.push({
path: "/father",
query: {
msg: "hello Vue-Router",
},
});
};
</script>
<template>
<div>
<router-link to="/">todolist</router-link>
|
<router-link to="/father">father</router-link>
</div>
<div>
<van-button type="primary" @click="jumpFather">跳转到father</van-button>
</div>
<router-view></router-view>
</template>
<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>
然后输入npm run dev
测试看看,显示如下,todolist和father点击后有所变化,配置成功啦!
5️⃣ Pinia:状态管理器
部分参考自:https://blog.csdn.net/qq1195566313/category_11672479.html
Pinia 是 Vue 的存储库,允许跨组件/页面共享状态。同样我们输入npm i pinia
安装Pinia,在项目src下创建store文件夹,以后项目中所有的状态管理部分文件都将放到store文件夹下。然后新建index.ts
,创建store:
// src/store/index.ts
import { createPinia } from 'pinia';
const pinia = createPinia();
export default pinia;
挂载store,打开main.ts
,以跟router差不多的方式,挂载进去:
import { createApp } from "vue";
import "./style.css";
import App from "./App.vue";
// 挂载router
import router from "./router/index";
// 挂载store
import store from "@/store";
const app = createApp(App);
app.use(router);
app.use(store);
app.mount("#app");
同样测试一下,在store文件夹下新建types文件夹,types文件夹为状态模块类型管理文件夹,创建模块类型文件home.ts
,写入代码如下:
export type storeHome = {
count: number,
status: boolean
}
在store文件夹下新建modules文件夹,modules文件夹为状态模块管理文件夹,创建模块文件home.ts
,写入代码如下:
import { defineStore } from "pinia";
import { storeHome } from "../types/home";
export const useHomeStore = defineStore("index", {
state: (): storeHome => {
return {
count: 0,
status: false,
};
},
getters: {
curCount(): number {
return this.count;
},
curStatus(): boolean {
return this.status;
},
},
actions: {
updatecount(val: number) {
this.count = val;
},
changeStatus(val: boolean) {
this.status = val;
},
},
});
然后在TodoList.vue文件中测试store是否成功:
<template>
<div>
<h2>这是TodoList组件</h2>
</div>
<div class="main-box">
<h1>状态管理测试界面</h1>
<h1>状态count:{{ homeStore.count }}</h1>
<!-- <h1>状态curCount:{{ calculateCount }}</h1>
<van-button @click="initCount">归零</van-button> -->
<van-button type="success" @click="changeCount">计数</van-button>
<van-button type="danger" @click="randomCount">随机</van-button>
</div>
</template>
<script setup lang="ts">
import { useHomeStore } from "@/store/modules/home";
const homeStore = useHomeStore();
const changeCount = () => {
homeStore.count++;
};
const randomCount = () => {
const num: number = Math.random() * 100;
homeStore.updatecount(Math.floor(num));
};
</script>
<style scoped></style>
输入npm run dev 进入测试,点击todolist,然后点击随机或者计数,可以看到状态count值的变化。
状态的持久化配置等内容暂时不展开,后续需要用到会说明。
至此项目的整体结构为:
6️⃣ Axios:网络请求封装
Axios 是一个基于 promise 的网络请求库,其使用简单,包尺寸小且提供了易于扩展的接口,首先输入npm i axios
安装Axios。
新建 src/utils/http 文件夹,新建 axios.ts
和types.ts
axios.ts
封装axios请求方法:
// src/utils/http/axios.ts
import axios, {
AxiosInstance,
AxiosError,
AxiosRequestConfig,
AxiosResponse,
} from "axios";
import { showToast } from "vant";
import "vant/es/toast/style";
// response interface { code, msg, success }
// 不含 data
interface Result {
code: number;
success: boolean;
msg: string;
}
// request interface,包含 data
interface ResultData<T = any> extends Result {
data?: T;
}
enum RequestEnums {
TIMEOUT = 10000, // 请求超时 request timeout
FAIL = 500, // 服务器异常 server error
LOGINTIMEOUT = 401, // 登录超时 login timeout
SUCCESS = 200, // 请求成功 request successfully
}
// axios 基础配置
const config = {
// 默认地址,可以使用 process Node内置的,
// 这里后续要配置到env.development里
baseURL: "/api",
timeout: RequestEnums.TIMEOUT as number, // 请求超时时间
withCredentials: true, // 跨越的时候允许携带凭证
};
class Request {
request(config: AxiosRequestConfig<any>) {
throw new Error("Method not implemented.");
}
service: AxiosInstance;
constructor(config: AxiosRequestConfig) {
// 实例化 serice
this.service = axios.create(config);
/**
* 请求拦截器
* request -> { 请求拦截器 } -> server
*/
this.service.interceptors.request.use(
(config: AxiosRequestConfig): any => {
const token = localStorage.getItem("token") ?? "";
return {
...config,
headers: {
customToken: "customBearer " + token,
},
};
},
(error: AxiosError) => {
// 请求报错
Promise.reject(error);
}
);
/**
* 响应拦截器
* response -> { 响应拦截器 } -> client
*/
this.service.interceptors.response.use(
(response: AxiosResponse) => {
const { data, config } = response;
if (data.code === RequestEnums.LOGINTIMEOUT) {
// 登录过期,需要重定向至登录页面
localStorage.setItem("token", "");
location.href = "/";
}
if (data.code && data.code !== RequestEnums.SUCCESS) {
showToast({ message: data });
return Promise.reject(data);
}
return data;
},
(error: AxiosError) => {
const { response } = error;
if (response) {
this.handleCode(response.status);
}
if (!window.navigator.onLine) {
showToast({
message: "网络连接失败,请检查网络",
});
// 可以重定向至404页面
}
}
);
}
public handleCode = (code: number): void => {
switch (code) {
case 401:
showToast({
message: "登陆失败,请重新登录",
});
break;
case 500:
showToast({
message: "请求异常,请联系管理员",
});
break;
case 404:
showToast({
message: "404错误,请联系管理员",
});
break;
default:
showToast({
message: "请求失败,请联系管理员",
});
break;
}
};
// 通用方法封装
get<T>(url: string, params?: object): Promise<ResultData<T>> {
return this.service.get(url, { params });
}
post<T>(url: string, params?: object): Promise<ResultData<T>> {
return this.service.post(url, params);
}
put<T>(url: string, params?: object): Promise<ResultData<T>> {
return this.service.put(url, params);
}
delete<T>(url: string, params?: object): Promise<ResultData<T>> {
return this.service.delete(url, { params });
}
}
export default new Request(config);
types.ts
和后端约定好接口返回的数据结构,如:
// src/utils/http/types.ts
// 和后端约定好接口返回的数据结构
export interface Response<T = any> {
code: number | string;
message: string;
result: T;
}
封装axios的方式多种多样,网上有很多种选择,本项目Axios封装主要参考自:https://blog.csdn.net/weixin_56650035/article/details/127467646
测试使用,src目录下新增 api/user/index.ts,内容如下:
// src/api/user/index.ts
import request from "@/utils/http/axios";
import { Response } from "@/utils/http/types";
export interface LoginParams {
username: string;
password: string;
}
export interface UserInfo {
id: number;
username: string;
mobile: number;
email: string;
}
export default {
async login(params: LoginParams) {
return await request.post<Response<UserInfo>>("/user/login", params);
},
};
最后,在某一个vue文件中调用api试试:
// 测试axios的封装
import Api, { LoginParams } from "@/api/user";
const loginInfo: LoginParams = {
username: "name",
password: "string",
};
const login = async () => {
const result = await Api.login(loginInfo);
// do something
console.log(result);
};
五、git commit规范辅助和git版本管理
5.1、设置commit规范辅助
这里暂不使用git Husky和eslint,需要的同学可以配置
使用到Commitizen帮助编写规范的commit message ,首先需要输入npm install commitizen -D
安装Commitizen,然后输入npm i -D cz-customizable
安装cz-customizable自定义的 Commitizen 插件,
配置 根目录创建 .cz-config.js
,内容如下:
module.exports = {
types: [
{
value: ':sparkles: feat',
name: '✨ feat: 新功能'
},
{
value: ':bug: fix',
name: '🐛 fix: 修复bug'
},
{
value: ':tada: init',
name: '🎉 init: 初始化'
},
{
value: ':pencil2: docs',
name: '✏️ docs: 文档变更'
},
{
value: ':lipstick: style',
name: '💄 style: 代码的样式美化'
},
{
value: ':recycle: refactor',
name: '♻️ refactor: 重构'
},
{
value: ':zap: perf',
name: '⚡️ perf: 性能优化'
},
{
value: ':white_check_mark: test',
name: '✅ test: 测试'
},
{
value: ':rewind: revert',
name: '⏪️ revert: 回退'
},
{
value: ':package: build',
name: '📦️ build: 打包'
},
{
value: ':rocket: chore',
name: '🚀 chore: 构建/工程依赖/工具'
},
{
value: ':construction_worker: ci',
name: '👷 ci: CI related changes'
}
],
messages: {
type: '请选择提交类型(必填)',
customScope: '请输入文件修改范围(可选)',
subject: '请简要描述提交(必填)',
body: '请输入详细描述(可选)',
breaking: '列出任何BREAKING CHANGES(可选)',
footer: '请输入要关闭的issue(可选)',
confirmCommit: '确定提交此说明吗?'
},
allowCustomScopes: true,
allowBreakingChanges: [':sparkles: feat', ':bug: fix'],
subjectLimit: 72
}
最后要把package.json的脚本中的"type": "module"
改为"type": "commonjs"
在scrpits中添加一行:"commit": "git add . && cz-customizable"
,如下
"scripts" : {
...
"commit": "git add . && cz-customizable"
}
以后就使用 npm run commit
代替 git commit
5.2、git版本管理
首先在自己的github或者gitee上新建一个空白项目,我命名为KFG-vue,然后复制刚刚创建好的项目地址如:https://gitee.com/airheaven/kfg-vue.git,然后:
git init # 把项目初始化,相当于在项目的跟目录生成一个 .git 目录
git add . # 把项目的所有文件加入暂存区
随后使用npm run commit
进行commit,可以看到规范配置成功,选择辅助信息:
链接远程仓库:git remote add origin https://gitee.com/airheaven/kfg-vue.git
(这里输入你刚刚创建好的仓库),然后git push origin master
将项目推送到master分支
5.3、git日常使用
npm run commit:对代码进行commit
git push origin master:将项目推送到master分支
💡 资源下载与学习
本部分的代码已上传至CSDN:https://download.csdn.net/download/air__Heaven/87530349
项目代码正在gitee同步更新中,请大家给个star🌟,项目地址:https://gitee.com/airheaven/kfg-vue文章来源:https://www.toymoban.com/news/detail-548639.html
🎉 支持我:点赞👍+收藏⭐️+留言📝文章来源地址https://www.toymoban.com/news/detail-548639.html
到了这里,关于【Vue H5项目实战】从0到1的自助点餐系统—— 搭建脚手架(Vue3.2 + Vite + TS + Vant + Pinia + Node.js)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!