Vue2 与 Vue3 的区别
- Vue3由于完全由TS进行重写,在应用中对类型判断的定义和使用有很强的表现。同一对象的多个键返回值必须通过定义对应的接口(interface)来进行类型定义。要不然在 ESLint 时都会报错。
- Vue2 与 Vue3 最大的区别: Vue2 使用Options API而 Vue3 使用的Composition API
介绍 vite
- 💡 极速的开发服务器启动
- ⚡️ 轻量快速的热模块重载(HMR)
- 🛠️ 丰富的功能
- 📦 自带优化的构建
- 🔩 通用的插件接口
- 🔑 完全类型化的 API
- Vite (法语意为 “迅速”,发音 /vit/)是一种全新的前端构建工具,它极大地改善了前端开发体验。
使用 vite 快速创建脚手架
兼容性注意:Vite 需要 Node.js 版本 >= 12.0.0。
- 第一步: 在需要创建项目文件目录下打开 cmd 运行以下命令
# npm 6.x npm init vite@latest my-vue-app --template vue # npm 7+, 需要额外的双横线: npm init vite@latest my-vue-app -- --template vue # yarn yarn create vite my-vue-app --template vue # pnpm pnpm create vite my-vue-app -- --template vue
复制
-
这里采用npm方法安装
-
这里选择vue-ts 然后回车
-
等项目创建完之后,就可以看到结果了cd到文件夹,安装依赖,启动项目
代码风格统一
Eslint支持
# eslint 安装 yarn add eslint --dev # eslint 插件安装 yarn add eslint-plugin-vue --dev yarn add @typescript-eslint/eslint-plugin --dev yarn add eslint-plugin-prettier --dev # typescript parser yarn add @typescript-eslint/parser --dev
复制
- 项目下新建 .eslintrc.js
module.exports = { root: true, env: { browser: true, node: true, es2021: true, }, parser: "vue-eslint-parser", extends: [ "eslint:recommended", "plugin:vue/vue3-recommended", "plugin:@typescript-eslint/recommended", "plugin:prettier/recommended", // eslint-config-prettier 的缩写 "prettier", ], parserOptions: { ecmaVersion: 12, parser: "@typescript-eslint/parser", sourceType: "module", ecmaFeatures: { jsx: true, }, }, // eslint-plugin-vue @typescript-eslint/eslint-plugin eslint-plugin-prettier的缩写 plugins: ["vue", "@typescript-eslint", "prettier"], rules: { "@typescript-eslint/ban-ts-ignore": "off", "@typescript-eslint/no-unused-vars": "off", "@typescript-eslint/explicit-function-return-type": "off", "@typescript-eslint/no-explicit-any": "off", "@typescript-eslint/no-var-requires": "off", "@typescript-eslint/no-empty-function": "off", "@typescript-eslint/no-use-before-define": "off", "@typescript-eslint/ban-ts-comment": "off", "@typescript-eslint/ban-types": "off", "@typescript-eslint/no-non-null-assertion": "off", "@typescript-eslint/explicit-module-boundary-types": "off", "no-var": "error", "prettier/prettier": "error", // 禁止出现console "no-console": "warn", // 禁用debugger "no-debugger": "warn", // 禁止出现重复的 case 标签 "no-duplicate-case": "warn", // 禁止出现空语句块 "no-empty": "warn", // 禁止不必要的括号 "no-extra-parens": "off", // 禁止对 function 声明重新赋值 "no-func-assign": "warn", // 禁止在 return、throw、continue 和 break 语句之后出现不可达代码 "no-unreachable": "warn", // 强制所有控制语句使用一致的括号风格 curly: "warn", // 要求 switch 语句中有 default 分支 "default-case": "warn", // 强制尽可能地使用点号 "dot-notation": "warn", // 要求使用 === 和 !== eqeqeq: "warn", // 禁止 if 语句中 return 语句之后有 else 块 "no-else-return": "warn", // 禁止出现空函数 "no-empty-function": "warn", // 禁用不必要的嵌套块 "no-lone-blocks": "warn", // 禁止使用多个空格 "no-multi-spaces": "warn", // 禁止多次声明同一变量 "no-redeclare": "warn", // 禁止在 return 语句中使用赋值语句 "no-return-assign": "warn", // 禁用不必要的 return await "no-return-await": "warn", // 禁止自我赋值 "no-self-assign": "warn", // 禁止自身比较 "no-self-compare": "warn", // 禁止不必要的 catch 子句 "no-useless-catch": "warn", // 禁止多余的 return 语句 "no-useless-return": "warn", // 禁止变量声明与外层作用域的变量同名 "no-shadow": "off", // 允许delete变量 "no-delete-var": "off", // 强制数组方括号中使用一致的空格 "array-bracket-spacing": "warn", // 强制在代码块中使用一致的大括号风格 "brace-style": "warn", // 强制使用骆驼拼写法命名约定 camelcase: "warn", // 强制使用一致的缩进 indent: "off", // 强制在 JSX 属性中一致地使用双引号或单引号 // 'jsx-quotes': 'warn', // 强制可嵌套的块的最大深度4 "max-depth": "warn", // 强制最大行数 300 // "max-lines": ["warn", { "max": 1200 }], // 强制函数最大代码行数 50 // 'max-lines-per-function': ['warn', { max: 70 }], // 强制函数块最多允许的的语句数量20 "max-statements": ["warn", 100], // 强制回调函数最大嵌套深度 "max-nested-callbacks": ["warn", 3], // 强制函数定义中最多允许的参数数量 "max-params": ["warn", 3], // 强制每一行中所允许的最大语句数量 "max-statements-per-line": ["warn", { max: 1 }], // 要求方法链中每个调用都有一个换行符 "newline-per-chained-call": ["warn", { ignoreChainWithDepth: 3 }], // 禁止 if 作为唯一的语句出现在 else 语句中 "no-lonely-if": "warn", // 禁止空格和 tab 的混合缩进 "no-mixed-spaces-and-tabs": "warn", // 禁止出现多行空行 "no-multiple-empty-lines": "warn", // 禁止出现; semi: ["warn", "never"], // 强制在块之前使用一致的空格 "space-before-blocks": "warn", // 强制在 function的左括号之前使用一致的空格 // 'space-before-function-paren': ['warn', 'never'], // 强制在圆括号内使用一致的空格 "space-in-parens": "warn", // 要求操作符周围有空格 "space-infix-ops": "warn", // 强制在一元操作符前后使用一致的空格 "space-unary-ops": "warn", // 强制在注释中 // 或 /* 使用一致的空格 // "spaced-comment": "warn", // 强制在 switch 的冒号左右有空格 "switch-colon-spacing": "warn", // 强制箭头函数的箭头前后使用一致的空格 "arrow-spacing": "warn", "no-var": "warn", "prefer-const": "warn", "prefer-rest-params": "warn", "no-useless-escape": "warn", "no-irregular-whitespace": "warn", "no-prototype-builtins": "warn", "no-fallthrough": "warn", "no-extra-boolean-cast": "warn", "no-case-declarations": "warn", "no-async-promise-executor": "warn", }, globals: { defineProps: "readonly", defineEmits: "readonly", defineExpose: "readonly", withDefaults: "readonly", }, };
复制
-
项目下新建 .eslintignore
复制# eslint 忽略检查 (根据项目需要自行添加) node_modules dist
prettier 支持
# 安装 prettier yarn add prettier --dev
复制
- 解决 eslint 和 prettier 冲突
# 安装插件 eslint-config-prettier yarn add eslint-config-prettier --dev
复制
- 项目下新建 .prettier.js
module.exports = { tabWidth: 2, jsxSingleQuote: true, jsxBracketSameLine: true, printWidth: 100, singleQuote: true, semi: false, overrides: [ { files: '*.json', options: { printWidth: 200, }, }, ], arrowParens: 'always', }
复制
- 项目下新建 .prettierignore
# 忽略格式化文件 (根据项目需要自行添加) node_modules dist
复制
4 package.json 配置: ```js { "script": { "lint": "eslint src --fix --ext .ts,.tsx,.vue,.js,.jsx", "prettier": "prettier --write ." } } ```
复制
配置 husky + lint-staged
- 使用husky + lint-staged助力团队编码规范,
- 安装插件
npm install husky -dev npm install lint-staged -dev
复制
- husky 是一个为 git 客户端增加 hook 的工具。安装后,它会自动在仓库中的 .git/ 目录下增加相应的钩子;比如 pre-commit 钩子就会在你执行 git commit 的触发。
- 那么我们可以在 pre-commit 中实现一些比如 lint 检查、单元测试、代码美化等操作
- lint-staged,一个仅仅过滤出 Git 代码暂存区文件(被 git add 的文件)的工具;这个很实用,因为我们如果对整个项目的代码做一个检查,可能耗时很长,如果是老项目,要对之前的代码做一个代码规范检查并修改的话,这可能就麻烦了呀,可能导致项目改动很大。
"husky": { "hooks": { "pre-commit": "lint-staged" } }, "lint-staged": { "*.{js,jsx,vue,ts,tsx}": [ "yarn lint", "prettier --write", "git add" ] }
复制
配置文件引用别名 alias
- 直接修改 vite.config.ts 文件配置:
import { defineConfig } from 'vite' import vue from '@vitejs/plugin-vue' import path from 'path' // https://vitejs.dev/config/ export default defineConfig({ plugins: [vue()], resolve: { alias: { '@': path.resolve(__dirname, 'src'), }, }, })
复制
- 修改 tsconfig.json
{ "compilerOptions": { "target": "esnext", "module": "esnext", "moduleResolution": "node", "strict": true, "jsx": "preserve", "sourceMap": true, "resolveJsonModule": true, "esModuleInterop": true, "lib": ["esnext", "dom"], "baseUrl": ".", "paths": { "@/*":["src/*"] } }, "include": ["src/**/*.ts", "src/**/*.d.ts", "src/**/*.tsx", "src/**/*.vue"] }
复制
配置 css 预处理器 scss
-
插件安装
复制yarn add sass-loader --dev yarn add dart-sass --dev yarn add sass --dev -
配置全局scss样式
- 在 src/assets 下新增 style 文件夹,用于存放全局样式文件
- 新建 main.scss, 设置一个用于测试的颜色变量 :
复制$test-color: rgb(0, 4, 255); -
全局配置
复制css:{ preprocessorOptions:{ scss:{ additionalData:'@import "@/assets/style/mian.scss";' } } }, -
组件中使用
```css <style scoped lang="scss"> .title { color: $test-color; } </style> ```
复制
路由安装使用
-
安装路由插件
复制yarn add vue-router@4 -
在 src 文件下新增 router 文件夹 => router.ts 文件,内容如下:
import { createRouter, createWebHistory, RouteRecordRaw } from 'vue-router'; const routes: RouteRecordRaw[] = [ { path: '/', name: 'home', component: () => import('@/views/Home/index.vue'), // 注意这里要带上 文件后缀.vue }, ]; const router = createRouter({ history: createWebHistory(), routes, }); export default router;
复制
- 修改入口文件 mian.ts :
import { createApp } from 'vue' import App from './App.vue' import router from './router/index' const app = createApp(App) app.use(router) app.mount('#app')
复制
- 路由文档使用说明
复制vue-router: https://next.router.vuejs.org/zh/guide/
状态管理 pinia
-
由于 vuex 4 对 typescript 的支持让人感到难过,所以状态管理弃用了 vuex 而采取了 pinia. pinia 的作者是 Vue 核心团队成员
-
安装 pinia
复制yarn add pinia@next -
main.ts 中增加
复制import { createPinia } from "pinia" # 创建根存储库并将其传递给应用程序 app.use(createPinia()) -
在 src 文件夹下新增 store 文件夹,接在在 store 中新增 main.ts
复制import { defineStore } from 'pinia' export const useMainStore = defineStore({ id: 'mian', state: () =>({ name: '群主' }) }) -
组建中获取 store :
<template> <div>{{mainStore.name}}</div> </template> <script setup lang="ts"> import { useMainStore } from "@/store/mian" const mainStore = useMainStore() </script>
复制
- getters 用法介绍
- Pinia 中的 getter 与 Vuex 中的 getter 、组件中的计算属性具有相同的功能
import { defineStore } from 'pinia' export const useMainStore = defineStore({ id: 'mian', state: () => ({ name: '群主', }), getters: { nameLength: (state) => state.name.length, } })
复制
- 组件中使用
<template> <div>用户名:{{ mainStore.name }}<br />长度:{{ mainStore.nameLength }}</div> <hr/> <button @click="updateName">修改store中的name</button> </template> <script setup lang="ts"> import { useMainStore } from '@/store/mian' const mainStore = useMainStore() const updateName = ()=>{ // $patch 修改 store 中的数据 mainStore.$patch({ name: '名称被修改了,nameLength也随之改变了' }) } </script>
复制
环境变量配置
-
vite 提供了两种模式:具有开发服务器的开发模式(development)和生产模式(production)
1. 项目根目录新建:.env.development :
复制NODE_ENV=development VITE_APP_WEB_URL= 'https://www.baidu.com' -
项目根目录新建:.env.production :
复制NODE_ENV=production VITE_APP_WEB_URL= 'https://www.baidu.com' -
使用方式
mport.meta.env.VITE_APP_WEB_URL
-
打包区分开发环境和生产环境
复制"build:dev": "vue-tsc --noEmit && vite build --mode development", "build:pro": "vue-tsc --noEmit && vite build --mode production", -
通过以上的流程,我们就可以搭建一个企业级专业的脚手架模板