共计 7728 个字符,预计需要花费 20 分钟才能阅读完成。
尤大的 Vue3.0 曾经公布有一阵子了,曾经很成熟了。
而且 Element Plus + Vite 也出了一段时间了,是时候该上手体验分享一波了。
次要是要纯熟一下 Vue3,好筹备用 Vue3 重构一下本人的网站我的项目: blog-vue-typescript,打算是过年期间会着手重构这个我的项目,年后会上线。
1. 初化化我的项目
全局装置 vite-app
npm i -g vite-app
创立我的项目
yarn create vite-app <project-name>
# 或者
npm init vite-app <project-name>
进入我的项目,装置依赖
cd <project-name>
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
<script type="module" src="/src/main.js"></script>
批改为:<script type="module" src="/src/main.ts"></script>
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<Store<State>> = Symbol()
export const store = createStore<State>({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 批改
<template>
<h1>{{msg}}</h1>
<button @click="inCrement"> count is: </button>
<p>{{count}}</p>
</template>
<script>
import {defineComponent, computed} from 'vue'
import {useStore} from 'vuex'
import {key} from '../store'
export default defineComponent({
name: 'HelloWorld',
props: {
msg: {
type: String,
default: ''
}
},
setup() {const store = useStore(key)
const count = computed(() => store.state.count)
return {
count,
inCrement: () => store.commit('increment')
}
}
})
</script>
4.2 vue-router
在 src 目录下建设 router/index.ts,内容如下:
import {createRouter, createWebHistory, RouteRecordRaw} from "vue-router";
import HelloWorld from "../components/HelloWorld.vue";
const routes: Array<RouteRecordRaw> = [
{
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 文件,内容如下:
<template>
<img
alt="Vue logo"
src="../assets/logo.png"
/>
<h1>{{msg}}</h1>
</template>
<script lang="ts">
import {defineComponent} from 'vue'
export default defineComponent({
name: 'About',
data() {
return {msg: 'Hello Vue 3.0 + Vite!'}
},
setup() {}
})
</script>
再批改 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/
和 http://localhost:3000/about 即可
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 时,能够传入一个全局配置对象。
该对象目前反对 size
与 zIndex
字段。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 全家桶 + 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 年终总结 – 我的本命年