【Vue H5项目实战】从0到1的自助点餐系统—— 搭建脚手架(Vue3.2 + Vite + TS + Vant + Pinia + Node.js)

这篇具有很好参考价值的文章主要介绍了【Vue H5项目实战】从0到1的自助点餐系统—— 搭建脚手架(Vue3.2 + Vite + TS + Vant + Pinia + Node.js)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

前言

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验证工具,可以让代码更加规范:

【Vue H5项目实战】从0到1的自助点餐系统—— 搭建脚手架(Vue3.2 + Vite + TS + Vant + Pinia + Node.js),Vue,TypeScript项目实战,vue.js,前端,typescript,vant,vite,Pinia,原力计划

Prettier:前端代码格式工具,可以让代码保持风格一致:

【Vue H5项目实战】从0到1的自助点餐系统—— 搭建脚手架(Vue3.2 + Vite + TS + Vant + Pinia + Node.js),Vue,TypeScript项目实战,vue.js,前端,typescript,vant,vite,Pinia,原力计划
Vue Language Features(Volar):针对Vue3的vscode插件:

【Vue H5项目实战】从0到1的自助点餐系统—— 搭建脚手架(Vue3.2 + Vite + TS + Vant + Pinia + Node.js),Vue,TypeScript项目实战,vue.js,前端,typescript,vant,vite,Pinia,原力计划

二、项目初始化

输入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 H5项目实战】从0到1的自助点餐系统—— 搭建脚手架(Vue3.2 + Vite + TS + Vant + Pinia + Node.js),Vue,TypeScript项目实战,vue.js,前端,typescript,vant,vite,Pinia,原力计划
由于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文件,

【Vue H5项目实战】从0到1的自助点餐系统—— 搭建脚手架(Vue3.2 + Vite + TS + Vant + Pinia + Node.js),Vue,TypeScript项目实战,vue.js,前端,typescript,vant,vite,Pinia,原力计划
文件中配置如下,使程序能够保存时自动使用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并自动注册了组件:
【Vue H5项目实战】从0到1的自助点餐系统—— 搭建脚手架(Vue3.2 + Vite + TS + Vant + Pinia + Node.js),Vue,TypeScript项目实战,vue.js,前端,typescript,vant,vite,Pinia,原力计划

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(""),
    },
  },
});


然后运行项目,即可发现支持了移动端适配,且自适应的调整高度,成功配置
【Vue H5项目实战】从0到1的自助点餐系统—— 搭建脚手架(Vue3.2 + Vite + TS + Vant + Pinia + Node.js),Vue,TypeScript项目实战,vue.js,前端,typescript,vant,vite,Pinia,原力计划

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点击后有所变化,配置成功啦!
【Vue H5项目实战】从0到1的自助点餐系统—— 搭建脚手架(Vue3.2 + Vite + TS + Vant + Pinia + Node.js),Vue,TypeScript项目实战,vue.js,前端,typescript,vant,vite,Pinia,原力计划

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值的变化。
【Vue H5项目实战】从0到1的自助点餐系统—— 搭建脚手架(Vue3.2 + Vite + TS + Vant + Pinia + Node.js),Vue,TypeScript项目实战,vue.js,前端,typescript,vant,vite,Pinia,原力计划
状态的持久化配置等内容暂时不展开,后续需要用到会说明。

至此项目的整体结构为:

【Vue H5项目实战】从0到1的自助点餐系统—— 搭建脚手架(Vue3.2 + Vite + TS + Vant + Pinia + Node.js),Vue,TypeScript项目实战,vue.js,前端,typescript,vant,vite,Pinia,原力计划

6️⃣ Axios:网络请求封装

Axios 是一个基于 promise 的网络请求库,其使用简单,包尺寸小且提供了易于扩展的接口,首先输入npm i axios安装Axios。
新建 src/utils/http 文件夹,新建 axios.tstypes.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
【Vue H5项目实战】从0到1的自助点餐系统—— 搭建脚手架(Vue3.2 + Vite + TS + Vant + Pinia + Node.js),Vue,TypeScript项目实战,vue.js,前端,typescript,vant,vite,Pinia,原力计划
测试使用,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,可以看到规范配置成功,选择辅助信息:
【Vue H5项目实战】从0到1的自助点餐系统—— 搭建脚手架(Vue3.2 + Vite + TS + Vant + Pinia + Node.js),Vue,TypeScript项目实战,vue.js,前端,typescript,vant,vite,Pinia,原力计划

链接远程仓库: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

到了这里,关于【Vue H5项目实战】从0到1的自助点餐系统—— 搭建脚手架(Vue3.2 + Vite + TS + Vant + Pinia + Node.js)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Vue3 脚手架搭建项目详细过程

    如果之前安装了2.0的脚手架,要先卸载掉,输入:npm uninstall vue-cli -g 进行全局卸载 然后重新安装:npm install @vue/cli -g 由于 git bash 来执行命令的时候无法使用键盘上下键来进行选项选择,所以我们要使用  cmd / powershell,这里使用 cmd 1.vue create + 项目名称  2.模板选择,通过键

    2024年02月06日
    浏览(75)
  • 【Android】线上自助点餐系统

    【Android】线上自助点餐系统 效果图 商品数据 由于没有服务器,无法网络获取商品信息,故化繁从简,将需要的商品信息保存成xml文件,次项目将商品信息分为三个文件:标题文件,商品详细信息文件,商品图片文件。 商品标题文件 商品详细文件信息 由于篇幅过长,就没有

    2024年02月08日
    浏览(47)
  • vue-cli5脚手架搭建项目过程详解 -vue组件单元测试

    单元测试是对软件中的最小可测试单元进行测试。(最小可测试单元是要有结果产出的。例如某个方法,单独的某个操作) 单元测试其实是伴随着敏捷开发,它是对更快开发的一种追求。早发现错误比晚发现错误会更好,保证自己的代码符合要求 一: 搭建基于 jest 的 vue 单元

    2023年04月14日
    浏览(111)
  • mac下安装vue cli脚手架并搭建一个简易项目

    1、确定本电脑下node和npm版本是否为项目所需版本。 2、下载vue脚手架 3、创建项目 如果有node,打开终端,输入node -v和npm -v , 确保node和npm的版本,(这里可以根据自己的需求去选择,如果对最新版本的内容有要求,也可以选择最新版本)如果没有node,可以点击nodejs官网去下载

    2024年02月15日
    浏览(98)
  • 基于微信小程序的食堂窗口自助点餐系统

    末尾获取源码 开发语言:Java Java开发工具:JDK1.8 后端框架:SSM 前端框架:VUE 数据库:MySQL5.7 服务器:Tomcat8.5 开发软件:IDEA / Eclipse 小程序运行软件:Wechat 是否Maven项目:是 目录 一、项目简介 二、系统功能 三、系统项目截图 3.1小程序端 3.2商家 3.3管理员 四、核心代码 4

    2024年02月11日
    浏览(47)
  • 基于微信小程序的餐饮自助点餐系统(源码+文档+包运行)

    毕设帮助、技术解答、源码交流 联系方式见文末。 微信小程序的出现,给建设自己的线上餐饮店铺提供了无限可能。商家有了自己的餐饮小程序,用户通过微信里面就可以看到并且可以自助点餐。本课题研究的基于微信小程序的自助点餐系统前后台分离,让商品订单,用户

    2024年02月03日
    浏览(41)
  • 【Vue2+3入门到实战】(17)VUE之VueCli脚手架自定认创建项目、ESlint代码规范与修复、 ESlint自动修正插件的使用 详细示例

    VueCli脚手架自定认创建项目 ESlint代码规范与修复 ESlint自动修正插件 1.安装脚手架 (已安装) 2.创建项目 选项 手动选择功能 选择vue的版本 是否使用history模式 选择css预处理 选择eslint的风格 (eslint 代码规范的检验工具,检验代码是否符合规范) 比如:const age = 18; = 报错!多加

    2024年02月03日
    浏览(58)
  • 基于微信小程序的奶茶自助点餐单送餐系统的设计与实现(源码+论文)_v_156

    摘   要 移动互联网时代的到来,智能手机的普及,在众多手机软件中,微信被广大用户认可并广泛被使用。随着微信的发展,微信的功能越来越齐全,越来越多的个人以及企业都看大了微信营销的优势,都逐渐加入都了微信营销中,即微商。其信息传播速度快的特点,能都

    2024年02月03日
    浏览(41)
  • uniapp使用cli脚手架创建兼容小程序和h5的项目 自动化命令打包运行

    HbuliderX搭建项目结构: CLI搭建项目结构: CLI方式搭建uniapp项目: 大家可以看下两种方式搭建的项目文件夹目录有什么区别,上面的是HbuilderX模版搭建的小程序项目,下面的是cli搭建的项目,先把my-test项目中src下面的文件全部删除,然后我把小程序代码全部塞进了src文件夹下

    2024年02月16日
    浏览(75)
  • 基于npm CLI脚手架的uniapp项目创建、运行与打包全攻略(微信小程序、H5、APP全覆盖)

    除了使用HBuilderX工具可视化搭建项目外,DCloud官方还提供了一个脚手架用于命令行搭建项目。 uni-app项目支持 uni cli和 HBuilderX cli两种脚手架工具: uni cli:面向非HBuilderX的用户(如习惯使用vscode/webstorm的开发者),提供创建项目、编译发行等能力;在App平台,仅支持生成离线

    2024年04月16日
    浏览(76)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包