vite vue3 ts vuex vue-router element-plus axios
文章目录
vite
$ yarn create vite
$ cd <project-name>
$ yarn
$ yarn dev
vue3的API自动导入
$ yarn add unplugin-auto-import -D
/vite.config.ts
import AutoImport from "unplugin-auto-import/vite";
export default {
plugins: [
AutoImport({
// 自动导入vue相关的Api
imports: ["vue"], // 也支持vue-router、axios等
// 声明文件的存放位置
dts: 'auto-imports.d.ts',
}),
],
}
/tsconfig.json
的include
中加入"auto-imports.d.ts"
{
"include": ["src/**/*.ts", "src/**/*.d.ts", "src/**/*.tsx", "src/**/*.vue", "auto-imports.d.ts"],
}
然后不需要import
就能直接使用vue3的api了
<template>
<p>firstName: {{firstName}}</p>
<p>lastName: {{lastName}}</p>
<p>fullName: {{fullName}}</p>
</template>
<script lang="ts" sutup>
// 使用unplugin-auto-import后无需引入即可直接使用vue3中的api
// import { ref, computed, onMounted } from 'vue'
const firstName = ref('')
const lastName = ref('')
onMounted(() => {
firstName.value = 'Alex'
lastName.value = 'Brown'
})
const fullName = computed(() => firstName.value + ' ' + lastName.value)
</script>
vuex
$ yarn add vuex
新增文件/src/store/index.ts
import { createStore } from 'vuex'
const store = createStore({
state: {},
getters: {},
mutations: {},
actions: {},
})
export default store
修改/src/main.ts
import store from './store/index'
createApp(App).use(store).mount('#app')
vue-router
$ yarn add vue-router
新增文件/src/router/index.ts
import { createRouter, createWebHistory } from 'vue-router'
const pages = import.meta.glob('../views/**/*.vue');
const routes = Object.keys(pages).map(path => {
let name = path.replace(/\.\.\/views(.*)\.vue$/, '$1').toLowerCase();
//去掉最后的/index
name = name.replace(/\/index$/, '');
return {
path: name === '/home' ? '/' : name,
component: pages[path]
}
})
const router = createRouter({
history: createWebHistory(),
routes
})
export default router
修改/src/main.ts
import router from './router/index'
createApp(App).use(store).use(router).mount('#app')
element-plus
$ yarn add element-plus
完整导入
/src/main.ts
import ElementPlus from 'element-plus'
import 'element-plus/dist/index.css'
createApp(App).use(store).use(router).use(ElementPlus).mount('#app')
如果您使用 Volar,请在
tsconfig.json
中通过compilerOptions.type
指定全局组件类型。
// tsconfig.json
{
"compilerOptions": {
// ...
"types": ["element-plus/global"]
}
}
按需自动导入
$ yarn add unplugin-auto-import unplugin-vue-components -D
// vite.config.ts
import { defineConfig } from 'vite'
import AutoImport from 'unplugin-auto-import/vite'
import Components from 'unplugin-vue-components/vite'
import { ElementPlusResolver } from 'unplugin-vue-components/resolvers'
// https://vitejs.dev/config/
export default defineConfig({
// ...
plugins: [
// ...
AutoImport({
resolvers: [ElementPlusResolver()],
}),
Components({
resolvers: [ElementPlusResolver()],
}),
],
})
愉快的使用element-plus组件
<template>
<el-button @click="showMessage" type="primary">showMessage</el-button><br>
</template>
<script lang="ts" setup>
const showMessage = () => {
ElMessage('this is a message')
}
</script>
Icon按需自动导入
$ yarn add unplugin-icons unplugin-auto-import -D
// vite.config.ts
import path from 'path'
import { defineConfig, loadEnv } from 'vite'
import vue from '@vitejs/plugin-vue'
import Icons from 'unplugin-icons/vite'
import IconsResolver from 'unplugin-icons/resolver'
import AutoImport from "unplugin-auto-import/vite";
import Components from 'unplugin-vue-components/vite'
import { ElementPlusResolver } from 'unplugin-vue-components/resolvers'
const pathSrc = path.resolve(__dirname, 'src')
export default ({ mode }) => {
const { VITE_APP_BASE_URL } = loadEnv(mode, process.cwd())
// https://vitejs.dev/config/
return defineConfig({
server: {
port: 1003,
https: false,
proxy: {
'/api': {
target: VITE_APP_BASE_URL,
changeOrigin: true,
rewrite: (path) => path.replace(/^\/api/, '')
}
}
},
resolve: {
alias: {
'@': pathSrc // 设置别名
}
},
plugins: [
vue(),
AutoImport({
// Auto import functions from Vue, e.g. ref, reactive, toRef...
// 自动导入 Vue 相关函数,如:ref, reactive, toRef 等
imports: ['vue'],
// Auto import functions from Element Plus, e.g. ElMessage, ElMessageBox... (with style)
// 自动导入 Element Plus 相关函数,如:ElMessage, ElMessageBox... (带样式)
resolvers: [
ElementPlusResolver(),
// Auto import icon components
// 自动导入图标组件
IconsResolver({
prefix: 'Icon',
}),
],
dts: path.resolve(pathSrc, 'auto-imports.d.ts'),
}),
Components({
resolvers: [
// Auto register icon components
// 自动注册图标组件
IconsResolver({
enabledCollections: ['ep'],
}),
// Auto register Element Plus components
// 自动导入 Element Plus 组件
ElementPlusResolver(),
],
dts: path.resolve(pathSrc, 'components.d.ts'),
}),
Icons({
autoInstall: true,
}),
]
})
}
使用 icon
<el-icon :size="20" color="red">
<i-ep-edit />
</el-icon>
配置路径别名
在/vite.config.ts
中加入以下代码
import path from 'path'
// https://vitejs.dev/config/
export default defineConfig({
resolve: {
alias: {
'@': path.resolve(__dirname, './src') // 设置别名
},
}
// ...
})
这时需要安装node
$ yarn add @types/node -D
否则path
和__dirname
会报错
找不到模块“path”或其相应的类型声明。ts(2307)
找不到名称“__dirname”。ts(2304)
在tsconfig.json
中配置别名
{
"paths": {
"@":["./src"],
"@/*":["./src/*"]
}
}
scss
$ yarn add sass -D
<style lang="scss" scoped></style>
axios
$ yarn add axios
新建文件/src/request/index.ts
import axios, { AxiosInstance } from 'axios'
import store from '@/store';
// http://www.axios-js.com/docs/#axios-create-config
const instance: AxiosInstance = axios.create({
baseURL: 'http://test.some-domain.com/api',
timeout: 3000,
withCredentials: true
})
// 添加请求拦截器
instance.interceptors.request.use(
(config: any) => {
// 在发送请求之前做些什么
config.headers.Authorization = store.state.token;
return config
},
(error) => {
// 对请求错误做些什么
console.log(error)
return Promise.reject(error)
}
)
// 添加响应拦截器
instance.interceptors.response.use(
(response) => {
console.log(response)
// 2xx 范围内的状态码都会触发该函数。
// 对响应数据做点什么
// dataAxios 是 axios 返回数据中的 data
const dataAxios = response.data
// 这个状态码是和后端约定的
const code = dataAxios.reset
return dataAxios
},
(error) => {
// 超出 2xx 范围的状态码都会触发该函数。
// 对响应错误做点什么
console.log(error)
return Promise.reject(error)
}
)
export default instance
使用
import axios from '@/request/index'
axios.get('https://api.path.domain').then(data => {
// do something
}).catch(err => {
Message.error(err.message)
})
配置环境变量
与vue-cli
中使用process.env
不同,Vite
在一个特殊的import.meta.env
对象上暴露环境变量。
根目录新建文件/.env.production
# .env.production
VITE_APP_BASE_URL = http://test.some-domain.com/api
根目录新建文件/.env.development
# .env.development
VITE_APP_BASE_URL = 'http://some-domain.com/api'
使用import.meta.env.VITE_APP_BASE_API
即可访问
/* /src/request/index.ts */
const instance: AxiosInstance = axios.create({
baseURL: import.meta.env.VITE_APP_BASE_URL
// ...
})
在所有情况下都可以使用import.meta.env
中的内建变量:
import.meta.env.MODE
: {string} 应用运行的模式。import.meta.env.BASE_URL
: {string} 部署应用时的基本 URL。他由base 配置项决定。import.meta.env.PROD
: {boolean} 应用是否运行在生产环境。import.meta.env.DEV
: {boolean} 应用是否运行在开发环境 (永远与import.meta.env.PROD
相反)。
配置代理
有时候涉及到跨域问题需要使用代理服务器做请求转发
/vite.config.ts
// https://vitejs.dev/config/
export default defineConfig({
server: {
// ...
proxy: {
'/api': {
target: "http://test.some-domain.com/api",
changeOrigin: true,
rewrite: (path) => path.replace(/^\/api/, '')
}
}
},
// ...
})
如果需要使用环境变量可引入loadEnv
/vite.config.ts
import { defineConfig, loadEnv } from 'vite'
export default ({ mode }) => {
const { VITE_APP_BASE_URL } = loadEnv(mode, process.cwd())
// https://vitejs.dev/config/
return defineConfig({
server: {
// ...
proxy: {
'/api': {
target: VITE_APP_BASE_URL,
changeOrigin: true,
rewrite: (path) => path.replace(/^\/api/, '')
}
}
},
// ...
})
}