美文网首页
Vite-Vue3.x-TS-Eslint项目初始化(2022-

Vite-Vue3.x-TS-Eslint项目初始化(2022-

作者: 东方三篇 | 来源:发表于2022-05-02 18:07 被阅读0次

    Vite-Vue3.x-TS-Eslint项目初始化

    Lzq811/Vue3.x-vite-ts-eslint-prettier: vue3大屏基础框架 (github.com)

    1. init

    yarn create vite demo-product --template vue-ts
    cd ./demo-product
    yarn
    yarn dev
    # 能正常方法 localhost:3000 页面,说明 init 成功
    

    2. 使用 element-plus UI 库

    yarn add element-plus
    
    • 推荐使用 按需引入 文档地址

      # 需要安装下面两个依赖
      yarn add unplugin-vue-component unplugin-auto-import
      
    • 然后再 vite.config.ts 文件中修改

      import { defineConfig } from 'vite'
      import vue from '@vitejs/plugin-vue'
      import AutoImport from 'unplugin-auto-import/vite'
      import Component from 'unplugin-vue-components/vite'
      import {ElementPlusResolver } from 'unplugin-vue-components/resolvers'
      
      // https://vitejs.dev/config/
      export default defineConfig({
        plugins: [
          vue(),
          AutoImport({
            resolvers: [ElementPlusResolver()]
          }),
          Component({
            resolvers: [ElementPlusResolver()]
          })
        ]
      })
      
      
    • 然后在使用的组件中直接调用

      <el-button type="primary">hello element btn</el-button>
      
    • 自定义主题 文档地址

    • 使用 Less

      # 安装依赖
      yarn add less less-loader -D
      # 然后vite.config.js, 要require('path'), 如果require 和 __dirname报ts错, 使用 @ts-ignore 或者安装 @types/node 依赖
      css: {
          preprocessorOptions: {
            less: {
              modifyVars: {
                hack: `true; @import (reference) "${path.resolve(__dirname, 'src/assets/base.less')}"` // 全局定义的less文件
              },
              javascriptEnabled: true
            }
          }
        }
        
       # 在组件内使用
       <style lang="less" scoped></style>
      

    3. 使用 Eslint 、 Prettier 做代码校验和自动格式化

    • 安装 eslint 以及相关依赖

      yarn add eslint eslint-plugin-vue vue-eslint-parser @typescript-eslint/parser @typescript-eslint/eslint-plugin eslint-config-airbnb-base eslint-plugin-import -D
      
    • vscode 编辑器 也要安装 Eslint 和 Prettier 拓展

    • 根目录添加 .eslintrc.js文件,并添加下面代码

      module.exports = {
        root: true,
        globals: {
            defineEmits: 'readonly',
            defineProps: 'readonly'
        },
        extends: [
            'plugin:@typescript-eslint/recommended',
            'plugin:vue/vue3-recommended',
            'airbnb-base'
        ],
        parserOptions: {
            parser: '@typescript-eslint/parser',
            ecmaVersion: 2020
        },
        rules: {
            'no-debugger': process.env.NODE_ENV === 'production' ? 'warn' : 'off', // 禁用 debugger
            'no-console': process.env.NODE_ENV === 'production' ? 'warn' : 'off', // 禁用 console
            'no-bitwise': 'off', // 禁用按位运算符
            'no-tabs': 'off', // 禁用 tab
            'array-element-newline': ['error', 'consistent'], // 强制数组元素间出现换行
            indent: [
                'error',
                2,
                { MemberExpression: 0, SwitchCase: 1, ignoredNodes: ['TemplateLiteral'] }
            ], // 强制使用一致的缩进
            quotes: ['error', 'single'], // 强制使用一致的反勾号、双引号或单引号
            'comma-dangle': ['error', 'always-multiline'], // 要求或禁止末尾逗号
            'object-curly-spacing': ['error', 'always'], // 强制在大括号中使用一致的空格
            'max-len': ['error', 120], // 强制一行的最大长度
            'no-new': 'off', // 禁止使用 new 以避免产生副作用
            'linebreak-style': 'off', // 强制使用一致的换行风格
            'import/extensions': 'off', // 确保在导入路径中统一使用文件扩展名
            'eol-last': 'off', // 要求或禁止文件末尾存在空行
            'no-shadow': 'off', // 禁止变量声明与外层作用域的变量同名
            'no-unused-vars': 'warn', // 禁止出现未使用过的变量
            'import/no-cycle': 'off', // 禁止一个模块导入一个有依赖路径的模块回到自己身上
            'arrow-parens': 'off', // 要求箭头函数的参数使用圆括号
            semi: ['error', 'never'], // 要求或禁止使用分号代替 ASI
            eqeqeq: 'on', // 要求使用 === 和 !==
            'no-param-reassign': 'off', // 禁止对 function 的参数进行重新赋值
            'import/prefer-default-export': 'off', // 如果模块只输入一个名字,则倾向于默认输出
            'no-use-before-define': 'on', // 禁止在变量定义之前使用它们,则倾向于默认输出
            'no-continue': 'off', // 禁用 continue 语句
            'prefer-destructuring': 'off', // 优先使用数组和对象解构
            'no-plusplus': 'off', // 禁用一元操作符 ++ 和 --
            'prefer-const': 'warn', // 要求使用 const 声明那些声明后不再被修改的变量
            'global-require': 'on', // 要求 require() 出现在顶层模块作用域中
            'no-prototype-builtins': 'off', // 禁止直接调用 Object.prototypes 的内置属性
            'consistent-return': 'off', // 要求 return 语句要么总是指定返回的值,要么不指定
            'one-var-declaration-per-line': 'off', // 要求或禁止在变量声明周围换行
            'one-var': 'off', // 强制函数中的变量要么一起声明要么分开声明
            'import/named': 'off', // 确保命名导入与远程文件中的命名导出相对应
            'object-curly-newline': 'off', // 强制大括号内换行符的一致性
            'default-case': 'off', // 要求 switch 语句中有 default 分支
            'no-trailing-spaces': 'on', // 禁用行尾空格
            'func-names': 'off', // 要求或禁止使用命名的 function 表达式
            radix: 'off', // 强制在 parseInt() 使用基数参数
            'no-unused-expressions': 'off', // 禁止出现未使用过的表达式
            'no-underscore-dangle': 'off', // 禁止标识符中有悬空下划线
            'no-nested-ternary': 'off', // 禁用嵌套的三元表达式
            'no-restricted-syntax': 'off', // 禁用特定的语法
            'no-await-in-loop': 'off', // 禁止在循环中出现 await
            'import/no-extraneous-dependencies': 'off', // 禁止使用外部包
            'import/no-unresolved': 'off', // 确保导入指向一个可以解析的文件/模块
            'template-curly-spacing': ['error', 'always'], // 要求或禁止模板字符串中的嵌入表达式周围空格的使用
            '@typescript-eslint/no-var-requires': 'off', // 除import语句外,禁止使用require语句
            '@typescript-eslint/no-empty-function': 'off', // 不允许空函数
            '@typescript-eslint/no-explicit-any': 'off', // 禁止使用 any 类型
            'guard-for-in': 'off', // 要求 for-in 循环中有一个 if 语句
            'class-methods-use-this': 'off', // 强制类方法使用 this
            'vue/html-indent': ['error', 2], // 在<template>中强制一致缩进
            'vue/html-self-closing': 'off', // 执行自闭合的风格
            'vue/max-attributes-per-line': [
                // 强制每行属性的最大数量
                'warn',
                {
                    singleline: {
                        max: 3,
                        allowFirstLine: true
                    },
                    multiline: {
                        max: 1,
                        allowFirstLine: false
                    }
                }
            ],
            'vue/singleline-html-element-content-newline': 'off' // 要求单行元素的内容前后有一个换行符
        }
      }
      
      
    • 根目录添加 prettier.config.js文件,并添加下面代码

      // prettier.config.js or .prettierrc.js
      module.exports = {
        // 一行最多 100 字符
        printWidth: 100,
        // 使用 2 个空格缩进
        tabWidth: 2,
        // 不使用缩进符,而使用空格
        useTabs: false,
        // 行尾需要有分号
        semi: false,
        // 使用单引号
        singleQuote: true,
        // 对象的 key 仅在必要时用引号
        quoteProps: 'as-needed',
        // jsx 不使用单引号,而使用双引号
        jsxSingleQuote: false,
        // 末尾不需要逗号
        trailingComma: 'none',
        // 大括号内的首尾需要空格
        bracketSpacing: true,
        // jsx 标签的反尖括号需要换行
        jsxBracketSameLine: false,
        // 箭头函数,只有一个参数的时候,也需要括号
        arrowParens: 'always',
        // 每个文件格式化的范围是文件的全部内容
        rangeStart: 0,
        rangeEnd: Infinity,
        // 不需要写文件开头的 @prettier
        requirePragma: false,
        // 不需要自动在文件开头插入 @prettier
        insertPragma: false,
        // 使用默认的折行标准
        proseWrap: 'preserve',
        // 根据显示样式决定 html 要不要折行
        htmlWhitespaceSensitivity: 'css',
        // 换行符使用 lf
        endOfLine: 'lf'
      }
      
      
    • 根目录 添加 .eslintignore 并写入下面代码

      /build/
      /config/
      /dist/
      /*.js
      /*.zip
      /*.rar
      
      

    4. 配置环境变量

    • 在根目录新建文件夹 env-config,然后在文件夹下新增文件并录入内容

      所有的环境变量必须以 VITE_ 开头

      # 新增 .env 文件 写入下面内容
        VITE_ENV = DEV
        VITE_APP_BASE_URL = 'http://DEV.com'
        
      # 新增 .env.test 文件并写入内容
        VITE_ENV = TEST
        VITE_APP_BASE_URL = 'http://TEST.com'
        
      # 新增 .env.prod 文件并写入内容
        VITE_ENV = PROD
        VITE_APP_BASE_URL = 'http://PROD.com'
      
    • vite.config.js文件夹中配置 envDir

      // @ts-ignore 如果提示错误 使用 @ts-ignore 或者 yarn add @types/node 只有node里面才有 require 和 __dirname
      const path = require('path')
      function _resolve(dir) {
        // @ts-ignore
        return path.resolve(__dirname, dir)
      }
      
      // https://vitejs.dev/config/
      export default defineConfig({
        envDir: _resolve('env-config'),
        ...
      })
      
    • 修改 package.json 的命令(我比较喜欢用 start 代替 dev)

        "scripts": {
          "dev": "vite",
          "start": "vite --mode env",
          "start-test": "vite --mode test",
          "start-prod": "vite --mode prod",
          "build": "vue-tsc --noEmit && vite build",
          "build-test": "vue-tsc --noEmit && vite build --mode test",
          "build-prod": "vue-tsc --noEmit && vite build --mode prod",
          "preview": "vite preview"
        },
      
    • 使用 import.meta.env 来获取环境变量信息

      # 组件里面调用测试
      onMounted(() => {console.log(import.meta.env)})
      
    • 执行start命令

      yarn start # 执行 dev 环境
      # OR
      yarn start-test # 执行 test 环境
      # OR
      yarn start-prod # 执行 orod 环境
      
      #demo
      yarn start-test
      # 调取 import.meta.env 的结果
        BASE_URL: "/"
        DEV: true
        MODE: "test"
        PROD: false
        VITE_APP_BASE_URL: "http://TEST.com"
        VITE_ENV: "TEST"
      
    • 执行build命令

      #demo
      yarn build-test
      # 调取 import.meta.env 的结果
        BASE_URL: "/"
        DEV: true
        MODE: "test"
        PROD: false
        VITE_APP_BASE_URL: "http://TEST.com"
        VITE_ENV: "TEST"
      

    5. 使用 axios 封装 ajax 请求

    • 安装 axios

      yarn add axios
      
    • 配置封装

      1. 新建文件src/api/index.tsx
      // index.tsx 文件
      import ajax from './ajax'
      /*
       * ajax 从 ajax.js 引入 需要
       * 第一个 参数 是 url 必填
       * 第二个 参数 是 params对象 默认 {} 非必填
       * 第三个 参数 是 GET、POST 请求方式, 默认 POST, 非必填
       */
      // 后台地址
      const BASE_URL: string = import.meta.env.VITE_APP_BASE_URL || '' // 环境变量后台地址
      // const BASE_URL: string = `http:xxxx/api`
      // const BASE_URL_OTHER:string = `http:xxx2.api` // 多个后台地址
      
      interface IParams {}
      
      // 登陆接口
      export const ReqLogin = (params: IParams) => ajax(`${BASE_URL}login`, params, 'POST') // POST 是默认值,可以不写
      
      // export const ReqOther = (params:IParams) => ajax(`${BASE_URL_OTHER}login`, params)
      
      
    1. 新建文件 src/api/ajax.tsx

      // ajax.tsx 文件
      import axios from 'axios'
      
      // 可以在这里做一下请求拦截,设置公共请求头等
      
      export default function ajax(url: string, data: any = {}, type: string = 'POST') {
        // 判断 url 地址, 在多个后台地址时候使用, 可以在这里拦截使用不同的请求头,传入不同token等操作
      
        return new Promise((resolve, reject) => {
          let promise: any // 返回一个 promise 对象
          if (type === 'GET') {
            promise = axios.get(url, { params: data })
      
            // 多个后台地址时候,传入不同的token值
            promise = axios.get(url, {
              params: data,
              headers: { access_totken: sessionStorage.getItem('token_other') || '' }
            })
          } else if (type === 'POST') {
            promise = axios.post(url, data)
      
            // 多个后台地址时候,传入不同的token值
            promise = axios.get(url, data)
          }
          // 统一处理 response
          promise
            .then((response: any) => {
              response && response.data ? resolve(response.data) : reject(response)
            })
            .catch((error: any) => {
              console.log(error)
            })
        })
      }
      
      
    2. 组件内调用

     ```tsx
     import {ReqLogin} from './src/api'
     
     const ajaxDemo = async () => {
        const res:any = await ReqLogin({}) // res就是ajax返回的结果
     }
     ```
    

    6. 页面弹性布局

    • 新建 src/utils/comfort_page.tsx

      /*
       * 做页面自适应
       * 0. 项目跟元素 id = root
       * 1. width 为适应基准
       * 2. 无论 width height 如何变化,都要输出 16 / 9 比例的页面
       * 3. 客户的设备分辨率 1920 * 1080
       */
      
      // @ts-nocheck
      
      const W = 1920
      const H = 1080
      
      export default () => {
        const root = document.getElementById('root')?.style
        window.onresize = () => {
          root.transform = `scale(${document.body.offsetWidth / W})`
          root.transformOrigin = `left top 0px`
          root.width = `${W}px`
          root.height = `${H}px`
        }
        root.transform = `scale(${document.body.offsetWidth / W})`
        root.transformOrigin = `left top 0px`
        root.width = `${W}px`
        root.height = `${H}px`
      }
      
      
    • App.vue 组件引入

      import ComfortPage from './utils/comfort_page'
      onMounted(() => {
        ComfortPage()
      })
      

    7. 路由

    • 路由要用 4 版本的,才对应 vue3版本

      yarn add vue-router@4
      
    • 新增 src/routes/index.tsx

      import { createRouter, createWebHistory } from 'vue-router'
      
      const routes: any = [
        {
          path: '/',
          redirect: 'home'
        },
        {
          path: '/home',
          name: 'home',
          component: () => import('../Home.vue') // 要提前注册号该组件
        },
        {
          path: '/first',
          name: 'first',
          component: () => import('../First.vue') // 要提前注册号该组件
        }
      ]
      
      const router = createRouter({
        history: createWebHistory(),
        routes: routes
      })
      
      router.beforeEach((to, from) => {
        const { path: toPath } = to
        const { path: fromPath } = from
        if (toPath === fromPath) {
          return false
        }
      })
      
      export default router
      
      
    • 修改 main.ts 文件

      import router from './routes'
      
      const app = createApp(App)
      app.use(router)
      app.mount('#app')
      
    • 修改 App.vue 文件

      <template>
          <router-view></router-view>
      </template>
      
    • 跳转

      import {useRouter} from 'vue-router'
      
      const router = useRouter()
      
      router.push('./first')
      

    8. 路径别名

    • 修改 vite.config.js 内容

      export default defineConfig({
        envDir: path.resolve(__dirname, 'env-config'),
        plugins: [
          vue(),
          AutoImport({
            resolvers: [ElementPlusResolver()]
          }),
          Component({
            resolvers: [ElementPlusResolver()]
          })
        ],
        css: {
          preprocessorOptions: {
            less: {
              modifyVars: {
                hack: `true; @import (reference) "${path.resolve(__dirname, 'src/assets/base.less')}"` // 全局定义的less文件
              },
              javascriptEnabled: true
            }
          }
        },
        resolve: {
          extensions: ['.js', '.vue', '.json'],
          alias: {
            '@api': _resolve('src/api'),
            '@components': _resolve('src/components'),
            '@': _resolve('src')
          }
        }
      })
      
    • 新增 src/ts.extends.json 文件

      {
        "compilerOptions": {
          "baseUrl": ".",
          "paths": {
            "@/*": [
              "*"
            ],
            "@api/*": [
              "src/api/*"
            ]
          }
        }
      }
      
    • 修改 tsconfig.json 文件

      {
        ...
        "extends": "./ts.extends.json" # 添加该属性
      }
      
    • 使用

      import { ReqLogin } from '@api/index'
      

    相关文章

      网友评论

          本文标题:Vite-Vue3.x-TS-Eslint项目初始化(2022-

          本文链接:https://www.haomeiwen.com/subject/gndvyrtx.html