看完你也可以写的vue3+ts+vite+element-plus项目

vue3完整项目配置(手把手教你从零到一的开发过程)

先把项目的readme丢出来吧

项目readme

相关技术

vue3 + ts + vite + windiCss + element-plus + pnpm

安装依赖/启动/打包

sudo npm i pnpm -g

pnpm i

## 启动项目
pnpm/npm start

## 打包项目
pnpm/npm run build
复制代码

pnpm是否使用都可以,看你自己平时的使用习惯

相关技术以及对应配置

初始化vue3

如果我们使用vite的时候我们可以直接使用vite来初始化项目,而不是使用@vue/cli,建议选择ts的模板

npm create vite my-vue-app -- --template vue
复制代码

动态router自动注入

安装依赖

npm i vue-route @vueuse/core -S
npm i vite-plugin-pages -D
复制代码

配置vite.config.ts文件

import { defineConfig } from 'vite'
import Vue from '@vitejs/plugin-vue'
import Pages from 'vite-plugin-pages'

export default defineConfig({
  plugins: [
    Vue(),
    Pages(),
  ],
  optimizeDeps: {
    include: [
      'vue',
      'vue-router',
      '@vueuse/core',
    ],
  },
})
复制代码

入口文件main.ts添加router

import { createApp } from 'vue'
import App from './App.vue'
import { createRouter, createWebHashHistory } from 'vue-router'
import routes from 'virtual:generated-pages'

const app = createApp(App)
const router = createRouter({
  history: createWebHashHistory(),
  routes,
})
app.use(router)
app.mount('#app')

复制代码

在src文件夹下添加pages的目录,这样pages下面的目录会自动天添加到router中去,不需要手动引入

注:根据pages文件夹下面自动生成动态路由,以下是新的写法

  1. [id].vue: 此组件可以传入一个props为id的参数进入组件
  2. [...all].vue: 此组件可以匹配没有匹配到其他类似[id].vue组件的组件,类似于vue2的*.vue组件

添加本地服务

配置vite.config.ts

import { defineConfig } from 'vite'

export default defineConfig({
  server: {
    fs: {
      strict: true,
    },
    // NOTE: ip和端口
    host: '',
    port: '',
    // NOTE: 本地调试代理
    proxy: {
    },
  }
})

复制代码

配置windiCss减少css

windiCss目前对webpack的支持并不是特别好,之前有个写营销组件的项目有想过使用webpack+windiCss的组件,但是调试起来有点费劲,最终放弃

但是windiCss对vite的支持非常好,在vite的项目我们只需要做这样几步就可以按照文档开心的使用了

npm i vite-plugin-windicss -D
复制代码

项目目录下添加windiCss的配置文件windi.config.ts

import { defineConfig } from 'windicss/helpers'

export default defineConfig({
  darkMode: 'class',
  // https://windicss.org/posts/v30.html#attributify-mode
  attributify: true
})
复制代码

vite.config.ts中配置windiCss的plugin

// ...
import WindiCSS from 'vite-plugin-windicss'
import { defineConfig } from 'vite'
// ...

export default defineConfig({
  // ...
  plugins: [
     // ...
    // https://github.com/antfu/vite-plugin-windicss
    WindiCSS()
  ],
  // ...
})

复制代码

以上说有的配置就完成了,接下来在入口文件main.ts中引入windicss相关的文件

import { createApp } from 'vue'
import App from './App.vue'

// NOTE: 以下为windiCss的引入
// windicss layers
import 'virtual:windi-base.css'
import 'virtual:windi-components.css'
import 'virtual:windi-utilities.css'

复制代码

接下来就可以愉快告别css、less这样的文件,而是直接通过添加class来编译的所需要的样式

添加element-plus以及自动化按需加载

element能够做到的点是:

  1. 无需单个import组件,引用关系有vite插件完成
  2. 所有的标签直接使用,且按需引入
npm i unplugin-icons unplugin-vue-components unplugin-element-plus -D
npm i element-plus @element-plus/icons -S
复制代码

vite.config.ts的配置

import { defineConfig } from 'vite'
import Icons from 'unplugin-icons/vite'
import IconsResolver from 'unplugin-icons/resolver'
import Components from 'unplugin-vue-components/vite'
import { ElementPlusResolver } from 'unplugin-vue-components/resolvers'
import ElementPlus from 'unplugin-element-plus/vite'

export default defineConfig({
  plugins: [
    // ...
    Components({
      dts: true,
      resolvers: [
        // auto import icons
        // https://github.com/antfu/vite-plugin-icons
        IconsResolver({}),
	ElementPlusResolver()
      ]
    }),
    // https://github.com/antfu/vite-plugin-icons
    Icons(),
    ElementPlus({})
  ]
})
复制代码

这样所有出现过的element标签都会自动在components.d.ts中去并注册为全局组件

eslint配置

npm i @typescript-eslint/eslint-plugin @typescript-eslint/parser @vue/eslint-config-typescript eslint eslint-plugin-vue -D
复制代码

添加.eslintrc.js的配置

const commonRules = {
  // allow paren-less arrow functions
  'arrow-parens': 0,
  // allow async-await
  'generator-star-spacing': 0,
  // 不强制要求三元运算符换行
  'multiline-ternary': 0,
  // 对象key保持一致风格,都加引号或者都不加
  'quote-props': ['error', 'as-needed'],
  // 关闭使用apply时提示使用解构参数的行为,因为有时候apply用于改变this指向
  'prefer-spread': 0,
  // 允许使用中括号进行属性取值操作
  'dot-notation': 0,
  // 不强制要求使用const
  'prefer-const': 2,
  // 允许混合使用 && 和 ||
  'no-mixed-operators': 0,
  // 允许promise.reject不返回 Error 类型
  'prefer-promise-reject-errors': 0,
  // 这个规则有问题,先关掉
  'no-unused-vars': 2,
  // 允许使用prototype
  'no-prototype-builtins': 2,
  // allow debugger during development
  'no-debugger': process.env.NODE_ENV ? 2 : 0,
  'space-before-function-paren': 2,
  // 不知道为什么会有node的规则,先关闭,可能是eslint默认引入了
  'node/no-callback-literal': 0,
  camelcase: 1,
  curly: 1,
  quotes: [2, 'single'],
  semi: [2, 'never'],
  'no-case-declarations': 0,
  'no-empty': 2,
  'lines-between-class-members': 2,
  'no-var': 'error',
  'comma-dangle': [
    'error',
    {
      arrays: 'always-multiline',
      objects: 'always-multiline',
      imports: 'always-multiline',
      exports: 'always-multiline',
      functions: 'only-multiline', // 关闭airbnb对函数调用参数,非一行,最后也要加逗号的限制
    },
  ],
}

const tsRules = {
  ...commonRules,
  // 允许使用非空断言
  '@typescript-eslint/no-non-null-assertion': 0,
  // 允许使用空函数,但后续应规范定义一个空函数统一引用
  '@typescript-eslint/no-empty-function': 0,
  // 允许使用ts注释
  '@typescript-eslint/ban-ts-comment': 0,
  // 允许显示使用any
  '@typescript-eslint/no-explicit-any': 0,
  // 允许使用变量存储this
  '@typescript-eslint/no-this-alias': 0,
  // 允许不显示声明函数返回类型
  '@typescript-eslint/explicit-module-boundary-types': 0,
  // ts不推荐使用的类型,先放开,后面加
  // '@typescript-eslint/ban-types': 0
  // require文件
  '@typescript-eslint/no-var-requires': 0,
}

module.exports = {
  root: true,
  env: {
    node: true,
  },
  parser: 'vue-eslint-parser',
  parserOptions: {
    parser: '@typescript-eslint/parser',
    ecmaVersion: 2020,
    sourceType: 'module',
    ecmaFeatures: {
      jsx: true,
    },
  },
  extends: [
    'eslint:recommended',
    'plugin:vue/vue3-essential',
    '@vue/typescript/recommended',
  ],
  rules: {
    ...commonRules,
    'no-console': process.env.NODE_ENV === 'production' ? 'warn' : 'off',
    'no-debugger': process.env.NODE_ENV === 'production' ? 'warn' : 'off',
    'no-unused-vars': [
      'error',
      { varsIgnorePattern: '.*', args: 'none' },
    ],
    '@typescript-eslint/no-unused-vars': [
      'error',
      { varsIgnorePattern: '.*', args: 'none' },
    ],
  },
  globals: {
    defineProps: 'readonly',
    defineEmits: 'readonly',
    defineExpose: 'readonly',
    withDefaults: 'readonly',
  },
  overrides: [
    {
      files: ['**/*.ts'],
      parser: '@typescript-eslint/parser',
      extends: [
        'plugin:@typescript-eslint/eslint-recommended',
        'plugin:@typescript-eslint/recommended',
      ],
      plugins: ['@typescript-eslint'],
      rules: tsRules,
    },
    {
      files: ['**/*.d.ts'],
      parser: '@typescript-eslint/parser',
      extends: [
        'plugin:@typescript-eslint/eslint-recommended',
        'plugin:@typescript-eslint/recommended',
      ],
      plugins: ['@typescript-eslint'],
      rules: {
        ...tsRules,
        '@typescript-eslint/ban-types': 0, // 针对全局类型取消类型使用限制
        // 允许使用空interface,主要为了便利require.d.ts
        '@typescript-eslint/no-empty-interface': 0,
        'no-use-before-define': 0,
      },
    },
  ],
}
复制代码

其中相关rules可根据自己或者团队的开发习惯做一些修改

vscode安装相关插件

  1. WindiCSS IntelliSense
  2. Vue Language Features (Volar)
  3. Vite
  4. Vetur TypeScript performance workaround
  5. ESLint

当然如果你的编辑器不是vscode,你可以找到相关插件的安装方法,也可留言评论,我们一起看看哦

项目地址

demo地址

おすすめ

転載: juejin.im/post/7040740423110754317
おすすめ