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

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

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/


微信图片_20220513125001.png


http://localhost:3000/about 即可


微信图片_20220513123952.gif


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。

相关文章
|
2月前
|
设计模式 监控 JavaScript
TypeScript 在大型项目内网管理监控软件中的结构优化
本文探讨了 TypeScript 在大型项目内网管理监控软件中的结构优化,包括模块划分与组织、接口与抽象类的使用以及依赖注入与控制反转的设计模式,通过具体代码示例展示了这些技术的应用,提高了代码的可读性、可维护性和灵活性。
45 3
|
4月前
|
JavaScript 前端开发 IDE
[译] 用 Typescript + Composition API 重构 Vue 3 组件
[译] 用 Typescript + Composition API 重构 Vue 3 组件
[译] 用 Typescript + Composition API 重构 Vue 3 组件
|
4天前
|
前端开发 JavaScript 开发者
前端项目代码规范工具 (ESLint. Prettier. Stylelint. TypeScript)
前端项目代码规范工具 (ESLint. Prettier. Stylelint. TypeScript)
|
1月前
|
JavaScript 前端开发
如何在 Vue 项目中配置 Tree Shaking?
通过以上针对 Webpack 或 Rollup 的配置方法,就可以在 Vue 项目中有效地启用 Tree Shaking,从而优化项目的打包体积,提高项目的性能和加载速度。在实际配置过程中,需要根据项目的具体情况和需求,对配置进行适当的调整和优化。
|
27天前
|
JavaScript 前端开发 安全
JavaScript与TypeScript的对比,分析了两者的特性及在实际项目中的应用选择
本文深入探讨了JavaScript与TypeScript的对比,分析了两者的特性及在实际项目中的应用选择。JavaScript以其灵活性和广泛的生态支持著称,而TypeScript通过引入静态类型系统,提高了代码的可靠性和可维护性,特别适合大型项目。文章还讨论了结合使用两种语言的优势,以及如何根据项目需求和技术背景做出最佳选择。
47 4
|
28天前
|
JavaScript 开发者
在软件开发中,代码规范至关重要,TypeScript 和 ESLint 是提升代码质量和团队协作效率的两大利器
在软件开发中,代码规范至关重要,TypeScript 和 ESLint 是提升代码质量和团队协作效率的两大利器。TypeScript 通过类型检查、接口定义和模块系统增强代码规范;ESLint 则专注于语法检查、风格统一和最佳实践。二者结合使用,能有效提高代码的可读性、可维护性,促进团队协作。制定合理的代码规范策略,注重团队共识、灵活性和持续优化,是确保项目成功的基石。
35 5
|
2月前
|
JavaScript 数据可视化
vue-cli学习二:vue-cli3版本 创建vue项目后,Runtime-Compiler和Runtime-only两个模式详解;vue项目管理器;配置文件的配置在哪,以及如何配置
这篇文章详细介绍了Vue CLI 3版本创建项目时的Runtime-Compiler和Runtime-only两种模式的区别、Vue程序的运行过程、render函数的使用、eslint的关闭方法,以及Vue CLI 2和3版本配置文件的不同和脚手架3版本创建项目的配置文件配置方法。
114 3
vue-cli学习二:vue-cli3版本 创建vue项目后,Runtime-Compiler和Runtime-only两个模式详解;vue项目管理器;配置文件的配置在哪,以及如何配置
|
1月前
|
JavaScript 前端开发 开发者
如何在 Visual Studio Code (VSCode) 中使用 ESLint 和 Prettier 检查代码规范并自动格式化 Vue.js 代码,包括安装插件、配置 ESLint 和 Prettier 以及 VSCode 设置的具体步骤
随着前端开发技术的快速发展,代码规范和格式化工具变得尤为重要。本文介绍了如何在 Visual Studio Code (VSCode) 中使用 ESLint 和 Prettier 检查代码规范并自动格式化 Vue.js 代码,包括安装插件、配置 ESLint 和 Prettier 以及 VSCode 设置的具体步骤。通过这些工具,可以显著提升编码效率和代码质量。
452 4
|
1月前
|
前端开发 JavaScript
手敲Webpack 5:React + TypeScript项目脚手架搭建实践
手敲Webpack 5:React + TypeScript项目脚手架搭建实践
|
2月前
|
资源调度 JavaScript 前端开发
路由管理:Vue Router的使用和配置技巧
【10月更文挑战第21天】路由管理:Vue Router的使用和配置技巧
46 3
下一篇
DataWorks