Vue3+TS+Vite+NaiveUI搭建一个项目骨架实现

作者:一碗周 时间:2024-05-28 15:55:14 

?? 写在前面

现在已经有很多项目团队使用Vue3+TS进行开发,同时也就意味着Vue3的生态越来越完善,如果还是停留在Vue2的阶段已经out了,这篇文章将会使用Vue3+TS+NaivaUI搭建一个简单的项目骨架。

?? 创建Vue3项目

首先我们通过Vite来创建一个Vue3+TS的一个项目,打开终端,找到我们项目应该存放的目录,出书如下命令:

npm create vite@latest

如果你是第一次使用Vite,需要先输入y,然后回依次出现:

  • 项目名称(想叫什么叫什么)

  • 框架(这里选择的是Vue)

  • Variant(这里选择的是Vue3+TS)

键入回车后等待一会项目就创建好了,然后进入项目安装依赖就好。

?? 开发规范

这里对开发规范的配置仅配置ESLint,其他的StyleLint、git提交验证这里不进行介绍;这里还会安装Prettier,用于代码格式化。

首先安装依赖:

npm i -D eslint eslint-plugin-vue eslint-define-config # eslink
npm i -D prettier eslint-plugin-prettier @vue/eslint-config-prettier # prettire
npm i -D @vue/eslint-config-typescript @typescript-eslint/eslint-plugin @typescript-eslint/parser # 对ts的支持

然后我们依次编写一下对应的配置文件:

ESLint风格检查配置文件:.eslintrc.js

const { defineConfig } = require('eslint-define-config')

module.exports = defineConfig({
 root: true,
 /* 指定如何解析语法。*/
 parser: 'vue-eslint-parser',
 /* 优先级低于parse的语法解析配置 */
 parserOptions: {
   parser: '@typescript-eslint/parser',
   //模块化方案
   sourceType: 'module',
 },
 env: {
   browser: true,
   es2021: true,
   node: true,
   // 解决 defineProps and defineEmits generate no-undef warnings
   'vue/setup-compiler-macros': true,
 },
 // https://eslint.bootcss.com/docs/user-guide/configuring#specifying-globals
 globals: {},
 extends: [
   'plugin:vue/vue3-recommended',
   'eslint:recommended',
   'plugin:@typescript-eslint/recommended', // typescript-eslint推荐规则,
   'prettier',
   'plugin:prettier/recommended',
 ],
 // https://cn.eslint.org/docs/rules/
 rules: {
   // 禁止使用 var
   'no-var': 'error',
   semi: 'off',
   // 优先使用 interface 而不是 type
   '@typescript-eslint/consistent-type-definitions': ['error', 'interface'],
   '@typescript-eslint/no-explicit-any': 'off', // 可以使用 any 类型
   '@typescript-eslint/explicit-module-boundary-types': 'off',
   // 解决使用 require() Require statement not part of import statement. 的问题
   '@typescript-eslint/no-var-requires': 0,
   // https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/eslint-plugin/docs/rules/ban-types.md
   '@typescript-eslint/ban-types': [
     'error',
     {
       types: {
         // add a custom message to help explain why not to use it
         Foo: "Don't use Foo because it is unsafe",

// add a custom message, AND tell the plugin how to fix it
         String: {
           message: 'Use string instead',
           fixWith: 'string',
         },

'{}': {
           message: 'Use object instead',
           fixWith: 'object',
         },
       },
     },
   ],
   // 禁止出现未使用的变量
   '@typescript-eslint/no-unused-vars': [
     'error',
     { vars: 'all', args: 'after-used', ignoreRestSiblings: false },
   ],
   'prettier/prettier': [
     'error',
     { singleQuote: true, parser: 'flow', semi: false },
   ],
   'vue/html-indent': 'off',
   // 关闭此规则 使用 prettier 的格式化规则,
   'vue/max-attributes-per-line': ['off'],
   // 优先使用驼峰,element 组件除外
   'vue/component-name-in-template-casing': [
     'error',
     'PascalCase',
     {
       ignores: ['/^el-/', '/^router-/'],
       registeredComponentsOnly: false,
     },
   ],
   // 强制使用驼峰
   camelcase: ['error', { properties: 'always' }],
   // 优先使用 const
   'prefer-const': [
     'error',
     {
       destructuring: 'any',
       ignoreReadBeforeAssign: false,
     },
   ],
 },
})

Prettier的代码格式化配置文件:prettierrc.js

module.exports = {
 // 结尾分号
 semi: false,
 // 单引号
 singleQuote: true,
 // 一行80字符
 printWidth: 80,
 // 尾逗号
 trailingComma: 'all',
 // 箭头函数的括号
 arrowParens: 'avoid',
 // 换行符
 endOfLine: 'lf',
}

配置ESLint的代码检测忽略的文件的配置文件:.eslintignore

/node_modules/
/public/
.vscode
.idea

?? Vite配置

?? 别名配置

配置别名可以帮助我们快速的找到我们想要的组件、图片等内容,不用使用../../../的方式,首先配置vite.config.ts,通过resolve.alias的方式配置,示例代码如下:

import { defineConfig } from 'vite'
import type { ConfigEnv } from 'vite'
import vue from '@vitejs/plugin-vue'
import { resolve } from 'path'

// https://vitejs.dev/config/
export default defineConfig(({ mode }: ConfigEnv) => {
 return {
   resolve: {
     alias: {
       '/@': resolve(__dirname, 'src'),
     },
     extensions: ['.js', '.json', '.ts', '.vue'], // 使用路径别名时想要省略的后缀名,可以自己 增减
   },

/* more config */
   plugins: [vue()],
 }
})

这里配置一个/@的别名,它指向src目录,然后配置tsconfig.json,允许别名在使用,代码如下:

"compilerOptions": {
 // 用于设置解析非相对模块名称的基本目录,相对模块不会受到baseUrl的影响
 "baseUrl": ".",
 "paths": {
   // 用于设置模块名到基于baseUrl的路径映射
   "/@/*": [ "src/*" ],
 }
},

环境变量

?? .env文件

在Vite中通过.env开头的文件去读取配置,来作为环境变量,Vite默认允许我们使用以下文件:

.env                # 所有情况下都会加载
.env.local          # 所有情况下都会加载,但会被 git 忽略
.env.[mode]         # 只在指定模式下加载
.env.[mode].local   # 只在指定模式下加载,但会被 git 忽略

这些文件是有优先级的,他们的优先级是.env<.env.local<.env.[mode]<.env.[mode].local;Vite中还预设了一些环境变量,这些的优先级是最高的,不会被覆盖,分别如下:

  • MODE: {string}:应用运行的模式(开发环境下为development,生成环境为production)。

  • BASE_URL: {string}:部署应用时的基本 URL。他由base 配置项决定。

  • PROD: {boolean}:当前是否是生产环境。

  • DEV: {boolean}:当前是否是开发环境 (永远与 PROD相反)。

这些环境变量Vite允许我们通过import.meto.env方式获取。

?? 定义环境变量

如果我么你想要自定义环境变量,就必须以VITE_开头,如果修改则需要通过envPrefix配置项,该配置项允许我们传入一个非空的字符串作为变量的前置。

.env

VITE_APP_API_BASE_URL=http://127.0.0.1:8080/

定义完成之后我们就可以在项目中通过import.meta.env.VITE_APP_API_BASE_URL的方式获取。

如果想要获得TypeScript的类型提示,需要在创建一个src/type/env.d.ts(把原src目录下的env.d.ts删除),示例代码如下:

/// <reference types="vite/client" />

interface ImportMetaEnv {
 readonly VITE_APP_API_BASE_URL: string
 // 定义更多环境变量
}

interface ImportMeta {
 readonly env: ImportMetaEnv
}

declare module '*.vue' {
 import type { DefineComponent } from 'vue'
 // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/ban-types
 const component: DefineComponent<{}, {}, any>
 export default component
}

在使用时就会获得智能提示。

?? 在vite.config.ts中获取环境变量

如果我们想要在vite.config.ts中获取环境变量,需要使用Vite提供的loadEnv()方法,该方法的定义如下:

function loadEnv(
 mode: string,
 envDir: string,
 prefixes?: string | string[]
): Record<string, string>

上面的三个参数的解释如下:

  • mode:模式;

  • envDir:环境变量配置文件所在目录;

  • prefixes:【可选】接受的环境变量前缀,默认为VITE_

了解了使用的API,在vite.config.ts中获取环境变量示例代码如下:

import { defineConfig, loadEnv } from 'vite'
import vue from '@vitejs/plugin-vue'
import AutoImport from 'unplugin-auto-import/vite'
import Components from 'unplugin-vue-components/vite'
import { ElementPlusResolver } from 'unplugin-vue-components/resolvers'
import type { ConfigEnv } from 'vite'

// https://vitejs.dev/config/
export default defineConfig(({ mode }: ConfigEnv) => {
 const env = loadEnv(mode, process.cwd())
 return {
   /* more config */
   server: {
     proxy: {
       '/api': {
         target: env.VITE_APP_API_BASE_URL,
         changeOrigin: true,
         rewrite: path => path.replace(/^\/api/, ''),
       },
     },
   },
 }
})

?? 自动导入

在使用setup语法糖进行开发的过程中,一些常用的API比如watchref等,需要每次都进行导入,而且组件如果是按需导入的话也需要进行导入,我们可以通过Vite的插件来帮助我们实现自动导入:

  • unplugin-vue-components:组件按需导入;

  • unplugin-auto-importvue, vue-router, vue-i18n, @vueuse/head, @vueuse/core等自动导入;

安装命令如下:

npm i -D unplugin-vue-components unplugin-auto-import

然后在vite.config.ts中导入并配置:

import { defineConfig, loadEnv } from 'vite'
import type { ConfigEnv } from 'vite'
import vue from '@vitejs/plugin-vue'
import { resolve } from 'path'
import AutoImport from 'unplugin-auto-import/vite'
import Components from 'unplugin-vue-components/vite'

// https://vitejs.dev/config/
export default defineConfig(({ mode }: ConfigEnv) => {
 const env = loadEnv(mode, process.cwd())
 return {
   resolve: {
     alias: {
       '/@': resolve(__dirname, 'src'),
     },
     extensions: ['.js', '.json', '.ts', '.vue'], // 使用路径别名时想要省略的后缀名,可以自己 增减
   },

/* more config */
   plugins: [
     vue(),
     AutoImport({
       resolvers: [],
       // 自定引入 Vue VueRouter API,如果还需要其他的可以自行引入
       imports: ['vue', 'vue-router'],
       // 调整自动引入的文件位置
       dts: 'src/type/auto-import.d.ts',
       // 解决自动引入eslint报错问题 需要在eslintrc的extend选项中引入
       eslintrc: {
         enabled: true,
         // 配置文件的位置
         filepath: './.eslintrc-auto-import.json',
         globalsPropValue: true,
       },
     }),
     Components({
       resolvers: [
         // 需要自动导入的组件
       ],
       dts: 'src/type/components.d.ts',
     }),
   ],
 }
})

现在我们可以在项目中直接使用Vue和VueRouter的所有API。

但是现在还有一个问题就是ESLint对自动引入的API报错,解决办法如下:

// 在.eslintrc.js中的extends配置项加入'./.eslintrc-auto-import.json',
extends: [
 'plugin:vue/vue3-recommended',
 'eslint:recommended',
 'plugin:@typescript-eslint/recommended', // typescript-eslint推荐规则,
 'prettier',
 'plugin:prettier/recommended',
 './.eslintrc-auto-import.json',
],

NaiveUI的安装

Q:众多UI组件库这里为什么选择NaiveUI?

A1:NaiveUI的官方文档对于其他UI组件库来说生动有趣;

A2:尤大推荐过;

A3:组件数量庞大;

安装依赖命令如下:

npm i -D naive-ui @vicons/ionicons5 # @vicons/ionicons5是icon的库

配置NaiveUI自动导入功能,打开vite.config.ts,从unplugin-vue-components/resolvers中引入NaiveUiResolver,并添加的在plugin中,示例代码如下:

Components({
 resolvers: [
   // 需要自动导入的组件
   NaiveUiResolver()
 ],
 dts: 'src/type/components.d.ts',
}),

现在就已经把 NaiveUI安装并引入了,其实很简单。

现在我们来使用一下这个UI组件库,这里就直接在App.vue中编写了,示例代码如下:

<script setup lang="ts">
import { zhCN, zhTW, dateZhCN, dateZhTW, darkTheme, lightTheme } from 'naive-ui'
import { Sunny, Moon } from '@vicons/ionicons5'
type LocaleType = 'zhCN' | 'zhTW'
const locale = ref<LocaleType>('zhCN')
const isDark = ref(false)
const langOpt = [
 { label: '简体中文', key: 'zhCN' },
 { label: '繁体中文', key: 'zhTW' },
]
const langList = {
 zhCN: { locale: zhCN, label: '简体中文', dataLocale: dateZhCN },
 zhTW: { locale: zhTW, label: '繁体中文', dataLocale: dateZhTW },
}
const handleSelect = (e: LocaleType) => {
 locale.value = e
}
</script>
<template>
 <NConfigProvider
   :locale="langList[locale].locale"
   :date-locale="langList[locale].dataLocale"
   :theme="isDark === true ? darkTheme : lightTheme"
 >
   <NGlobalStyle />
   <!-- vue-router占位 -->
   <router-view/>
 </NConfigProvider>
</template>
<style></style>

在里面展示了一部分组件,运行效果如下:

Vue3+TS+Vite+NaiveUI搭建一个项目骨架实现

?? 写在最后

这篇文章到这里就结束了,其实还有好多东西没有安装和配置,比如VueRouter、Pinia,还可以安装TailWindCSS,这些依赖的安装方式比较简单,官网都有比较完整的安装方式,这里就不啰嗦了。

来源:https://juejin.cn/post/7111998263753965576

标签:Vue3,项目骨架
0
投稿

猜你喜欢

  • Tkinter组件Checkbutton的具体使用

    2023-03-19 14:55:46
  • Python3中的tuple函数知识点讲解

    2021-12-31 17:22:56
  • 如何将anaconda安装配置的mmdetection环境离线拷贝到另一台电脑

    2022-12-16 00:48:47
  • 实例讲解Python中global语句下全局变量的值的修改

    2022-12-28 07:10:46
  • 详解python使用turtle库来画一朵花

    2021-08-30 14:58:49
  • Python图像锐化与边缘检测之Sobel与Laplacian算子详解

    2023-01-25 01:36:04
  • 全网最详细的vscode基础教程

    2022-09-22 08:43:05
  • Pandas出现KeyError的问题解决及分析

    2023-07-01 16:37:22
  • Python读取YAML文件过程详解

    2021-04-21 07:12:25
  • Python人脸识别初探

    2023-01-24 09:39:58
  • 实例讲解Python中整数的最大值输出

    2021-12-20 22:04:39
  • 如何前后翻阅聊友们的发言?

    2010-01-18 20:49:00
  • 利用PyInstaller将python程序.py转为.exe的方法详解

    2021-07-09 16:41:51
  • SQL Server 2016 无域群集配置 AlwaysON 可用性组图文教程

    2024-01-13 00:22:49
  • Python中json模块load/loads方法实战以及参数详解

    2022-01-28 14:14:30
  • ASP编程如何执行存储过程?

    2010-03-17 20:56:00
  • javascript onmouseout 解决办法

    2024-02-26 00:32:44
  • python文件操作之目录遍历实例分析

    2021-05-16 11:46:16
  • INSERT INTO .. ON DUPLICATE KEY更新多行记录

    2024-01-21 23:27:49
  • 在js中的replace方法详解

    2007-08-21 15:47:00
  • asp之家 网络编程 m.aspxhome.com