一、摘要
本篇文章可以带你手把手搭建一个vite+vue3.0+ts+naive-ui的项目。
兼容性说明
Vite 需要Node.js版本 >=12.0.0。
二、创建项目
-
在要创建项目的文件中右键打开PowerShell
-
运行命令 $ npm init vite@latest
-
输入项目名称
-
选择vue框架
-
选择vue-ts模板
这样就创建完成了。
我们打开文件夹看到
三、运行项目
- 用vscode打开,在终端运行npm install。
如果安装过程过慢,可以使用淘宝镜像,运行npm config set registry registry.npm.taobao.org
(使用yarn、cnpm的应该没这个问题),换过镜像后再运行npm install - 使用npm run dev运行项目,可以看到默认初始界面(ctrl+c结束运行)
四、代码规范
1.集成prettier(代码格式化)
-
安装prettier
npm install prettier -D
安装过后,我们发现package.json文件中有了prettier,package.json文件中存放的是项目中依赖的插件库,有些插件像prettier这种只是在开发时要用到的,代码提交上线时不需要,所以存在
devDependencies
即可,dependencies
中存放的是生产环境中要用到的插件。
安装命令后的-D就是可以存到devDependencies
中。 -
配置prettier
在根目录创建.prettierrc文件,在该文件中配置prettier各项规范。{ "end_of_line": "lf" }
这个配置是可以在ctrl+s保存后自动将行尾序列crlf转换成lf。 prettier具体配置可见:Options · Prettier
常用的配置选项 默认值 注解 printWidth: <int> 80 超过80个字符换行 tabWidth: <int> 2 缩进空格数 useTabs: <bool> false 用制表符缩进 trailingComma: "<es5|none|all>" es5 行尾逗号 bracketSameLine: <bool> false 将多行 HTML元素放在最后一行的末尾,而不是单独放在下一行(不适用于自闭合元素) - 安装prettier插件
2.集成eslint(检验代码格式的工具)
- 安装eslint
npm install eslint -D
安装与使用可见eslint官网:入门 - ESLint 中文
-
配置eslint
在根目录创建.eslintrc.js文件,在该文件中配置eslint。module.exports = { root: true, env: { node: true, }, extends: [ "plugin:vue/vue3-essential", "eslint:recommended", "@vue/typescript/recommended", "@vue/prettier", "@vue/prettier/@typescript-eslint", ], parserOptions: { ecmaVersion: 2020, // 配置ECMAScript版本 }, rules: {}, };
五、项目配置
1.配置路由
vue-router4配置详情可见:安装 | Vue Router (vuejs.org)
-
安装vue-router
npm install vue-router@4 // vue-router 4.x版本支持vue3
-
在main.ts中引入
import { createApp } from 'vue' // vue的启动函数,返回一个应用实例 import App from './App.vue' // 入口文件 import router from "./router" // 路由 createApp(App).use(router).mount('#app')
-
在src文件下创建router文件夹并创建index.ts文件。
import { createRouter, createWebHistory, RouteRecordRaw } from "vue-router" const routes: Array<RouteRecordRaw> = [] const router = createRouter({ history: createWebHistory(), // 使用history模式 routes, }) export default router;
- vue-router3.x:默认使用hash模式。
- vue-router4.x: 可以灵活的配置路由模式
- history---createWebHistory
- hash---createWebHashHistory
- abstract---createMemoryHistory
-
更改入口文件app.vue
<template> <router-view></router-view> </template> <script lang="ts" setup></script> <style> #app { font-family: Avenir, Helvetica, Arial, sans-serif; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; text-align: center; color: #2c3e50; margin-top: 60px; } </style>
-
在src下创建views文件夹,之后的页面文件都存入此文件夹中。在views文件夹下创建index.vue文件作为项目的首页。
<template> <div>首页</div> </template> <script lang="ts" setup></script> <style scoped></style>
-
将首页配置到路由文件中
import { createRouter, createWebHistory, RouteRecordRaw } from "vue-router" const routes: Array<RouteRecordRaw> = [ { path: "/", name: "Home", component: () => import("../views/index.vue"), } ] const router = createRouter({ history: createWebHistory(), routes, }) export default router;
-
运行项目,可以看到
2.配置vuex
vuex4配置详情可见: Installation | Vuex (vuejs.org)
-
安装vuex
npm install vuex@next --save // vuex4.x支持vue3
-
在src下创建store文件夹(之后要存入vuex的数据都放入此文件夹中),并创建index.ts文件
import { createStore } from "vuex"; export default createStore({ state: {}, mutations: {}, actions: {}, modules: {}, });
-
在main.ts中引入
import { createApp } from 'vue' import App from './App.vue' import router from "./router" import store from "./store" createApp(App).use(store).use(router).mount('#app')
3.使用naive-ui
官方文档入口:Naive UI: 一个 Vue 3 组件库
-
安装naive-ui
npm i -D naive-ui
-
在src下创建plugins文件夹(该文件夹存放项目中用到的插件),并创建naiveui.ts文件。
按需引入组件示例:import { create, NButton, NInput } from "naive-ui"; const naive = create({ components: [NButton, NInput] }) export default naive;
-
在main.ts中引入
import { createApp } from 'vue' import App from './App.vue' import router from "./router" import store from "./store" import naiveui from "./plugins/naiveui"; createApp(App).use(store).use(router).use(naiveui).mount('#app')
-
组件使用示例:
<template> <div> <h1>首页</h1> <n-button type="primary">按钮</n-button> <n-input v-model:value="value" type="text" placeholder="基本的 Input" ></n-input> </div> </template> <script lang="ts" setup> import { ref } from "@vue/reactivity"; const value = ref(111); </script> <style scoped></style>
运行后可以看到:
4.集成scss
-
安装
npm install sass -D
-
安装后可见:
-
之后在vue文件中可以直接使用
<style lang="scss" scoped></style>
-
5.封装axios
-
安装axios
npm install axios
-
在plugins文件夹下创建axios文件夹(该文件夹用来封装axios)
-
在axios文件下创建interceptors文件夹(该文件夹用来拦截请求、拦截响应,为什么拦截请求和拦截响应要分两个文件呢?因为单一职能原则)
- 在interceptors文件夹下创建request.ts文件
import { Axios } from "axios"; export default (axiosInstance: Axios): void => { axiosInstance.interceptors.request.use((config) => { return config; }); };
- 在interceptors文件夹下创建response.ts文件
import { Axios } from "axios"; export default (axiosInstance: Axios): void => { // 相应拦截器 axiosInstance.interceptors.response.use( (response) => { const { responseType } = response.config; // 不拦截blob if (responseType === "blob") { return response; } const { success, errMsg } = response.data; // 处理失败请求 if (!success) { window.$message.error(errMsg); return Promise.reject(errMsg); } return response.data; }, (error) => { return Promise.reject(error); } ); };
-
在axios下创建index.ts,用来创建axios实例
import axios, { Axios } from "axios"; import responseInterceptor from "./interceptors/response"; import requestInterceptor from "./interceptors/request"; // 创建axios实例 const axiosInstance: Axios = axios.create({ baseURL: process.env.VUE_APP_BASE_API_PATH, timeout: 10000, withCredentials: true, }); // 请求拦截器 requestInterceptor(axiosInstance); // 响应拦截器 responseInterceptor(axiosInstance); export default axiosInstance;
-
-
在src下创建api文件夹(之后页面要调用的接口都统一从这里导出,为什么api与axios封装没在一个文件夹下?为了解耦)
- 在api文件夹下创建index.ts文件(由该文件统一导出各个文件接口)
- 在api文件夹下创建bussniess文件夹(该文件夹里边存放所有业务接口)
-
补充
因为在/plugins/axios/interceptor/request.ts文件中使用了naive-ui中message组件,所以需要引入:-
在/plugins/naiveui.ts文件中
import { create, NButton, NInput, NMessageProvider } from "naive-ui"; const naive = create({ components: [NButton, NInput, NMessageProvider] }) export default naive;
引入后直接移步到【六、踩坑系列】第3点处
-
-
接口调用示例
- 在api/bussniess下创建user文件夹,并创建index.ts文件。
import axiosInstance from "@/plugins/axios" const GETUSERINFOAPI = (data: any): Promise<any> => axiosInstance.get('/blog/user', data); export default{ GETUSERINFOAPI, // 获取用户信息 }
- 在api/index.ts文件中统一导出。
import userApi from '@/api/bussniess/user' export { userApi, }
- 在页面中调用
<script lang="ts" setup> import { userApi } from "@/api"; const userInfo = () => { userApi.GETUSERINFOAPI({}).then(() => {}); }; </script>
六、搭建中遇到的坑
1.全局样式引入失败
这个坑暂时还没有解决,解决后再更新文章。
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import path from "path"
export default defineConfig({
resolve: {
alias: {
"@": path.resolve(__dirname, 'src')
}
},
plugins: [vue()],
css: {
preprocessorOptions: {
scss: {
additionalData: `@import '@/assets/scss/index.scss';`
}
}
}
})
2.vite路径修改别名失败(已解决)
-
安装@types/node
npm i @types/node -D
-
配置tsconfig.json文件
-
vite.config.ts
- 然后就可以优雅的使用别名了
3.全局使用naive-ui中的message组件(已解决)
-
在声明文件env.d.ts中声明$message
declare interface Window { $message: any; }
-
在components文件中创建MessageApi.vue组件
<template> <div></div> </template> <script lang="ts" setup> import { defineComponent, getCurrentInstance } from "vue"; import { useMessage } from "naive-ui"; window.$message = useMessage(); </script>
此时useMessage()已挂载到window上,可以通过window.$message使用
-
在App.vue文件中引入MessageApi组件
<template> <n-message-provider> <MessageApi /> </n-message-provider> <router-view></router-view> </template>
-
在文件中使用
打印window可以看到
页面上点击按钮显示
最后
1.项目结构一览图
2.项目开源链接
vite-practice: vite+vue3.0+ts+naive-ui (gitee.com)
3.其他
本人正在参加年度人气创作者评选,如果你看到了最后,感觉对你有所帮助的话,请为我投上宝贵的一票,附上链接:掘金 - 2021年度人气创作者榜单 (juejin.cn)。