国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

【Vue H5項(xiàng)目實(shí)戰(zhàn)】從0到1的自助點(diǎn)餐系統(tǒng)—— 搭建腳手架(Vue3.2 + Vite + TS + Vant + Pinia + Node.js)

這篇具有很好參考價(jià)值的文章主要介紹了【Vue H5項(xiàng)目實(shí)戰(zhàn)】從0到1的自助點(diǎn)餐系統(tǒng)—— 搭建腳手架(Vue3.2 + Vite + TS + Vant + Pinia + Node.js)。希望對大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問。

前言

H5 項(xiàng)目基于 Web 技術(shù),可以在智能手機(jī)、平板電腦等移動(dòng)設(shè)備上的瀏覽器中運(yùn)行,無需下載和安裝任何應(yīng)用程序,且H5 項(xiàng)目的代碼和資源可以集中在服務(wù)器端進(jìn)行管理,只需更新服務(wù)器上的代碼,即可讓所有顧客訪問到最新的系統(tǒng)版本。

本系列將以肯德基自助點(diǎn)餐頁面為模板,搭建一款自助點(diǎn)餐系統(tǒng),第一次開發(fā)移動(dòng)端h5項(xiàng)目,免不了有所差錯(cuò)和不足,歡迎各位大佬指正。

項(xiàng)目代碼正在gitee同步更新中,項(xiàng)目地址:https://gitee.com/airheaven/kfg-vue,學(xué)習(xí)前請大家給個(gè)star哦??

技術(shù)棧

Vue3.2 + Vite + TS + Vant + Pinia + Node.js

一、起始準(zhǔn)備

1.1、安裝nvm

nvm 全英文也叫 node.js version management,是一個(gè) nodejs 的版本管理工具,用于管理nodejs。
首先進(jìn)入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會(huì)自動(dòng)幫你安裝好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查看已經(jīng)安裝過的node版本。

安裝好node和npm后,需要使用nvm use 16.16.0啟用該版本。

1.3、利用npm安裝Vite

既然是新項(xiàng)目,且用的是Vue3.2,那么我們必須用上現(xiàn)在嘎嘎香 嘎嘎快的Vite,Vite是新一代的前端開發(fā)與構(gòu)建工具,具有開箱即用、高度的可擴(kuò)展性和完整的類型支持。

使用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中找到擴(kuò)展,需要安裝的擴(kuò)展插件有:

ESlint:開源的JavaScript驗(yàn)證工具,可以讓代碼更加規(guī)范:

【Vue H5項(xiàng)目實(shí)戰(zhàn)】從0到1的自助點(diǎn)餐系統(tǒng)—— 搭建腳手架(Vue3.2 + Vite + TS + Vant + Pinia + Node.js),Vue,TypeScript項(xiàng)目實(shí)戰(zhàn),vue.js,前端,typescript,vant,vite,Pinia,原力計(jì)劃

Prettier:前端代碼格式工具,可以讓代碼保持風(fēng)格一致:

【Vue H5項(xiàng)目實(shí)戰(zhàn)】從0到1的自助點(diǎn)餐系統(tǒng)—— 搭建腳手架(Vue3.2 + Vite + TS + Vant + Pinia + Node.js),Vue,TypeScript項(xiàng)目實(shí)戰(zhàn),vue.js,前端,typescript,vant,vite,Pinia,原力計(jì)劃
Vue Language Features(Volar):針對Vue3的vscode插件:

【Vue H5項(xiàng)目實(shí)戰(zhàn)】從0到1的自助點(diǎn)餐系統(tǒng)—— 搭建腳手架(Vue3.2 + Vite + TS + Vant + Pinia + Node.js),Vue,TypeScript項(xiàng)目實(shí)戰(zhàn),vue.js,前端,typescript,vant,vite,Pinia,原力計(jì)劃

二、項(xiàng)目初始化

輸入npm create vite@latest使用Vite初始化項(xiàng)目,填寫項(xiàng)目名稱(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進(jìn)入KFG-vue項(xiàng)目目錄,輸入:npm install安裝項(xiàng)目所需的基本依賴:

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運(yùn)行項(xiàng)目,控制臺(tái)會(huì)輸出網(wǎng)址,如http://127.0.0.1:5173/即可以查看初始化好的項(xiàng)目:

> 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

然后我們需要?jiǎng)h除一些初始化項(xiàng)目中不需要的東西,刪除public里的vite.svg,刪除assets里面的vue.svg,刪除components里面的HelloWorld.vue,清空style.css,清空App.vue里的內(nèi)容(僅僅保留最基本的vue3模板):
【Vue H5項(xiàng)目實(shí)戰(zhàn)】從0到1的自助點(diǎn)餐系統(tǒng)—— 搭建腳手架(Vue3.2 + Vite + TS + Vant + Pinia + Node.js),Vue,TypeScript項(xiàng)目實(shí)戰(zhàn),vue.js,前端,typescript,vant,vite,Pinia,原力計(jì)劃
由于vue中ts無法識(shí)別引入的vue文件,引入模塊后會(huì)提示打不到module,但是編譯可能成功,運(yùn)行也不報(bào)錯(cuò),為了我的強(qiáng)迫癥我選擇在src文件夾下新增一個(gè)env.d.ts文件解決這個(gè)問題:

// 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;
}

三、代碼規(guī)范配置(可選)

插件拿來不一定能夠完全適用,需要提供了一些額外的適用于 ts 和vue語法的規(guī)則,配置以下項(xiàng):

ESlint配置:輸入npx eslint --init,選擇如下:

√ How would you like to use ESLint? · problems(第二個(gè))
√ What type of modules does your project use? · esm(第一個(gè))
√ Which framework does your project use? · vue
√ Does your project use TypeScript? · No / Yes
√ Where does your code run? · browser, node(兩個(gè)都勾選)
√ What format do you want your config file to be in? · JavaScript

Prettier配置:輸入npm i prettier eslint-config-prettier eslint-plugin-prettier -D
創(chuàng)建prettier.cjs文件,文件中輸入:

// prettier.cjs
module.exports = {
  printWidth: 100,
  tabWidth: 2,
  useTabs: false, // 是否使用tab進(jìn)行縮進(jìn),默認(rèn)為false
  singleQuote: true, // 是否使用單引號代替雙引號,默認(rèn)為false
  semi: true, // 行尾是否使用分號,默認(rèn)為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', // 指定要使用的解析器
  // 給解析器傳入一些其他的配置參數(shù)
  parserOptions: {
    ecmaVersion: 'latest', // 支持的es版本
    parser: '@typescript-eslint/parser',
    sourceType: 'module', // 模塊類型,默認(rèn)為script,我們設(shè)置為module
  },
  plugins: ['vue', '@typescript-eslint', 'prettier'], // eslint-plugin- 可以省略
  rules: {
    'vue/multi-word-component-names': 'off',
    '@typescript-eslint/no-var-requires': 'off',
  },
};

配置保存文件自動(dòng)格式化:在項(xiàng)目的.vscode中新建一個(gè)setting.json文件,

【Vue H5項(xiàng)目實(shí)戰(zhàn)】從0到1的自助點(diǎn)餐系統(tǒng)—— 搭建腳手架(Vue3.2 + Vite + TS + Vant + Pinia + Node.js),Vue,TypeScript項(xiàng)目實(shí)戰(zhàn),vue.js,前端,typescript,vant,vite,Pinia,原力計(jì)劃
文件中配置如下,使程序能夠保存時(shí)自動(dòng)使用eslint格式化(懶人福音),setting.json配置 如下所示:

// .vscode/setting.json
  {
  	"editor.codeActionsOnSave": {
  		"source.fixAll.eslint": true
    },
  // #每次保存的時(shí)候自動(dòng)格式化
  	"editor.formatOnSave": true,
  	"editor.formatOnType": true,
  // #每次保存的時(shí)候?qū)⒋a按eslint格式進(jìn)行修復(fù)
  	"eslint.autoFixOnSave": true,
  	"eslint.format.enable": true,
  } 

添加lint命令(可選):package.json中進(jìn)行配置,可以運(yùn)行npm run lint檢查代碼:

// package.json

// 可以運(yùn)行`npm run lint`檢查代碼
"lint": "eslint --ext .js,.vue,.ts src --fix"

四、項(xiàng)目搭建

4.1、清除默認(rèn)樣式

在網(wǎng)上找一個(gè)reset.css文件,放入到src/styles文件夾(可能需要新建)中,從而清除默認(rèn)樣式:

/* src/styles */
/* 清除內(nèi)外邊距 */
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;
}

/* 設(shè)置默認(rèn)字體 */
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; } /* 將粗體扶細(xì) */
code, kbd, pre, samp, tt { font-family: "Courier New", Courier, monospace; } /* 統(tǒng)一等寬字體 */
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瀏覽器默認(rèn)也顯示垂直滾動(dòng)條,防止因滾動(dòng)條引起的閃爍 */
html { overflow-y: scroll; }

a:link:hover{
    color : rgb(79, 76, 212) !important;
    text-decoration: underline;
}

/* 清除浮動(dòng) */
.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, 加入以下內(nèi)容(resolve的alias),設(shè)置別名@:

// vite.config.ts
import { defineConfig } from "vite";
import vue from "@vitejs/plugin-vue";

// 設(shè)置路徑
import { resolve } from "path";

// Vant聲明和按需引入
import Component from "unplugin-vue-components/vite";
import { VantResolver } from "unplugin-vue-components/resolvers";

// vw方案,將px轉(zhuǎn)為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", // 要轉(zhuǎn)化的單位
          viewportWidth: 750, // UI設(shè)計(jì)稿的寬度,一般寫 320

          // 下面的不常用,上面的常用
          unitPrecision: 6, // 轉(zhuǎn)換后的精度,即小數(shù)點(diǎn)位數(shù)
          propList: ["*"], // 指定轉(zhuǎn)換的css屬性的單位,*代表全部css屬性的單位都進(jìn)行轉(zhuǎn)換
          viewportUnit: "vw", // 指定需要轉(zhuǎn)換成的視窗單位,默認(rèn)vw
          fontViewportUnit: "vw", // 指定字體需要轉(zhuǎn)換成的視窗單位,默認(rèn)vw
          selectorBlackList: ["ignore-"], // 指定不轉(zhuǎn)換為視窗單位的類名,
          minPixelValue: 1, // 默認(rèn)值1,小于或等于1px則不進(jìn)行轉(zhuǎn)換
          mediaQuery: true, // 是否在媒體查詢的css代碼中也進(jìn)行轉(zhuǎn)換,默認(rèn)false
          replace: true, // 是否轉(zhuǎn)換后直接更換屬性值
          landscape: false, // 是否處理橫屏情況
        }),
      ],
    },
  },
  resolve: {
    alias: {
      "@": resolve(__dirname, "./src"),
      "*": resolve(""),
    },
  },
});

然后在tsconfig.json,加入以下內(nèi)容(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": ".",
    // 用于設(shè)置解析非相對模塊名稱的基本目錄,相對模塊不會(huì)受到baseUrl的影響
    "paths": {
      "@/*": ["src/*"]
    }
  },
  "include": ["src/**/*.ts", "src/**/*.d.ts", "src/**/*.tsx", "src/**/*.vue"],
  "references": [{ "path": "./tsconfig.node.json" }]
}

4.3、項(xiàng)目搭建

1?? Less: CSS預(yù)處理器

我選用了less作為CSS預(yù)處理器,需要安裝相應(yīng)的預(yù)處理器依賴:npm i less -D
如果需要規(guī)定全局樣式的話,可以配置一下在src/asserts/less文件夾下新建一個(gè)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: 輕量可定制的移動(dòng)端組件庫

選用移動(dòng)端最常用的Vant作為組件庫,輸入npm i vant 安裝Vant。

然后安裝按需引入插件,輸入npm i unplugin-vue-components -D安裝插件,它可以自動(dòng)引入組件,并按需引入組件的樣式。相比于常規(guī)用法,這種方式可以按需引入組件的 CSS 樣式,從而減少一部分代碼體積,但使用起來會(huì)變得繁瑣一些。

配置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 會(huì)解析模板并自動(dòng)注冊對應(yīng)的組件。
可以試試在App.vue中寫入:

<script setup lang="ts"></script>

<template>
  <van-button type="primary">Hello World</van-button>
</template>

<style scoped></style>

顯示如下則成功引入Vant并自動(dòng)注冊了組件:
【Vue H5項(xiàng)目實(shí)戰(zhàn)】從0到1的自助點(diǎn)餐系統(tǒng)—— 搭建腳手架(Vue3.2 + Vite + TS + Vant + Pinia + Node.js),Vue,TypeScript項(xiàng)目實(shí)戰(zhàn),vue.js,前端,typescript,vant,vite,Pinia,原力計(jì)劃

3?? vw/vh方案:移動(dòng)端適配

移動(dòng)端適配通常使用的有rem方案和vw/vh方案,我選用的是vw方案,首先輸入npm install postcss-px-to-viewport -D安裝插件,將 px 轉(zhuǎn)化成 vw,安裝完成后,修改 vite.config.ts聲明插件(由于 vite 中已經(jīng)內(nèi)聯(lián)了 postcss,所以無需創(chuàng)建 postcss.config.js文件來聲明插件):

// vite.config.ts
import { defineConfig } from "vite";
import vue from "@vitejs/plugin-vue";
// 設(shè)置路徑
import { resolve } from "path";
// Vant聲明和按需引入
import Component from "unplugin-vue-components/vite";
import { VantResolver } from "unplugin-vue-components/resolvers";
// vw方案,將px轉(zhuǎn)為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", // 要轉(zhuǎn)化的單位
          viewportWidth: 750, // UI設(shè)計(jì)稿的寬度,一般寫 320

          // 下面的不常用,上面的常用
          unitPrecision: 6, // 轉(zhuǎn)換后的精度,即小數(shù)點(diǎn)位數(shù)
          propList: ["*"], // 指定轉(zhuǎn)換的css屬性的單位,*代表全部css屬性的單位都進(jìn)行轉(zhuǎn)換
          viewportUnit: "vw", // 指定需要轉(zhuǎn)換成的視窗單位,默認(rèn)vw
          fontViewportUnit: "vw", // 指定字體需要轉(zhuǎn)換成的視窗單位,默認(rèn)vw
          selectorBlackList: ["ignore-"], // 指定不轉(zhuǎn)換為視窗單位的類名,
          minPixelValue: 1, // 默認(rèn)值1,小于或等于1px則不進(jìn)行轉(zhuǎn)換
          mediaQuery: true, // 是否在媒體查詢的css代碼中也進(jìn)行轉(zhuǎn)換,默認(rèn)false
          replace: true, // 是否轉(zhuǎn)換后直接更換屬性值
          landscape: false, // 是否處理橫屏情況
        }),
      ],
    },
  },
  resolve: {
    alias: {
      "@": resolve(__dirname, "./src"),
      "*": resolve(""),
    },
  },
});


然后運(yùn)行項(xiàng)目,即可發(fā)現(xiàn)支持了移動(dòng)端適配,且自適應(yīng)的調(diào)整高度,成功配置
【Vue H5項(xiàng)目實(shí)戰(zhàn)】從0到1的自助點(diǎn)餐系統(tǒng)—— 搭建腳手架(Vue3.2 + Vite + TS + Vant + Pinia + Node.js),Vue,TypeScript項(xiàng)目實(shí)戰(zhàn),vue.js,前端,typescript,vant,vite,Pinia,原力計(jì)劃

4?? Vue Router:路由配置

部分參考自:https://blog.csdn.net/jason_renyu/article/details/123261823

Vue Router是Vue.js 的官方路由,非常方便好用,在控制臺(tái)輸入:npm i vue-router@4安裝Vue Router,新建router文件夾,新建router/index.ts,配置如下:

/**
 * createRouter 這個(gè)為創(chuàng)建路由的方法
 * createWebHashHistory 這個(gè)就是vue2中路由的模式,
 *                      這里的是hash模式,這個(gè)還可以是createWebHistory等
 * RouteRecordRaw 這個(gè)為要添加的路由記錄,也可以說是routes的ts類型
 */
import { createRouter, createWebHashHistory, RouteRecordRaw } from "vue-router";
// 路由記錄,這個(gè)跟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,內(nèi)容如下:
Father.vue:

<!-- compnents/Father.vue -->
<template>
  <div>
    <h2>這是Father組件</h2>
    <h3>路由傳入的參數(shù)為:{{ route.query.msg }}</h3>
  </div>
</template>

<script setup lang="ts">
import { ref } from "vue";
// 路由接收參數(shù)
import { useRoute } from "vue-router";
const route = useRoute();
// 接收路由傳入的參數(shù)
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中測試調(diào)用:

<!-- App.vue -->
<script setup lang="ts">
// useRouter的使用
import { useRouter } from "vue-router";
const router = useRouter();

const jumpFather = () => {
  // 編程式跳轉(zhuǎn)和傳參
  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">跳轉(zhuǎn)到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點(diǎn)擊后有所變化,配置成功啦!
【Vue H5項(xiàng)目實(shí)戰(zhàn)】從0到1的自助點(diǎn)餐系統(tǒng)—— 搭建腳手架(Vue3.2 + Vite + TS + Vant + Pinia + Node.js),Vue,TypeScript項(xiàng)目實(shí)戰(zhàn),vue.js,前端,typescript,vant,vite,Pinia,原力計(jì)劃

5?? Pinia:狀態(tài)管理器

部分參考自:https://blog.csdn.net/qq1195566313/category_11672479.html

Pinia 是 Vue 的存儲(chǔ)庫,允許跨組件/頁面共享狀態(tài)。同樣我們輸入npm i pinia安裝Pinia,在項(xiàng)目src下創(chuàng)建store文件夾,以后項(xiàng)目中所有的狀態(tài)管理部分文件都將放到store文件夾下。然后新建index.ts創(chuàng)建store

// src/store/index.ts
import { createPinia } from 'pinia';

const pinia = createPinia();

export default pinia;

掛載store,打開main.ts,以跟router差不多的方式,掛載進(jìn)去:

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文件夾為狀態(tài)模塊類型管理文件夾,創(chuàng)建模塊類型文件home.ts,寫入代碼如下:

export type storeHome = {
    count: number,
    status: boolean
}

在store文件夾下新建modules文件夾,modules文件夾為狀態(tài)模塊管理文件夾,創(chuàng)建模塊文件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>狀態(tài)管理測試界面</h1>
    <h1>狀態(tài)count:{{ homeStore.count }}</h1>
    <!-- <h1>狀態(tài)curCount:{{ calculateCount }}</h1>
    <van-button @click="initCount">歸零</van-button> -->
    <van-button type="success" @click="changeCount">計(jì)數(shù)</van-button>
    <van-button type="danger" @click="randomCount">隨機(jī)</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 進(jìn)入測試,點(diǎn)擊todolist,然后點(diǎn)擊隨機(jī)或者計(jì)數(shù),可以看到狀態(tài)count值的變化。
【Vue H5項(xiàng)目實(shí)戰(zhàn)】從0到1的自助點(diǎn)餐系統(tǒng)—— 搭建腳手架(Vue3.2 + Vite + TS + Vant + Pinia + Node.js),Vue,TypeScript項(xiàng)目實(shí)戰(zhàn),vue.js,前端,typescript,vant,vite,Pinia,原力計(jì)劃
狀態(tài)的持久化配置等內(nèi)容暫時(shí)不展開,后續(xù)需要用到會(huì)說明。

至此項(xiàng)目的整體結(jié)構(gòu)為:

【Vue H5項(xiàng)目實(shí)戰(zhàn)】從0到1的自助點(diǎn)餐系統(tǒng)—— 搭建腳手架(Vue3.2 + Vite + TS + Vant + Pinia + Node.js),Vue,TypeScript項(xiàng)目實(shí)戰(zhàn),vue.js,前端,typescript,vant,vite,Pinia,原力計(jì)劃

6?? Axios:網(wǎng)絡(luò)請求封裝

Axios 是一個(gè)基于 promise 的網(wǎng)絡(luò)請求庫,其使用簡單,包尺寸小且提供了易于擴(kuò)展的接口,首先輸入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, // 請求超時(shí) request timeout
  FAIL = 500, // 服務(wù)器異常 server error
  LOGINTIMEOUT = 401, // 登錄超時(shí) login timeout
  SUCCESS = 200, // 請求成功 request successfully
}

// axios 基礎(chǔ)配置
const config = {
  // 默認(rèn)地址,可以使用 process Node內(nèi)置的,
  // 這里后續(xù)要配置到env.development里
  baseURL: "/api",
  timeout: RequestEnums.TIMEOUT as number, // 請求超時(shí)時(shí)間
  withCredentials: true, // 跨越的時(shí)候允許攜帶憑證
};

class Request {
  request(config: AxiosRequestConfig<any>) {
    throw new Error("Method not implemented.");
  }
  service: AxiosInstance;

  constructor(config: AxiosRequestConfig) {
    // 實(shí)例化 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) => {
        // 請求報(bào)錯(cuò)
        Promise.reject(error);
      }
    );

    /**
     * 響應(yīng)攔截器
     * response -> { 響應(yīng)攔截器 } -> 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: "網(wǎng)絡(luò)連接失敗,請檢查網(wǎng)絡(luò)",
          });
          // 可以重定向至404頁面
        }
      }
    );
  }

  public handleCode = (code: number): void => {
    switch (code) {
      case 401:
        showToast({
          message: "登陸失敗,請重新登錄",
        });
        break;
      case 500:
        showToast({
          message: "請求異常,請聯(lián)系管理員",
        });
        break;
      case 404:
        showToast({
          message: "404錯(cuò)誤,請聯(lián)系管理員",
        });
        break;
      default:
        showToast({
          message: "請求失敗,請聯(lián)系管理員",
        });
        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和后端約定好接口返回的數(shù)據(jù)結(jié)構(gòu),如:

// src/utils/http/types.ts		

// 和后端約定好接口返回的數(shù)據(jù)結(jié)構(gòu)
export interface Response<T = any> {
  code: number | string;
  message: string;
  result: T;
}

封裝axios的方式多種多樣,網(wǎng)上有很多種選擇,本項(xiàng)目Axios封裝主要參考自:https://blog.csdn.net/weixin_56650035/article/details/127467646
【Vue H5項(xiàng)目實(shí)戰(zhàn)】從0到1的自助點(diǎn)餐系統(tǒng)—— 搭建腳手架(Vue3.2 + Vite + TS + Vant + Pinia + Node.js),Vue,TypeScript項(xiàng)目實(shí)戰(zhàn),vue.js,前端,typescript,vant,vite,Pinia,原力計(jì)劃
測試使用,src目錄下新增 api/user/index.ts,內(nèi)容如下:

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

最后,在某一個(gè)vue文件中調(diào)用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規(guī)范輔助和git版本管理

5.1、設(shè)置commit規(guī)范輔助

這里暫不使用git Husky和eslint,需要的同學(xué)可以配置

使用到Commitizen幫助編寫規(guī)范的commit message ,首先需要輸入npm install commitizen -D安裝Commitizen,然后輸入npm i -D cz-customizable安裝cz-customizable自定義的 Commitizen 插件,
配置 根目錄創(chuàng)建 .cz-config.js,內(nèi)容如下:

module.exports = {
    types: [
      {
        value: ':sparkles: feat',
        name: '? feat:     新功能'
      },
      {
        value: ':bug: fix',
        name: '?? fix:      修復(fù)bug'
      },
      {
        value: ':tada: init',
        name: '?? init:     初始化'
      },
      {
        value: ':pencil2: docs',
        name: '??  docs:     文檔變更'
      },
      {
        value: ':lipstick: style',
        name: '?? style:    代碼的樣式美化'
      },
      {
        value: ':recycle: refactor',
        name: '??  refactor: 重構(gòu)'
      },
      {
        value: ':zap: perf',
        name: '?? perf:     性能優(yōu)化'
      },
      {
        value: ':white_check_mark: test',
        name: '? test:     測試'
      },
      {
        value: ':rewind: revert',
        name: '?? revert:   回退'
      },
      {
        value: ':package: build',
        name: '??? build:    打包'
      },
      {
        value: ':rocket: chore',
        name: '?? chore:    構(gòu)建/工程依賴/工具'
      },
      {
        value: ':construction_worker: ci',
        name: '?? ci:       CI related changes'
      }
    ],
    messages: {
      type: '請選擇提交類型(必填)',
      customScope: '請輸入文件修改范圍(可選)',
      subject: '請簡要描述提交(必填)',
      body: '請輸入詳細(xì)描述(可選)',
      breaking: '列出任何BREAKING CHANGES(可選)',
      footer: '請輸入要關(guān)閉的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上新建一個(gè)空白項(xiàng)目,我命名為KFG-vue,然后復(fù)制剛剛創(chuàng)建好的項(xiàng)目地址如:https://gitee.com/airheaven/kfg-vue.git,然后:

git init   # 把項(xiàng)目初始化,相當(dāng)于在項(xiàng)目的跟目錄生成一個(gè) .git 目錄
git add .    # 把項(xiàng)目的所有文件加入暫存區(qū)

隨后使用npm run commit 進(jìn)行commit,可以看到規(guī)范配置成功,選擇輔助信息:
【Vue H5項(xiàng)目實(shí)戰(zhàn)】從0到1的自助點(diǎn)餐系統(tǒng)—— 搭建腳手架(Vue3.2 + Vite + TS + Vant + Pinia + Node.js),Vue,TypeScript項(xiàng)目實(shí)戰(zhàn),vue.js,前端,typescript,vant,vite,Pinia,原力計(jì)劃

鏈接遠(yuǎn)程倉庫:git remote add origin https://gitee.com/airheaven/kfg-vue.git(這里輸入你剛剛創(chuàng)建好的倉庫),然后git push origin master將項(xiàng)目推送到master分支

5.3、git日常使用

npm run commit:對代碼進(jìn)行commit
git push origin master:將項(xiàng)目推送到master分支

?? 資源下載與學(xué)習(xí)

本部分的代碼已上傳至CSDN:https://download.csdn.net/download/air__Heaven/87530349

項(xiàng)目代碼正在gitee同步更新中,請大家給個(gè)star??,項(xiàng)目地址:https://gitee.com/airheaven/kfg-vue

?? 支持我:點(diǎn)贊??+收藏??+留言??文章來源地址http://www.zghlxwxcb.cn/news/detail-548639.html

到了這里,關(guān)于【Vue H5項(xiàng)目實(shí)戰(zhàn)】從0到1的自助點(diǎn)餐系統(tǒng)—— 搭建腳手架(Vue3.2 + Vite + TS + Vant + Pinia + Node.js)的文章就介紹完了。如果您還想了解更多內(nèi)容,請?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • Vue3 腳手架搭建項(xiàng)目詳細(xì)過程

    Vue3 腳手架搭建項(xiàng)目詳細(xì)過程

    如果之前安裝了2.0的腳手架,要先卸載掉,輸入:npm uninstall vue-cli -g 進(jìn)行全局卸載 然后重新安裝:npm install @vue/cli -g 由于 git bash 來執(zhí)行命令的時(shí)候無法使用鍵盤上下鍵來進(jìn)行選項(xiàng)選擇,所以我們要使用? cmd / powershell,這里使用 cmd 1.vue create + 項(xiàng)目名稱 ?2.模板選擇,通過鍵

    2024年02月06日
    瀏覽(93)
  • 【Android】線上自助點(diǎn)餐系統(tǒng)

    【Android】線上自助點(diǎn)餐系統(tǒng)

    【Android】線上自助點(diǎn)餐系統(tǒng) 效果圖 商品數(shù)據(jù) 由于沒有服務(wù)器,無法網(wǎng)絡(luò)獲取商品信息,故化繁從簡,將需要的商品信息保存成xml文件,次項(xiàng)目將商品信息分為三個(gè)文件:標(biāo)題文件,商品詳細(xì)信息文件,商品圖片文件。 商品標(biāo)題文件 商品詳細(xì)文件信息 由于篇幅過長,就沒有

    2024年02月08日
    瀏覽(20)
  • vue-cli5腳手架搭建項(xiàng)目過程詳解 -vue組件單元測試

    vue-cli5腳手架搭建項(xiàng)目過程詳解 -vue組件單元測試

    單元測試是對軟件中的最小可測試單元進(jìn)行測試。(最小可測試單元是要有結(jié)果產(chǎn)出的。例如某個(gè)方法,單獨(dú)的某個(gè)操作) 單元測試其實(shí)是伴隨著敏捷開發(fā),它是對更快開發(fā)的一種追求。早發(fā)現(xiàn)錯(cuò)誤比晚發(fā)現(xiàn)錯(cuò)誤會(huì)更好,保證自己的代碼符合要求 一: 搭建基于 jest 的 vue 單元

    2023年04月14日
    瀏覽(439)
  • mac下安裝vue cli腳手架并搭建一個(gè)簡易項(xiàng)目

    mac下安裝vue cli腳手架并搭建一個(gè)簡易項(xiàng)目

    1、確定本電腦下node和npm版本是否為項(xiàng)目所需版本。 2、下載vue腳手架 3、創(chuàng)建項(xiàng)目 如果有node,打開終端,輸入node -v和npm -v , 確保node和npm的版本,(這里可以根據(jù)自己的需求去選擇,如果對最新版本的內(nèi)容有要求,也可以選擇最新版本)如果沒有node,可以點(diǎn)擊nodejs官網(wǎng)去下載

    2024年02月15日
    瀏覽(100)
  • 基于微信小程序的食堂窗口自助點(diǎn)餐系統(tǒng)

    基于微信小程序的食堂窗口自助點(diǎn)餐系統(tǒng)

    末尾獲取源碼 開發(fā)語言:Java Java開發(fā)工具:JDK1.8 后端框架:SSM 前端框架:VUE 數(shù)據(jù)庫:MySQL5.7 服務(wù)器:Tomcat8.5 開發(fā)軟件:IDEA / Eclipse 小程序運(yùn)行軟件:Wechat 是否Maven項(xiàng)目:是 目錄 一、項(xiàng)目簡介 二、系統(tǒng)功能 三、系統(tǒng)項(xiàng)目截圖 3.1小程序端 3.2商家 3.3管理員 四、核心代碼 4

    2024年02月11日
    瀏覽(16)
  • 基于微信小程序的餐飲自助點(diǎn)餐系統(tǒng)(源碼+文檔+包運(yùn)行)

    基于微信小程序的餐飲自助點(diǎn)餐系統(tǒng)(源碼+文檔+包運(yùn)行)

    畢設(shè)幫助、技術(shù)解答、源碼交流 聯(lián)系方式見文末。 微信小程序的出現(xiàn),給建設(shè)自己的線上餐飲店鋪提供了無限可能。商家有了自己的餐飲小程序,用戶通過微信里面就可以看到并且可以自助點(diǎn)餐。本課題研究的基于微信小程序的自助點(diǎn)餐系統(tǒng)前后臺(tái)分離,讓商品訂單,用戶

    2024年02月03日
    瀏覽(19)
  • 【Vue2+3入門到實(shí)戰(zhàn)】(17)VUE之VueCli腳手架自定認(rèn)創(chuàng)建項(xiàng)目、ESlint代碼規(guī)范與修復(fù)、 ESlint自動(dòng)修正插件的使用 詳細(xì)示例

    【Vue2+3入門到實(shí)戰(zhàn)】(17)VUE之VueCli腳手架自定認(rèn)創(chuàng)建項(xiàng)目、ESlint代碼規(guī)范與修復(fù)、 ESlint自動(dòng)修正插件的使用 詳細(xì)示例

    VueCli腳手架自定認(rèn)創(chuàng)建項(xiàng)目 ESlint代碼規(guī)范與修復(fù) ESlint自動(dòng)修正插件 1.安裝腳手架 (已安裝) 2.創(chuàng)建項(xiàng)目 選項(xiàng) 手動(dòng)選擇功能 選擇vue的版本 是否使用history模式 選擇css預(yù)處理 選擇eslint的風(fēng)格 (eslint 代碼規(guī)范的檢驗(yàn)工具,檢驗(yàn)代碼是否符合規(guī)范) 比如:const age = 18; = 報(bào)錯(cuò)!多加

    2024年02月03日
    瀏覽(127)
  • 基于微信小程序的奶茶自助點(diǎn)餐單送餐系統(tǒng)的設(shè)計(jì)與實(shí)現(xiàn)(源碼+論文)_v_156

    基于微信小程序的奶茶自助點(diǎn)餐單送餐系統(tǒng)的設(shè)計(jì)與實(shí)現(xiàn)(源碼+論文)_v_156

    摘 ? 要 移動(dòng)互聯(lián)網(wǎng)時(shí)代的到來,智能手機(jī)的普及,在眾多手機(jī)軟件中,微信被廣大用戶認(rèn)可并廣泛被使用。隨著微信的發(fā)展,微信的功能越來越齊全,越來越多的個(gè)人以及企業(yè)都看大了微信營銷的優(yōu)勢,都逐漸加入都了微信營銷中,即微商。其信息傳播速度快的特點(diǎn),能都

    2024年02月03日
    瀏覽(29)
  • uniapp使用cli腳手架創(chuàng)建兼容小程序和h5的項(xiàng)目 自動(dòng)化命令打包運(yùn)行

    uniapp使用cli腳手架創(chuàng)建兼容小程序和h5的項(xiàng)目 自動(dòng)化命令打包運(yùn)行

    HbuliderX搭建項(xiàng)目結(jié)構(gòu): CLI搭建項(xiàng)目結(jié)構(gòu): CLI方式搭建uniapp項(xiàng)目: 大家可以看下兩種方式搭建的項(xiàng)目文件夾目錄有什么區(qū)別,上面的是HbuilderX模版搭建的小程序項(xiàng)目,下面的是cli搭建的項(xiàng)目,先把my-test項(xiàng)目中src下面的文件全部刪除,然后我把小程序代碼全部塞進(jìn)了src文件夾下

    2024年02月16日
    瀏覽(36)
  • 基于npm CLI腳手架的uniapp項(xiàng)目創(chuàng)建、運(yùn)行與打包全攻略(微信小程序、H5、APP全覆蓋)

    基于npm CLI腳手架的uniapp項(xiàng)目創(chuàng)建、運(yùn)行與打包全攻略(微信小程序、H5、APP全覆蓋)

    除了使用HBuilderX工具可視化搭建項(xiàng)目外,DCloud官方還提供了一個(gè)腳手架用于命令行搭建項(xiàng)目。 uni-app項(xiàng)目支持 uni cli和 HBuilderX cli兩種腳手架工具: uni cli:面向非HBuilderX的用戶(如習(xí)慣使用vscode/webstorm的開發(fā)者),提供創(chuàng)建項(xiàng)目、編譯發(fā)行等能力;在App平臺(tái),僅支持生成離線

    2024年04月16日
    瀏覽(118)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包