1. 创建项目
这里推荐使用Vue脚手架创建项目模板
- 创建vue3+vite版本模板
npm init vue
- 创建vue2+vite版本模板
npm init vue@2
创建过程可以选择需要的功能:
创建完后目录:
2.代码检测和格式化插件
目前我比较喜欢的是选择eslint+stylelint
进行代码的检测和格式化,可以选择自己喜欢的方式,比如eslint+prettier
都是可以的。
ESLint
1.安装 eslint
-D 表示安装到 devDependencies, -D 是--save-dev 的缩写
不写默认安装到 dependencies
推荐使用pnpm进行安装
pnpm install eslint -D
npm install eslint -D
2.VSCode安装 ESLint 插件
3.自动生成 Eslint
配置文件
npx eslint --init
没有 npx 可以先全局安装,在 npm 版本为 5.2 之后默认会给你安装 npx
npm install -g npx
根据命令提示,完成操作:
How would you like to use ESLint?
你想如何使用 eslint?
- To check syntax only(
只检查语法检查语法并发现问题
) - To check syntax and find problems(
检查语法并发现问题
)
选择 To check syntax, find problems, and enforce code style(检查语法,发现问题,并强制代码样式
)
What type of modules does your project use?
您的项目使用什么类型的模块?
选择 JavaScript modules (import/export) 。
Which framework does your project use?
你的项目使用什么框架?
React Vue.js None of these
Does your project use TypeScript?
你的项目中使用 Typescript 吗?
Yes/No
Where does your code run?
你的代码运行在??
Browser(浏览器
)Node(Node
)
选择Browser
How would you like to define a style for your project?
你想给你的项目定义什么风格?
选择Use a popular style guide(使用一个流行的风格指南
)Answer questions about your style(回答你关于风格的问题
)Inspect your JavaScript file(检查你的 javascript 文件
)
Which style guide do you want to follow?
你想遵循是么样的风格指南?
Airbnb: github.com/airbnb/java…
Standard: github.com/standard/st…
Google: github.com/google/esli…
上面四种风格都是社区流行的 javascript 风格指南,选择Standard
What format do you want your config file to be in?
你希望配置文件的格式是什么?
JavaScript/YAML/JSON
选择javascript
eslint 根据上面我们选择的配置,来告诉我们安装哪些 npm 包,选择 Yes
即可。
4.个人常用配置
pnpm i eslint eslint-config-standard eslint-plugin-import eslint-plugin-n eslint-plugin-promise eslint-plugin-vue -D
.eslintrc.js
文件
module.exports = {
env: {
browser: true,
es2021: true
},
extends: [
'plugin:vue/vue3-strongly-recommended',
'standard'
],
parserOptions: {
ecmaVersion: 'latest',
sourceType: 'module'
},
plugins: [
'vue'
],
rules: {
'vue/multi-word-component-names': 'off',
'import/no-absolute-path': 'off',
'vue/require-default-prop': 'off',
'vue/max-attributes-per-line': ['error', {
singleline: {
max: 3
},
multiline: {
max: 1
}
}]
}
}
Stylelint
使用stylelint对 css/scss进行代码格式化
1.安装stylelint
pnpm i stylelint stylelint-config-html stylelint-config-recommended-scss stylelint-config-recommended-vue stylelint-config-standard stylelint-config-standard-scss stylelint-order postcss postcss-html -D
2.vscode安装Stylelint插件
在 vscode 的 settings.json 中配置stylelint
"stylelint.enable": true,
"editor.codeActionsOnSave": {
"source.fixAll.stylelint": true
},
"stylelint.validate": ["css", "less", "postcss", "scss", "vue", "sass"]
3.个人常用配置
配置 .stylelintrc.js
文件
module.exports = {
extends: [
'stylelint-config-standard',
'stylelint-config-html/vue',
'stylelint-config-standard-scss',
'stylelint-config-recommended-vue/scss',
],
plugins: ['stylelint-order'],
rules: {
'no-descending-specificity': null,
'function-url-quotes': 'always',
'string-quotes': 'double',
indentation: 2,
'unit-case': null,
'color-hex-case': 'lower',
'color-hex-length': 'long',
'rule-empty-line-before': 'never',
'font-family-no-missing-generic-family-keyword': null,
'block-opening-brace-space-before': 'always',
'property-no-unknown': null,
'no-empty-source': null,
'selector-pseudo-class-no-unknown': [
true,
{
ignorePseudoClasses: ['deep'],
},
],
'order/properties-order': [
'position',
'top',
'right',
'bottom',
'left',
'z-index',
'display',
'justify-content',
'align-items',
'float',
'clear',
'overflow',
'overflow-x',
'overflow-y',
'margin',
'margin-top',
'margin-right',
'margin-bottom',
'margin-left',
'padding',
'padding-top',
'padding-right',
'padding-bottom',
'padding-left',
'width',
'min-width',
'max-width',
'height',
'min-height',
'max-height',
'font-size',
'font-family',
'font-weight',
'border',
'border-style',
'border-width',
'border-color',
'border-top',
'border-top-style',
'border-top-width',
'border-top-color',
'border-right',
'border-right-style',
'border-right-width',
'border-right-color',
'border-bottom',
'border-bottom-style',
'border-bottom-width',
'border-bottom-color',
'border-left',
'border-left-style',
'border-left-width',
'border-left-color',
'border-radius',
'text-align',
'text-justify',
'text-indent',
'text-overflow',
'text-decoration',
'white-space',
'color',
'background',
'background-position',
'background-repeat',
'background-size',
'background-color',
'background-clip',
'opacity',
'filter',
'list-style',
'outline',
'visibility',
'box-shadow',
'text-shadow',
'resize',
'transition',
],
},
}
Prettier
Prettier 是一款强大的代码格式化工具,支持 JavaScript、TypeScript、CSS、SCSS、Less、JSX、Angular、Vue、GraphQL、JSON、Markdown 等语言
1.安装 prettier
npm install prettier -D
2.配置 .prettierrc.js
module.exports = {
printWidth: 160, // 单行输出(不折行)的(最大)长度
tabWidth: 2, // 每个缩进级别的空格数
semi: false, // 是否在语句末尾打印分号
singleQuote: true, // 是否使用单引号
quoteProps: 'as-needed', // 仅在需要时在对象属性周围添加引号
bracketSpacing: true, // 是否在对象属性添加空格
htmlWhitespaceSensitivity: 'ignore', // 指定 HTML 文件的全局空白区域敏感度, "ignore" - 空格被认为是不敏感的
trailingComma: 'none', // 去除对象最末尾元素跟随的逗号
useTabs: false, // 缩进不使用tab,使用空格
jsxSingleQuote: false, // jsx 不使用单引号,而使用双引号
arrowParens: 'avoid', // 箭头函数,只有一个参数的时候,也需要括号 always总是 avoid:省略括号
rangeStart: 0, // 每个文件格式化的范围是文件的全部内容
proseWrap: 'always', // 当超出print width(上面有这个参数)时就折行
endOfLine: 'lf' // 换行符使用 lf
}
3.创建 .prettierignore
忽略文件
/dist/*
.local
.output.js
/node_modules/**
**/*.svg
**/*.sh
/public/*
4.VSCode安装prettier插件
5.测试 prettier 是否生效
- 测试一:在代码中保存代码;
- 测试二:配置一次性修改的命令;
在 package.json 的 scripts
对象中添加 prettier
:执行 npm run prettier
可以对全部文件格式化
"scripts": {
"prettier": "prettier --write ."
}
解决 eslint
和 prettier
冲突
安装插件 eslint-plugin-prettier
和 eslint-config-prettier
npm i eslint-plugin-prettier eslint-config-prettier -D
5.在 .eslintrc.js
中添加 prettier
即可,代码第 9 行
module.exports = {
env: {
browser: true,
es2021: true
},
extends: [
'plugin:vue/vue3-essential',
'airbnb-base',
'plugin:prettier/recommended' // 添加 prettier 插件
],
parserOptions: {
ecmaVersion: 'latest',
sourceType: 'module'
},
plugins: ['vue'],
rules: {}
}
注意:
重启 vscode 后 eslint 的规则才会按照 prettier 的配置规则生效,不重启还是原先的规则。
配置 vscode 的 eslint,在设置中找到 ESLint,把这个勾打上
在 package.json
中添加格式化脚本,之后只需要执行 npm run lint
即可全局自动格式化所有需要格式化的文件
"scripts": {
"dev": "vite",
"build": "vue-tsc --noEmit && vite build",
...
"lint": "eslint ./src/**/*.{js,jsx,vue,ts,tsx} --fix"
},
3. 代码规范
这个看个人需要,团队项目有这个会规范很多
1.集成 editorconfig 配置
EditorConfig 有助于为不同 IDE 编辑器上处理同一项目的多个开发人员维护一致的编码风格。
# http://editorconfig.org
root = true
[*] # 表示所有文件适用
charset = utf-8 # 设置文件字符集为 utf-8
indent_style = space # 缩进风格(tab | space)
indent_size = 2 # 缩进大小
end_of_line = lf # 控制换行类型(lf | cr | crlf)
trim_trailing_whitespace = true # 去除行首的任意空白字符
insert_final_newline = true # 始终在文件末尾插入一个新行
[*.md] # 表示仅 md 文件适用以下规则
max_line_length = off
trim_trailing_whitespace = false
VSCode 需要安装一个插件:EditorConfig for VS Code
2.git commit 规范
通常我们的 git commit 会按照统一的风格来提交,这样可以快速定位每次提交的内容,方便之后对版本进行控制。
但是如果每次手动来编写这些是比较麻烦的事情,我们可以使用一个 vscode 的工具:
Type | 作用 |
---|---|
init | 项目初始化 |
feat | 新增特性 (feature) |
fix | 修复 Bug(bug fix) |
docs | 修改文档 (documentation) |
style | 代码格式修改(white-space, formatting, missing semi colons, etc) |
refactor | 代码重构(refactor) |
perf | 改善性能(A code change that improves performance) |
test | 测试(when adding missing tests) |
build | 变更项目构建或外部依赖(例如 scopes: webpack、gulp、npm 等) |
ci | 更改持续集成软件的配置文件和 package 中的 scripts 命令,例如 scopes: Travis, Circle 等 |
chore | 变更构建流程或辅助工具(比如更改测试环境) |
revert | 代码回退 |
3.代码提交验证
我们无法避免其他开发者会提交什么代码,所以需要进行统一的 git commit
之前进行代码校验,如果校验不通过则不让提交。
- 安装下面的插件
Plain Text npx mrm@2 lint-staged
该插件做了以下的事情,在 package.json 中增加了三行,创建了 husky 文件夹
在 package.json 中配置规则,该规则表示 commit 之前会先执行上面定义的 eslint 检查,如果不通过则无法提交
"lint-staged": {
"*.{js,jsx,vue,ts,tsx}": [
"npm run lint",
"git add"
]
}
4. 库集成
由于第一步已经选择vue-router
和pinia
,所以已安装了这两个库的可以跳过
1.vue-router
1.安装
@next 表示 vue-router 的最新版本
npm install vue-router@next
2.创建 router 对象
router/index.js
import { createRouter, createWebHashHistory, RouteRecordRaw } from 'vue-router'
const routes: RouteRecordRaw[] = [
{
path: '/',
redirect: '/main'
},
{
path: '/main',
component: () => import('../views/main/main.vue')
},
{
path: '/login',
component: () => import('../views/login/login.vue')
}
]
const router = createRouter({
routes,
history: createWebHashHistory()
})
export default router
3.使用
在main.js
中
import router from './router'
createApp(App).use(router).mount('#app')
在 App.vue 中配置跳转
<template>
<div id="app">
<router-link to="/login">登录</router-link>
<router-link to="/main">首页</router-link>
<router-view></router-view>
</div>
</template>
2.pinia
vue3 对于 vuex 兼容性差一些,可以使用更好用的 pinia
1. 安装
npm install pinia --save
2. 创建 Store
新建 src/store
目录并在其下面创建 index.js
,导出 store
import { createPinia } from 'pinia'
const store = createPinia()
export default store
3. 使用
在 main.js
中引入
import { createApp } from 'vue'
import App from './App.vue'
import store from './store'
const app = createApp(App)
app.use(store)
4. 数据持久化插件
1.安装
pnpm install pinia-plugin-persist
2.注册使用
import { createPinia } from 'pinia'
import piniaPluginPersist from 'pinia-plugin-persist'
const store = createPinia()
store.use(piniaPluginPersist)
数据默认存在 sessionStorage 里,并且会以 store 的 id 作为 key。
export const useUserStore = defineStore({
id: 'user',
state: () => {
return {
name: '张三'
}
},
// 开启数据缓存
persist: {
enabled: true
}
})
3.自定义 key和默认存储位置
persist: {
enabled: true,
strategies: [
{
key: 'my_user',
storage: localStorage,
}
]
}
4.持久化部分 state
默认所有 state 都会进行缓存,你可以通过 paths 指定要持久化的字段,其他的则不会进行持久化。
state: () => {
return {
name: '张三',
age: 18,
gender: '男'
}
},
persist: {
enabled: true,
strategies: [
{
storage: localStorage,
paths: ['name', 'age']
}
]
}
上面我们只持久化 name 和 age,并将其改为 localStorage, 而 gender 不会被持久化,如果其状态发送更改,页面刷新时将会丢失,重新回到初始状态,而 name 和 age 则不会。
5. setup语法
在这种语法中,ref
与 state
对应、computed
与 getters
对应、function
与 actions
对应。
export const useCounterStore = defineStore('counter', () => {
const count = ref(0)
const doubleCount = computed(() => count.value * 2)
function increment() {
count.value++
}
return { count, doubleCount, increment }
})
6. 在setup语法外使用
如果准备在 Vue3 的 Setup 语法外引入 Pinia 的 Store,例如 useCounterStore。
直接 import { useCounterStore } from "@/store/modules/xxxxxx"
是不行的
正确用法:
将这个store导出后引入使用
import store from "@/store"
export const useCounterStore = defineStore('counter', () => {
const count = ref(0)
const doubleCount = computed(() => count.value * 2)
function increment() {
count.value++
}
return { count, doubleCount, increment }
})
/** 在 setup 外使用 */
export function useCounterStoreHook() {
return useCounterStore(store)
}
然后引入
import { useCounterStoreHook } from "@/store/modules/xxxxxx"
即可!
3.vuex
1.安装
npm install vuex@next
2.创建 store 对象
import { createStore } from 'vuex'
const store = createStore({
state() {
return {
name: 'coderwhy'
}
}
})
export default store
3.使用 store
在main.js
中
createApp(App).use(router).use(store).mount('#app')
4. element-plus
Element Plus,一套为开发者、设计师和产品经理准备的基于 Vue 3.0 的桌面端组件库。
1.安装
npm install element-plus --save
2.引入
完整引入
如果你对打包后的文件大小不是很在乎,那么使用完整导入会更方便。
// main.ts
import { createApp } from 'vue'
import ElementPlus from 'element-plus'
import 'element-plus/dist/index.css'
import App from './App.vue'
const app = createApp(App)
app.use(ElementPlus)
app.mount('#app')
按需引入
首先你需要安装 unplugin-vue-components
和 unplugin-auto-import
这两款插件
npm install -D unplugin-vue-components unplugin-auto-import
3.配置
在 vite
中配置 vite.config.js
import { defineConfig } from 'vite'
import AutoImport from 'unplugin-auto-import/vite'
import Components from 'unplugin-vue-components/vite'
import { ElementPlusResolver } from 'unplugin-vue-components/resolvers'
export default {
plugins: [
// ...
AutoImport({
resolvers: [ElementPlusResolver()],
}),
Components({
resolvers: [ElementPlusResolver()],
}),
],
}
在 webpack
中配置 vue.config.js
const AutoImport = require('unplugin-auto-import/webpack')
const Components = require('unplugin-vue-components/webpack')
const { ElementPlusResolver } = require('unplugin-vue-components/resolvers')
module.exports = {
// ...
plugins: [
AutoImport({
resolvers: [ElementPlusResolver()],
}),
Components({
resolvers: [ElementPlusResolver()],
}),
],
}
通过以上步骤即可随用随加载对应组件。
5. axios
1.安装
npm install axios
2.封装
import axios from 'axios'
import QS from 'qs' //用于序列化body内容,后端有配置可以不用这个库
import { ElLoading, ElMessage } from 'element-plus' //用于请求成功与否的弹框提醒和等待
import store from '@/store'
import router from '@/router'
//可以通过下面这个来获取vite中的环境是开发环境还是生产环境
//let { VITE_NORMALURL: normalUrl, MODE } = import.meta.env
//console.log('vite', import.meta.env)
//如果为开发模式
//let baseURL = MODE == 'development' ? String(normalUrl) : String(normalUrl)
let baseURL ='http://localhost:3000/'
const instance = axios.create({
baseURL, //基础url
timeout: 30000, //请求超时时间
})
// 请求拦截器
instance.interceptors.request.use(
(config) => {
/*
*将token放在请求头里就不需要每次都手动添加token。
*即使本地存在token,也有可能token是过期的,所以在响应拦截器中要对返回状态进行判断。
*/
//const token = store.state.token;
//token && (config.headers.Authorization = token);
//如果公司的token是直接放在请求参数里面的,那么可以使用以下的配置
let token = store.state.token
if (token) {
if (config.params) {
config.params.token = token
} else {
config.params = {
token,
}
}
}
return config
},
(error) => {
return Promise.error(error)
}
)
// 响应拦截器
instance.interceptors.response.use(
(response) => {
if (response.status === 200) {
return Promise.resolve(response)
} else {
return Promise.reject(response)
}
},
// 服务器状态码不是200的情况
(error) => {
if (error.response.status) {
switch (error.response.status) {
//无权限,直接回到登录页
case 401:
ElMessage({
message: '登录过期,请重新登录',
type: 'error',
})
// 清除token
store.commit('setUserInfo', { token: '' })
// 跳转登录页面,并将要浏览的页面fullPath传过去,登录成功后跳转需要访问的页面
setTimeout(() => {
router.replace({
path: '/',
query: {
redirect: router.currentRoute.fullPath,
},
})
}, 1000)
break
// 404请求不存在
case 404:
ElMessage({
message: '网络请求不存在',
type: 'error',
})
break
// 其他错误,直接抛出错误提示
default:
ElMessage({
message: error.response.data.message,
type: 'error',
})
}
return Promise.reject(error.response)
}
}
)
/**
* get方法,对应get请求
* @param {String} url [请求的url地址]
* @param {Object} params [请求时携带的参数]
*/
export function get(url, params) {
return new Promise((resolve, reject) => {
instance
.get(url, {
params: params,
})
.then((res) => {
resolve(res.data)
})
.catch((err) => {
reject(err.data)
})
})
}
/**
* post方法,对应post请求
* @param {String} url [请求的url地址]
* @param {Object} params [请求时携带的参数]
*/
export function post(url, params) {
return new Promise((resolve, reject) => {
instance
.post(url, QS.stringify(params))
.then((res) => {
resolve(res.data)
})
.catch((err) => {
reject(err.data)
})
})
}
export { instance }
6. normalize.css
作用:
- 保护有用的浏览器样式而不是去掉他们。
- 为大部分 HTML 元素提供一般化的样式。
- 修复浏览器自身的 bug 并保证各浏览器的一致性。
- 优化 css 可用性。
- 用注释和详细的文档来解释代码。
- Normalize 支持包括手机浏览器在内的超多浏览器,同时对 HTML5 元素、排版、列表、嵌入的内容、表单和表格都进行了一般化。
1.安装
npm install --save normalize.css
2.使用
main.js
中引入
import 'normalize.css'
7. scss
npm i -D sass
8. unocss
1.安装
pnpm i unocss -D
2.配置
创建uno.config.js
文件
import { presetMini, presetAttributify, presetIcons, defineConfig } from 'unocss'
export default defineConfig({
presets: [presetAttributify(), presetMini(), presetIcons()],
rules: [
[
'base',
{
width: '100%',
height: '100%',
display: 'flex',
'flex-direction': 'column'
}
],
[
'ellipsis',
{
overflow: 'hidden',
'text-overflow': 'ellipsis',
'white-space': 'nowrap'
}
],
[/^ellipsis-(\d+)$/, ([, d]) => ({
'word-break': 'break-all',
'text-overflow': 'ellipsis',
display: '-webkit-box',
'-webkit-box-orient': 'vertical',
'-webkit-line-clamp': d,
overflow: 'hidden'
})]
]
})
在vite.config.js
中使用unocss
import { defineConfig, loadEnv } from 'vite'
import vue from '@vitejs/plugin-vue'
import vueJsx from '@vitejs/plugin-vue-jsx' // 引入jsx
import Unocss from 'unocss/vite'
export default defineConfig(({ mode }) => {
const env = loadEnv(mode, process.cwd())
return {
plugins: [
vue(),
vueJsx({
// 配置选项
}),
Unocss()
],
resolve: {
extensions: ['.vue', '.mjs', '.js', '.ts', '.jsx', '.tsx', '.json'],
alias: {
'@': path.join(__dirname, 'src')
}
}
}
})
3.安装vscode unocss 插件
有这种效果即可以正常使用unocss
5. 个人后台模板
这是自己使用vue3+vite+element-plus+unocss搭建的后台管理模板,欢迎体验
github地址:
在线体验: