Vue3 全家桶 + Element Plus + Vite + TypeScript + Eslint 项目配置最佳实践

Vue3 全家桶 + Element Plus + Vite + TypeScript + Eslint 项目配置最佳实践_第1张图片

尤大的 Vue3.0 已经发布有一阵子了,已经很成熟了。

而且 Element Plus + Vite 也出了一段时间了,是时候该上手体验分享一波了。

主要是要熟练一下 Vue3,好准备用 Vue3 重构一下自己的网站项目: blog-vue-typescript ,计划是过年期间会着手重构这个项目,年后会上线。

Vue3 全家桶 + Element Plus + Vite + TypeScript + Eslint 项目配置最佳实践_第2张图片

1. 初化化项目

全局安装 vite-app

npm?i?-g?vite-app

创建项目

yarn?create?vite-app?

#?或者
npm?init?vite-app?

进入项目,安装依赖

cd?

yarn?#?或?npm?i

运行项目

yarn?dev?

打开浏览器 http://localhost:3000 查看

2. 引入TypeScript

加入 ts 依赖

yarn?add?--dev?typescript

在 项目根目录下创建 TypeScript 的配置文件 tsconfig.json

{
??"compilerOptions":?{
????//?允许从没有设置默认导出的模块中默认导入。这并不影响代码的输出,仅为了类型检查。
????"allowSyntheticDefaultImports":?true,
????
????//?解析非相对模块名的基准目录
????"baseUrl":?".",

????"esModuleInterop":?true,

????//?从?tslib?导入辅助工具函数(比如?__extends,?__rest等)
????"importHelpers":?true,

????//?指定生成哪个模块系统代码
????"module":?"esnext",

????//?决定如何处理模块。
????"moduleResolution":?"node",

????//?启用所有严格类型检查选项。
????//?启用?--strict相当于启用?--noImplicitAny,?--noImplicitThis,?--alwaysStrict,?
????//?--strictNullChecks和?--strictFunctionTypes和--strictPropertyInitialization。
????"strict":?true,

????//?生成相应的 .map文件。
????"sourceMap":?true,

????//?忽略所有的声明文件(?*.d.ts)的类型检查。
????"skipLibCheck":?true,

????//?指定ECMAScript目标版本?
????"target":?"esnext",
????
????//?要包含的类型声明文件名列表
????"types":?[

????],

????"isolatedModules":?true,

????//?模块名到基于 baseUrl的路径映射的列表。
????"paths":?{
??????"@/*":?[
????????"src/*"
??????]
????},
????//?编译过程中需要引入的库文件的列表。
????"lib":?[
??????"ESNext",
??????"DOM",
??????"DOM.Iterable",
??????"ScriptHost"
????]
??},
??"include":?[
????"src/**/*.ts",
????"src/**/*.tsx",
????"src/**/*.vue",
????"tests/**/*.ts",
????"tests/**/*.tsx"
??],
??"exclude":?[
????"node_modules"
??]
}

在 src 目录下新加 shim.d.ts 文件

/*?eslint-disable?*/
import?type?{?DefineComponent?}?from?'vue'

declare?module?'*.vue'?{
??const?component:?DefineComponent<{},?{},?any>
??export?default?component
}

把 main.js 修改成 main.ts

在根目录,打开 Index.html


修改为:

3. 引入 eslint

安装 eslint prettier 依赖

@typescript-eslint/parser @typescr ipt-eslint/eslint-plugin 为 eslint 对 typescript 支持。

yarn?add?--dev?eslint?prettier?eslint-config-prettier?eslint-plugin-prettier?eslint-plugin-vue?@typescript-eslint/parser?@typescr?ipt-eslint/eslint-plugin

在根目录下建立 eslint 配置文件:.eslintrc.js

module.exports?=?{
??parser:?'vue-eslint-parser',
??parserOptions:?{
????parser:?'@typescript-eslint/parser',
????ecmaVersion:?2020,
????sourceType:?'module',
????ecmaFeatures:?{
??????jsx:?true
????}
??},
??extends:?[
????'plugin:vue/vue3-recommended',
????'plugin:@typescript-eslint/recommended',
????'prettier/@typescript-eslint',
????'plugin:prettier/recommended'
??],
??rules:?{
????'@typescript-eslint/ban-ts-ignore':?'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',
????'vue/custom-event-name-casing':?'off',
????'no-use-before-define':?'off',
????//?'no-use-before-define':?[
????//???'error',
????//???{
????//?????functions:?false,
????//?????classes:?true,
????//???},
????//?],
????'@typescript-eslint/no-use-before-define':?'off',
????//?'@typescript-eslint/no-use-before-define':?[
????//???'error',
????//???{
????//?????functions:?false,
????//?????classes:?true,
????//???},
????//?],
????'@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',
????'@typescript-eslint/no-unused-vars':?[
??????'error',
??????{
????????argsIgnorePattern:?'^h$',
????????varsIgnorePattern:?'^h$'
??????}
????],
????'no-unused-vars':?[
??????'error',
??????{
????????argsIgnorePattern:?'^h$',
????????varsIgnorePattern:?'^h$'
??????}
????],
????'space-before-function-paren':?'off',
????quotes:?['error',?'single'],
????'comma-dangle':?['error',?'never']
??}
};

建立 prettier.config.js

module.exports?=?{
??printWidth:?100,
??tabWidth:?2,
??useTabs:?false,
??semi:?false,?//?未尾逗号
??vueIndentScriptAndStyle:?true,
??singleQuote:?true,?//?单引号
??quoteProps:?'as-needed',
??bracketSpacing:?true,
??trailingComma:?'none',?//?未尾分号
??jsxBracketSameLine:?false,
??jsxSingleQuote:?false,
??arrowParens:?'always',
??insertPragma:?false,
??requirePragma:?false,
??proseWrap:?'never',
??htmlWhitespaceSensitivity:?'strict',
??endOfLine:?'lf'
}

4. vue-router、vuex

yarn?add?vue-router@next?vuex@next

4.1 vuex

在根目录下创建 store/index.ts

import?{?InjectionKey?}?from?'vue'
import?{?createStore,?Store?}?from?'vuex'

export?interface?State?{
??count:?number
}

export?const?key:?InjectionKey>?=?Symbol()

export?const?store?=?createStore({
??state()?{
????return?{
??????count:?0
????}
??},
??mutations:?{
????increment(state)?{
??????state.count++
????}
??}
})

main.ts 修改

import?{?createApp?}?from?'vue'
import?{?store,?key?}?from?'./store'
import?App?from?'./App'
import?'./index.css'

const?app?=?createApp(App)

app.use(store,?key)

app.mount('#app')

components/HelloWord.vue 修改




4.2 vue-router

在 src 目录下建立 router/index.ts,内容如下:

import?{?createRouter,?createWebHistory,?RouteRecordRaw?}?from?"vue-router";
import?HelloWorld?from?"../components/HelloWorld.vue";

const?routes:?Array?=?[
????{
????????path:?"/",
????????name:?"HelloWorld",
????????component:?HelloWorld,
????},
????{
????????path:?"/about",
????????name:?"About",
????????//?route?level?code-splitting
????????//?this?generates?a?separate?chunk?(about.[hash].js)?for?this?route
????????//?which?is?lazy-loaded?when?the?route?is?visited.
????????component:?()?=>
????????????import(/*?webpackChunkName:?"About"?*/?"../components/About.vue")
????}
];

const?router?=?createRouter({
????history:?createWebHistory(process.env.BASE_URL),
????routes,
});

export?default?router;

再新建一个 components/About.vue 文件,内容如下:




import?{?defineComponent?}?from?'vue'

export?default?defineComponent({
??name:?'About',
??data()?{
????return?{
??????msg:?'Hello?Vue?3.0?+?Vite!'
????}
??},
??setup()?{}
})

再修改 main.ts

import?{?createApp?}?from?'vue'
import?{?store,?key?}?from?'./store'
import?router?from?"./router";
import?App?from?'./App'
import?'./index.css'

const?app?=?createApp(App)

app.use(store,?key)
app.use(router)
app.mount('#app')

再访问 http://localhost:3000/

Vue3 全家桶 + Element Plus + Vite + TypeScript + Eslint 项目配置最佳实践_第3张图片

和 http://localhost:3000/about 即可

Vue3 全家桶 + Element Plus + Vite + TypeScript + Eslint 项目配置最佳实践_第4张图片

5. 加入 Element Plus

5.1 安装 element-plus

全局安装

npm?install?element-plus?--save

5.2 引入 Element Plus

你可以引入整个 Element Plus,或是根据需要仅引入部分组件。我们先介绍如何引入完整的 Element。

完整引入

在 main.js 中写入以下内容:

import?{?createApp?}?from?'vue'
import?ElementPlus?from?'element-plus';
import?router?from?"./router";
import?'element-plus/lib/theme-chalk/index.css';
import?App?from?'./App.vue';
import?'./index.css'

const?app?=?createApp(App)
app.use(ElementPlus)
app.use(router)
app.mount('#app')

以上代码便完成了 Element Plus 的引入。需要注意的是,样式文件需要单独引入。


按需引入

借助babel-plugin-component,我们可以只引入需要的组件,以达到减小项目体积的目的。

首先,安装 babel-plugin-component:

npm?install?babel-plugin-component?-D

然后,将 .babelrc 修改为:

{
??"plugins":?[
????[
??????"component",
??????{
????????"libraryName":?"element-plus",
????????"styleLibraryName":?"theme-chalk"
??????}
????]
??]
}

接下来,如果你只希望引入部分组件,比如 Button 和 Select,那么需要在 main.js 中写入以下内容:

import?{?createApp?}?from?'vue'
import?{?store,?key?}?from?'./store';
import?router?from?"./router";
import?{?ElButton,?ElSelect?}?from?'element-plus';
import?App?from?'./App.vue';
import?'./index.css'

const?app?=?createApp(App)
app.component(ElButton.name,?ElButton);
app.component(ElSelect.name,?ElSelect);

/*?or
?*?app.use(ElButton)
?*?app.use(ElSelect)
?*/

app.use(store,?key)
app.use(router)
app.mount('#app')
app.mount('#app')

更详细的安装方法请看 快速上手。

5.3 全局配置

在引入 Element Plus 时,可以传入一个全局配置对象。

该对象目前支持sizezIndex字段。size用于改变组件的默认尺寸,zIndex设置弹框的初始 z-index(默认值:2000)。按照引入 Element Plus 的方式,具体操作如下:

完整引入 Element:

import?{?createApp?}?from?'vue'
import?ElementPlus?from?'element-plus';
import?App?from?'./App.vue';

const?app?=?createApp(App)
app.use(ElementPlus,?{?size:?'small',?zIndex:?3000?});

按需引入 Element:

import?{?createApp?}?from?'vue'
import?{?ElButton?}?from?'element-plus';
import?App?from?'./App.vue';

const?app?=?createApp(App)
app.config.globalProperties.$ELEMENT?=?option
app.use(ElButton);

按照以上设置,项目中所有拥有size属性的组件的默认尺寸均为 ‘small’,弹框的初始 z-index 为 3000。

最后

Vue3 全家桶 + Element Plus + Vite + TypeScript + Eslint 项目配置最佳实践_第5张图片

至此,一个基于 Vue3 全家桶 + Vite + TypeScript + Eslint + Element Plus 的开发环境已经搭建完毕,现在就可以编写代码了。

各个组件的使用方法请参阅它们各自的文档。

不得不说 Vue3 + Element Plus + Vite + TypeScript 是真的香!

推荐一个 Vue3 相关的资料汇总:Vue3 的学习教程汇总、源码解释项目、支持的 UI 组件库、优质实战项目,相信你会挖到矿哦!

Vue3 中文文档,国内 CDN 加速版:

https://vue3js.cn/docs/zh/

Element Plus 官网:

https://element-plus.org/#/zh-CN


作为 2021 第 2 篇原创技术文章,质量应该还可以吧,1 月的 KPI 完成,哈哈哈

猫哥的年终总结在这里:前端工程师的 2020 年终总结 - 乾坤未定,你我皆黑马,希望能带给你一点启发,也看看猫哥的脸都被打歪的

参考文章:vue3 + vite + typescript + eslint + jest 项目配置实践

推荐阅读

  • TypeScript 中提升幸福感的 10 个高级技巧

  • 前端工程师的 2019?年终总结 - 当勤精进,但念无常

  • 前端工程师的 2018?年终总结 - 我的本命年

你可能感兴趣的:(前端,html,typescript,javascript,vue.js)