网易首页 > 网易号 > 正文 申请入驻

web前端培训Vite2 + Vue3 + TypeScript + Pinia 搭建开发

0
分享至

Vue2 与 Vue3 的区别

Vue3由于完全由TS进行重写,在应用中对类型判断的定义和使用有很强的表现。同一对象的多个键返回值必须通过定义对应的接口(interface)来进行类型定义。要不然在 ESLint 时都会报错。

vue2 的双向数据绑定是利用 ES5 的一个 API Object.definePropert()对数据进行劫持 结合 发布订阅模式的方式来实现的。Vue3 中使用了 es6ProxyAPI 对数据代理。

Vue3支持碎片(Fragments)

Vue2 与 Vue3 最大的区别: Vue2 使用Options API而 Vue3 使用的Composition API

生命周期钩子变化:

Vue2 ~~~~~~~~~~~ vue3

beforeCreate -> setup()

created -> setup()

beforeMount -> onBeforeMount

mounted -> onMounted

beforeUpdate -> onBeforeUpdate

updated -> onUpdated

beforeDestroy -> onBeforeUnmount

destroyed -> onUnmounted

activated -> onActivated

deactivated -> onDeactivated

介绍 vite

Vite:下一代前端开发与构建工具

  • 极速的开发服务器启动
  • 轻量快速的热模块重载(HMR)
  • 丰富的功能
  • 自带优化的构建
  • 通用的插件接口
  • 完全类型化的 API

Vite (法语意为 “迅速”,发音 /vit/)是一种全新的前端构建工具,它极大地改善了前端开发体验。

它主要由两部分组成:

  • 一个开发服务器,它基于 原生 ES 模块 提供了 丰富的内建功能,如速度快到惊人的 模块热更新(HMR)。
  • 一套构建指令,它使用 Rollup 打包你的代码,并且它是预配置的,可以输出用于生产环境的优化过的静态资源。
  • Vite 意在提供开箱即用的配置,同时它的 插件 API 和 JavaScript API 带来了高度的可扩展性,并有完整的类型支持。

使用 vite 快速创建脚手架

兼容性注意:Vite 需要 Node.js 版本 >= 12.0.0。

  1. 第一步: 在需要创建项目文件目录下打开 cmd 运行以下命令

# npm 6.x

npm init @vitejs/app vite_vue3_ts --template

# npm 7+, 需要额外的双横线:

npm init @vitejs/app vite_vue3_ts -- --template

# yarn

yarn create @vitejs/app vite_vue3_ts --template

这里我采用 yarn 来安装

  1. 第二步: 选择 vue回车 => vue-ts回车

  1. 第三步: cd 到项目文件夹,安装依赖,启动项目

# 进入项目文件夹

cd vite_vue3_ts

# 安装依赖

yarn

# 启动

yarn dev

约束代码风格

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

注意: 如果 eslint 安装报错:

可以尝试运行以下命令:

yarn config set ignore-engines true

运行成功后再次执行 eslint 安装命令

项目下新建 .eslintrc.js

配置 eslint 校验规则:

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 中的样式规范和 prettier 中样式规范的冲突,【关注尚硅谷,轻松学IT】以 prettier 的样式规范为准,使 ESLint 中的样式规范自动失效

# 安装插件 eslint-config-prettier

yarn add eslint-config-prettier --dev

项目下新建 .prettier.js

配置 prettier 格式化规则:

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

package.json 配置:

{

"script": {

"lint": "eslint src --fix --ext .ts,.tsx,.vue,.js,.jsx",

"prettier": "prettier --write ."

}

}

上面配置完成后,可以运行以下命令测试下代码检查个格式化效果:

# eslint 检查

yarn lint

# prettier 自动格式化

yarn prettier

配置 husky + lint-staged

使用husky + lint-staged助力团队编码规范, husky&lint-staged 安装推荐使用 mrm, 它将根据 package.json 依赖项中的代码质量工具来安装和配置 husky 和 lint-staged,因此请确保在此之前安装并配置所有代码质量工具,如 Prettier 和 ESlint

首先安装 mrm

npm i mrm -D --registry=https://registry.npm.taobao.org

husky 是一个为 git 客户端增加 hook 的工具。安装后,它会自动在仓库中的 .git/ 目录下增加相应的钩子;比如 pre-commit 钩子就会在你执行 git commit 的触发。

那么我们可以在 pre-commit 中实现一些比如 lint 检查单元测试代码美化等操作。当然,pre-commit 阶段执行的命令当然要保证其速度不要太慢,每次 commit 都等很久也不是什么好的体验。

lint-staged,一个仅仅过滤出 Git 代码暂存区文件(被 git add 的文件)的工具;这个很实用,因为我们如果对整个项目的代码做一个检查,可能耗时很长,如果是老项目,要对之前的代码做一个代码规范检查并修改的话,这可能就麻烦了呀,可能导致项目改动很大。

所以这个 lint-staged,对团队项目和开源项目来说,是一个很好的工具,它是对个人要提交的代码的一个规范和约束

安装 lint-staged

mrm 安装 lint-staged 会自动把 husky 一起安装下来

npx mrm lint-staged

安装成功后会发现 package.json 中多了一下几个配置:

因为我们要结合 prettier 代码格式化,所有修改一下配置:

"husky": {

"hooks": {

"pre-commit": "lint-staged"

}

},

"lint-staged": {

"*.{js,jsx,vue,ts,tsx}": [

"yarn lint",

"prettier --write",

"git add"

]

}

好了,到这里代码格式化配置基本大功告成了!!!

可以修改部分代码尝试 git commit ,你会发现代码将自动格式化:

提交前的代码(发现编辑器爆红了):

执行 commit 操作,控制台可以看到走了哪些流程:

commit 后的代码,是不是已经被格式化了

配置文件引用别名 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

虽然 vite 原生支持 less/sass/scss/stylus,但是你必须手动安装他们的预处理器依赖

安装

yarn ass sass-loader --dev

yarn add dart-sass --dev

yarn add sass --dev

配置全局 scss 样式文件

src/assets 下新增 style 文件夹,用于存放全局样式文件

新建 main.scss, 设置一个用于测试的颜色变量 :

$test-color: red;

如何将这个全局样式文件全局注入到项目中呢?配置 Vite 即可:

css:{

preprocessorOptions:{

scss:{

additionalData:'@import "@/assets/style/mian.scss";'

}

}

},

组件中使用

不需要任何引入可以直接使用全局scss定义的变量

.test{

color: $test-color;

}

路由

# 安装路由

yarn add vue-router@4

src 文件下新增 router 文件夹 => router.ts 文件,内容如下:

import { createRouter, createWebHistory, RouteRecordRaw } from 'vue-router'

const routes: RouteRecordRaw[] = [

{

path: '/',

name: 'Login',

component: () => import('@/pages/login/Login.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-router4.x 支持 typescript,配置路由的类型是 RouteRecordRaw,这里 meta 可以让我们有更多的发挥空间,这里提供一些参考:

  • title:string; 页面标题,通常必选。
  • icon?:string; 图标,一般配合菜单使用。
  • auth?:boolean; 是否需要登录权限。
  • ignoreAuth?:boolean; 是否忽略权限。
  • roles?:RoleEnum[]; 可以访问的角色
  • keepAlive?:boolean; 是否开启页面缓存
  • hideMenu?:boolean; 有些路由我们并不想在菜单中显示,比如某些编辑页面。
  • order?:number; 菜单排序。
  • frameUrl?:string; 嵌套外链。

这里只提供一些思路,每个项目涉及到的业务都会存在些差异,这里就不作详细讲解了,根据自己业务需求做配置即可。

统一请求封装

使用过 vue2.x 的同学应该对 axios 很熟悉了,这里我们直接使用 axios 做封装:

# 安装 axios

yarn add axios

# 安装 nprogress 用于请求 loading

# 也可以根据项目需求自定义其它 loading

yarn add nprogress

# 类型声明,或者添加一个包含 `declare module 'nprogress'

yarn add @types/nprogress --dev

实际使用中可以根据项目修改,比如RESTful api中可以自行添加putdelete请求,ResType也可以根据后端的通用返回值动态的去修改

新增 service 文件夹,service 下新增 http.ts 文件以及 api 文件夹:

http.ts : 用于axios封装

//http.ts

import axios, { AxiosRequestConfig } from 'axios'

import NProgress from 'nprogress'

// 设置请求头和请求路径

axios.defaults.baseURL = '/api'

axios.defaults.timeout = 10000

axios.defaults.headers.post['Content-Type'] = 'application/json;charset=UTF-8'

axios.interceptors.request.use(

(config): AxiosRequestConfig

=> {

const token = window.sessionStorage.getItem('token')

if (token) {

//@ts-ignore

config.headers.token = token

}

return config

},

(error) => {

return error

}

)

// 响应拦截

axios.interceptors.response.use((res) => {

if (res.data.code === 111) {

sessionStorage.setItem('token', '')

// token过期操作

}

return res

})

interface ResType

{

code: number

data?: T

msg: string

err?: string

}

interface Http {

get

(url: string, params?: unknown): Promise

>

post

(url: string, params?: unknown): Promise

>

upload

(url: string, params: unknown): Promise

>

download(url: string): void

}

const http: Http = {

get(url, params) {

return new Promise((resolve, reject) => {

NProgress.start()

axios

.get(url, { params })

.then((res) => {

NProgress.done()

resolve(res.data)

})

.catch((err) => {

NProgress.done()

reject(err.data)

})

})

},

post(url, params) {

return new Promise((resolve, reject) => {

NProgress.start()

axios

.post(url, JSON.stringify(params))

.then((res) => {

NProgress.done()

resolve(res.data)

})

.catch((err) => {

NProgress.done()

reject(err.data)

})

})

},

upload(url, file) {

return new Promise((resolve, reject) => {

NProgress.start()

axios

.post(url, file, {

headers: { 'Content-Type': 'multipart/form-data' },

})

.then((res) => {

NProgress.done()

resolve(res.data)

})

.catch((err) => {

NProgress.done()

reject(err.data)

})

})

},

download(url) {

const iframe = document.createElement('iframe')

iframe.style.display = 'none'

iframe.src = url

iframe.onload = function () {

document.body.removeChild(iframe)

}

document.body.appendChild(iframe)

},

}

export default http

api : 项目中接口做统一管理,按照模块来划分

api 文件下新增 login 文件夹,用于存放登录模块的请求接口,login 文件夹下分别新增 login.ts types.ts :

login.ts:

import http from '@/service/http'

import * as T from './types'

const loginApi: T.ILoginApi = {

login(params){

return http.post('/login', params)

}

}

export default loginApi

types.ts:

export interface ILoginParams {

userName: string

passWord: string | number

}

export interface ILoginApi {

login: (params: ILoginParams)=> Promise

}

至此,一个简单地请求封装完成了!!!!

除了自己手动封装 axios ,这里还推荐一个 vue3 的请求库: VueRequest,非常好用,下面来看看 VueRequest有哪些比较好用的功能吧!!!

  • 所有数据都具有响应式
  • 轮询请求
  • 自动处理错误重试
  • 内置请求缓存
  • 节流请求与防抖请求
  • 聚焦页面时自动重新请求
  • 强大的分页扩展以及加载更多扩展
  • 完全使用 Typescript 编写,具有强大的类型提示
  • 兼容 Vite
  • 轻量化
  • 开箱即用

状态管理 pinia

由于 vuex 4 对 typescript 的支持让人感到难过,【关注尚硅谷,轻松学IT】所以状态管理弃用了 vuex 而采取了 pinia. pinia 的作者是 Vue 核心团队成员

尤大好像说 pinia 可能会代替 vuex,所以请放心使用。

安装 pinia

Pinia 与 Vuex 的区别:

  • id 是必要的,它将所使用 store 连接到 devtools。
  • 创建方式:new Vuex.Store(...)(vuex3),createStore(...)(vuex4)。
  • 对比于 vuex3 ,state 现在是一个函数返回对象
  • 没有 mutations,不用担心,state 的变化依然记录在 devtools 中。

# 安装

yarn add pinia@next

main.ts 中增加

# 引入

import { createPinia } from "pinia"

# 创建根存储库并将其传递给应用程序

app.use(createPinia())

src 文件夹下新增 store 文件夹,接在在 store 中新增 main.ts

创建store, mian.ts :

import { defineStore } from 'pinia'

export const useMainStore = defineStore({

id: 'mian',

state: () =>({

name: '超级管理员'

})

})

组建中获取 store :

import { useMainStore } from "@/store/mian"

const mainStore = useMainStore()

getters 用法介绍

Pinia 中的 getter 与 Vuex 中的 getter 、组件中的计算属性具有相同的功能

store => mian.ts

import { defineStore } from 'pinia'

export const useMainStore = defineStore({

id: 'mian',

state: () => ({

name: '超级管理员',

}),

// getters

getters: {

nameLength: (state) => state.name.length,

}

})

组件中使用:

import { useMainStore } from '@/store/mian'

const mainStore = useMainStore()

const updateName = ()=>{

// $patch 修改 store 中的数据

mainStore.$patch({

name: '名称被修改了,nameLength也随之改变了'

})

}

actions

这里与 Vuex 有极大的不同,Pinia 仅提供了一种方法来定义如何更改状态的规则,放弃 mutations 只依靠 Actions,这是一项重大的改变。

PiniaActions 更加的灵活:

  • 可以通过组件或其他 action 调用
  • 可以从其他 storeaction 中调用
  • 直接在 store 实例上调用
  • 支持同步异步
  • 有任意数量的参数
  • 可以包含有关如何更改状态的逻辑(也就是 vuex 的 mutations 的作用)
  • 可以 $patch 方法直接更改状态属性

import { defineStore } from 'pinia'

export const useMainStore = defineStore({

id: 'mian',

state: () => ({

name: '超级管理员',

}),

getters: {

nameLength: (state) => state.name.length,

},

actions: {

async insertPost(data:string){

// 可以做异步

// await doAjaxRequest(data);

this.name = data;

}

},

})

环境变量配置

vite 提供了两种模式:具有开发服务器的开发模式(development)和生产模式(production)

项目根目录新建:.env.development :

NODE_ENV=development

VITE_APP_WEB_URL= 'YOUR WEB URL'

项目根目录新建:.env.production :

NODE_ENV=production

VITE_APP_WEB_URL= 'YOUR WEB URL'

组件中使用:

console.log(import.meta.env.VITE_APP_WEB_URL)

配置 package.json:

打包区分开发环境和生产环境

"build:dev": "vue-tsc --noEmit && vite build --mode development",

"build:pro": "vue-tsc --noEmit && vite build --mode production",

使用组件库 Naive UI

组件库选择,这里我们选择 Naive UI 至于为什么选择它?我可以直接说尤大大推荐的吗?

  • 官方介绍:
  • 一个 Vue 3 组件库
  • 比较完整,主题可调,使用 TypeScript,不算太慢
  • 有点意思

介绍还是比较谦虚的,既然尤大推荐,肯定有它的优势了!!!

安装 Naive UI

# 安装 组件库

yarn add naive-ui

# 安装 字体

yarn add vfonts

如何使用

import { NButton } from "naive-ui"

naive-ui

全局配置 Config Provider

全局化配置设置内部组件的主题、语言和组件卸载于其他位置的 DOM 的类名。

组件库选择上不做任何强制,根据自己的项目需要选择合适的组件库即可

Vite 常用基础配置

基础配置

运行 代理打包 配置

server: {

host: '0.0.0.0',

port: 3000,

open: true,

https: false,

proxy: {}

},

生产环境去除 console debugger

build:{

...

terserOptions: {

compress: {

drop_console: true,

drop_debugger: true

}

}

}

生产环境生成 .gz 文件

开启 gzip 可以极大的压缩静态资源,对页面加载的速度起到了显著的作用。

使用 vite-plugin-compression 可以 gzipbrotli 的方式来压缩资源,这一步需要服务器端的配合,vite 只能帮你打包出 .gz 文件。此插件使用简单,www.atguigu.com 你甚至无需配置参数,引入即可。

# 安装

yarn add --dev vite-plugin-compression

plugins 中添加:

import viteCompression from 'vite-plugin-compression'

// gzip压缩 生产环境生成 .gz 文件

viteCompression({

verbose: true,

disable: false,

threshold: 10240,

algorithm: 'gzip',

ext: '.gz',

}),

最终 vite.config.ts

import { defineConfig } from 'vite'

import vue from '@vitejs/plugin-vue'

import path from 'path'

//@ts-ignore

import viteCompression from 'vite-plugin-compression'

// https://vitejs.dev/config/

export default defineConfig({

base: './', //打包路径

plugins: [

vue(),

// gzip压缩 生产环境生成 .gz 文件

viteCompression({

verbose: true,

disable: false,

threshold: 10240,

algorithm: 'gzip',

ext: '.gz',

}),

],

// 配置别名

resolve: {

alias: {

'@': path.resolve(__dirname, 'src'),

},

},

css:{

preprocessorOptions:{

scss:{

additionalData:'@import "@/assets/style/mian.scss";'

}

}

},

//启动服务配置

server: {

host: '0.0.0.0',

port: 8000,

open: true,

https: false,

proxy: {}

},

// 生产环境打包配置

//去除 console debugger

build: {

terserOptions: {

compress: {

drop_console: true,

drop_debugger: true,

},

},

},

})

常用插件

  • @vitejs/plugin-vue 提供 Vue 3 单文件组件支持
  • @vitejs/plugin-vue-jsx 提供 Vue 3 JSX 支持(通过 专用的 Babel 转换插件)
  • @vitejs/plugin-legacy 为打包后的文件提供传统浏览器兼容性支持
  • unplugin-vue-components 组件的按需自动导入
  • vite-plugin-compression 使用 gzip 或者 brotli 来压缩资源
  • .....

非常推荐使用的 hooks 库

因为vue3.x和react hooks真的很像,所以就称为 hooks

看到这个库的第一眼,让我立马想到了 react 的 ahooks

VueUse 是一个基于 Composition API 的实用函数集合。通俗的来说,这就是一个工具函数包,它可以帮助你快速实现一些常见的功能,免得你自己去写,解决重复的工作内容。以及进行了基于 Composition API 的封装。让你在 vue3 中更加得心应手

文章转载来源于程序员的那些事

特别声明:以上内容(如有图片或视频亦包括在内)为自媒体平台“网易号”用户上传并发布,本平台仅提供信息存储服务。

Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.

相关推荐
热点推荐
刚访问中国后就捅刀子,中方非常不悦:“立即取消”!

刚访问中国后就捅刀子,中方非常不悦:“立即取消”!

占豪
2024-06-15 03:31:31
20-1!欧洲杯大屠杀,德国倒退10年

20-1!欧洲杯大屠杀,德国倒退10年

足球大号
2024-06-15 13:35:30
刘和平:开出俄乌停火谈判的条件后, 普京手中还剩几张牌?

刘和平:开出俄乌停火谈判的条件后, 普京手中还剩几张牌?

直新闻
2024-06-15 23:13:39
现场|京港、沪港高铁动卧首发列车抵港,乘客“打100分”

现场|京港、沪港高铁动卧首发列车抵港,乘客“打100分”

澎湃新闻
2024-06-16 10:36:35
G7发布联合声明,不许中国援俄,不许武力收台,也不许反制菲律宾

G7发布联合声明,不许中国援俄,不许武力收台,也不许反制菲律宾

贺文萍
2024-06-15 16:53:41
格兰德:克罗斯当时想要与格策持平的薪水,他如今是最成功的球员

格兰德:克罗斯当时想要与格策持平的薪水,他如今是最成功的球员

直播吧
2024-06-16 09:04:20
16岁的暑假班!亚马尔生吃格瓦迪奥尔、1v4、带作业到德国做✍️

16岁的暑假班!亚马尔生吃格瓦迪奥尔、1v4、带作业到德国做✍️

直播吧
2024-06-16 10:40:12
大陆不再沉默,给黄仁勋上了一课,选在美收紧对华AI芯片出口之际

大陆不再沉默,给黄仁勋上了一课,选在美收紧对华AI芯片出口之际

陈菲副教授
2024-06-15 18:20:03
东莞茶山教育管理中心主任文辉被查,已有同僚落马

东莞茶山教育管理中心主任文辉被查,已有同僚落马

南方都市报
2024-06-16 10:56:09
湖南省辰溪县中医医院原党支部书记、院长傅胜义接受纪律审查和监察调查

湖南省辰溪县中医医院原党支部书记、院长傅胜义接受纪律审查和监察调查

鲁中晨报
2024-06-16 10:59:05
乌克兰和平峰会、美俄核潜艇“对视”,都是俄乌冲突背景音乐!

乌克兰和平峰会、美俄核潜艇“对视”,都是俄乌冲突背景音乐!

新民周刊
2024-06-16 09:09:58
乌情报总局局长:俄最新型S-500防空系统部分部件已运抵克里米亚

乌情报总局局长:俄最新型S-500防空系统部分部件已运抵克里米亚

红星新闻
2024-06-15 20:16:15
A股超1600家通过转融通出借股份做空自己,尤其这几家尽量远离!

A股超1600家通过转融通出借股份做空自己,尤其这几家尽量远离!

股海风云大作手
2024-06-16 09:19:07
一针69.7万,医保谈判到3万!可澳洲184块,为何却说中国价最低?

一针69.7万,医保谈判到3万!可澳洲184块,为何却说中国价最低?

风起云间
2024-06-14 21:44:22
俄罗斯金融体系面临崩盘,惨烈!

俄罗斯金融体系面临崩盘,惨烈!

户外阿崭
2024-06-15 23:31:50
中俄联合开发黑瞎子岛,当年黑瞎子岛是怎样被俄方占领的?

中俄联合开发黑瞎子岛,当年黑瞎子岛是怎样被俄方占领的?

浩然史观
2024-06-15 16:55:02
倒查30年后补税是个危险信号

倒查30年后补税是个危险信号

深度财线
2024-06-15 22:03:47
消失173天后,凯特王妃终于现身!但昨天发的近照图破绽百出,怎么回事呀?

消失173天后,凯特王妃终于现身!但昨天发的近照图破绽百出,怎么回事呀?

北美省钱快报
2024-06-16 00:17:56
G7峰会:喧嚣过后,困局依旧

G7峰会:喧嚣过后,困局依旧

齐鲁壹点
2024-06-16 07:43:09
欧洲杯很搞笑!镜头告诉你:瑞士前锋射门前掉下的异物是啥?

欧洲杯很搞笑!镜头告诉你:瑞士前锋射门前掉下的异物是啥?

足球大腕
2024-06-16 00:04:15
2024-06-16 11:44:49
IT爱好者小尚
IT爱好者小尚
分享IT教育类信息
630文章数 55关注度
往期回顾 全部

科技要闻

iPhone 16会杀死大模型APP吗?

头条要闻

法国股市暴跌引发恐慌 马克龙:法国处于非常严峻时刻

头条要闻

法国股市暴跌引发恐慌 马克龙:法国处于非常严峻时刻

体育要闻

没人永远年轻 但青春如此无敌还是离谱了些

娱乐要闻

上影节红毯:倪妮好松弛,娜扎吸睛

财经要闻

打断妻子多根肋骨 上市公司创始人被公诉

汽车要闻

售17.68万-21.68万元 极狐阿尔法S5正式上市

态度原创

家居
手机
亲子
艺术
公开课

家居要闻

空谷来音 朴素留白的侘寂之美

手机要闻

哥伦比亚手机市场分析:三星第一不保,小米排名第二

亲子要闻

孩子吃饭时习惯让别人盛饭,外婆是这样做的...

艺术要闻

穿越时空的艺术:《马可·波罗》AI沉浸影片探索人类文明

公开课

近视只是视力差?小心并发症

无障碍浏览 进入关怀版