背景
最近有朋友要搭建一个vue3+ts的项目,本着帮一把的原则,搭建了一个,仅仅作为参考,市场很多成熟框架如admin等。好记性不如烂笔头记录下,目录如下 后面不在重复提及
项目搭建
采用vite
vue3
ts
eslint
pinia
tailwindcss
element-plus
等搭建项目,下面分布记录下
vite初始化项目
js
npm create vite
输入文件名称,回车即可,默认名称为vite-project
选择vue
ts
回车 创建成功
js
cd vite-tets-work
npm install
npm run dev
安装依赖 dev项目启动成功, 默认http://localhost:5173/
端口
安装sass
js
npm i -D sass
安装@types/node
解决vite.config.ts的 import path from "node:path";
ts报错问题
js
npm i @types/node -D
设置别名和sever 设置代理及端口设置
vite.config.ts
文件做以下修改,此时端口已更改且默认打开浏览器
js
import { defineConfig } from 'vite'
import path from "node:path";
import vue from '@vitejs/plugin-vue'
export default defineConfig({
plugins: [
vue()
],
base: "./",
resolve: {
alias: {
"@": path.resolve(__dirname, "./src"),
},
},
// 配置代理
server: {
host: "0.0.0.0",
port: 8861,
open: true,
proxy: {
"/api": {
target: "***********",
changeOrigin: true,
secure: false,
// rewrite: (path) => path.replace(/^\/api/, ""),
}
},
cors: true,
},
})
tsconfig.json
做以下修改
js
{
"compilerOptions": {
"target": "ES2020",
"useDefineForClassFields": true,
"module": "ESNext",
"lib": ["ES2020", "DOM", "DOM.Iterable"],
"skipLibCheck": true,
/* Bundler mode */
"moduleResolution": "bundler",
"allowImportingTsExtensions": true,
"resolveJsonModule": true,
"isolatedModules": true,
"noEmit": true,
"jsx": "preserve",
/* Linting */
"strict": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"noFallthroughCasesInSwitch": true,
// @设置
"baseUrl": ".",
"paths": {
"@/*": ["src/*"]
},
},
"include": ["src/**/*.ts", "src/**/*.tsx", "src/**/*.vue", "src/**/*.d.ts"],
"references": [{ "path": "./tsconfig.node.json" }]
}
router路由
js
npm i vue-router -S
创建router
文件夹,内部创建index.ts
js
import { createRouter, createWebHistory, RouteRecordRaw } from 'vue-router';
import TestRoutes from '@/views/test/routes';
const routes: Array<RouteRecordRaw> = [
{
path: '/',
redirect: '/login'
},
{
path: '/login',
name: 'Login',
component: () => import('@/views/login/index.vue')
},
{
path: '/test',
name: 'test',
children: [...TestRoutes],
meta: {
sort: 1,
icon: 'FillSet',
title: '测试带单',
menu: true
}
}
];
const router = createRouter({
scrollBehavior(to, from, savedPosition) {
return { top: 0 };
},
history: createWebHistory(),
routes
});
router.beforeEach((to: any, from, next) => {
next();
});
export default router;
创建views
文件夹,下一级创建login
test
文件夹。目录如下,请自行创建对应文件
test
中的 routes.ts
如下
js
import { RouteRecordRaw } from 'vue-router';
const routes: Array<RouteRecordRaw> = [
{
path: 'test1',
name: 'test1',
component: () => import('@/views/test/test1.vue'),
meta: {
title: '测试1'
}
},
{
path: 'test2',
name: 'test2',
component: () => import('@/views/test/test2.vue'),
meta: {
title: '测试2'
}
}
];
export default routes;
main.ts
引用路由
js
import { createApp } from "vue";
import "./style.css";
import App from "./App.vue";
// routes
import router from "./router/index";
const app = createApp(App);
app.use(router);
app.mount("#app");
app.vue
文件引入 <router-view/>
js
<template>
<div>
<router-view/>
</div>
</template>
<style scoped>
.logo {
height: 6em;
padding: 1.5em;
will-change: filter;
transition: filter 300ms;
}
.logo:hover {
filter: drop-shadow(0 0 2em #646cffaa);
}
.logo.vue:hover {
filter: drop-shadow(0 0 2em #42b883aa);
}
</style>
此时如果报ts 找不到模块"vue-router"或其相应的类型声明
重新打开下vscode即可
重新 npm run dev
默认http://localhost:8861/login
打开你的login组件, http://localhost:8861/test/test1
会打开test下的test1组件。
安装pinia
js
npm i pinia -S
npm i pinia-plugin-persistedstate -S
pinia-plugin-persistedstate
为了持久化pinia
创建 store
文件夹,内部创建 use-user.ts
,内容如下
js
// src/stores/counter.ts
import { defineStore } from 'pinia';
import { reactive } from 'vue';
export const useUserInfoStore = defineStore(
'userInfo',
() => {
const user = reactive({
name: '',
age: '',
sex: ''
});
const setUserInfo = (data: { name: string, age: string, sex: string }) => {
Object.assign(user, data);
};
return { user, setUserInfo };
},
{
persist: true,
}
);
login
中的index.vue
修改为
js
<template>
<div>
<span class="text-[#ff0000]">{{ user }}</span>
<button @click="addStore">点击</button>
</div>
</template>
<script lang="ts" setup>
import { storeToRefs } from "pinia";
import { useUserInfoStore } from "@/store/use-user";
const userInfoStore = useUserInfoStore();
const { user } = storeToRefs(userInfoStore);
const addStore = () => {
userInfoStore.setUserInfo({
name: "张三",
age: Math.random() * 100 + "",
sex: "男"
});
};
</script>
test
中的 test1.vue
修改为
js
<template>
<hl-group class="empty" align="items-center items-middle" dir="vertical" gap="var(--md)">
{{ JSON.stringify(user) }}
</hl-group>
</template>
<script lang="ts" setup>
import { useUserInfoStore } from '@/store/use-user';
import { storeToRefs } from 'pinia';
const userInfoStore = useUserInfoStore();
const { user } = storeToRefs(userInfoStore);
</script>
main.ts
中引入pinia
js
import { createApp } from 'vue'
import './style.css'
import App from './App.vue'
import { createPinia } from 'pinia';
import piniaPluginPersistedstate from 'pinia-plugin-persistedstate';
//routes
import router from "./router/index";
const pinia = createPinia();
pinia.use(piniaPluginPersistedstate);
const app= createApp(App)
app.use(pinia);
app.use(router);
app.mount('#app');
此时login
组件操作,可修改pinia
, test1
组件会获取到pinia
状态, 此时ts 报错 store找不到
重启vscode即可
安装element-plus @element-plus/icons-vue 及动态导入
element-plus unplugin-vue-components
unplugin-auto-import
自动导入插件,可以按需引入不用此插件
js
npm i element-plus @element-plus/icons-vue -S
npm install unplugin-vue-components unplugin-auto-import -D
vite.config.ts
做更改
js
import { defineConfig } from 'vite'
import path from "node:path";
import vue from '@vitejs/plugin-vue'
import { ElementPlusResolver } from 'unplugin-vue-components/resolvers'
import AutoImport from "unplugin-auto-import/vite"
import Components from 'unplugin-vue-components/vite';
export default defineConfig({
plugins: [
vue(),
Components({
resolvers: [ElementPlusResolver()],
dts: "src/components.d.ts",
}),
AutoImport({
imports: ['vue', 'vue-router'],
dts: "src/auto-import.d.ts",
})
],
base: "./",
// base: "/rag",
// 配置别名
resolve: {
alias: {
"@": path.resolve(__dirname, "./src"),
},
},
// 配置代理
server: {
host: "0.0.0.0",
port: 8861,
open: true,
proxy: {
"/api": {
target: "***********",
changeOrigin: true,
secure: false,
}
},
cors: true,
},
})
login
组件做更改
js
<template>
<div>
<span>{{ user }}</span>
<button @click="addStore">点击</button>
<el-button type="primary">Primary</el-button>
<el-button type="success">Success</el-button>
<el-button type="info">Info</el-button>
<el-button type="warning">Warning</el-button>
<el-button type="danger">Danger</el-button>
</div>
</template>
<script lang="ts" setup>
import { storeToRefs } from "pinia";
import { useUserInfoStore } from "@/store/use-user";
const userInfoStore = useUserInfoStore();
const { user } = storeToRefs(userInfoStore);
const addStore = () => {
userInfoStore.setUserInfo({
name: "张三",
age: Math.random() * 100 + "",
sex: "男"
});
};
</script>
可见element-plus
已经引入,button组件展示
安装tailwindcss
js
npm install -D tailwindcss postcss autoprefixer
js
npx tailwindcss init -p
两步骤操根目录生成 postcss.config.js
js
export default {
plugins: {
tailwindcss: {},
autoprefixer: {},
},
}
tailwind.config.js
js
/** @type {import('tailwindcss').Config} */
export default {
content: [],
theme: {
extend: {},
},
plugins: [],
}
有次两步文件及初始化成功,创建styles
文件夹 下级创建index.css
tailwind.css
index.css
js
@import url('tailwind.css');
tailwind.css
js
/* src/index.css */
@tailwind base;
@tailwind components;
@tailwind utilities;
main.ts
引入 tailwindcss
js
import { createApp } from 'vue'
import './style.css'
import App from './App.vue'
import { createPinia } from 'pinia';
import piniaPluginPersistedstate from 'pinia-plugin-persistedstate';
import "@/styles/index.css";
//routes
import router from "./router/index";
const pinia = createPinia();
pinia.use(piniaPluginPersistedstate);
const app= createApp(App)
app.use(pinia);
app.use(router);
app.mount('#app');
tailwind.config.js
做如下更改
js
/** @type {import('tailwindcss').Config} */
export default {
darkMode: "class",
corePlugins: {
preflight: false
},
content: ["./index.html", "./src/**/*.{vue,js,ts,jsx,tsx}"],
theme: {
extend: {
colors: {
title: "#202020",
secondTitle: "#8A8A8A",
normal: "#4b4b4b",
light: "#dddddd",
active: "#2C54D1",
disabled: "#aaaaaa",
},
fontSize: {
20: "20px",
18: "18px",
16: "16px",
14: "14px",
},
},
},
plugins: [],
}
login
中的 index.vue
试用下 tailwindcss
class="text-[#ff0000]"
样式已生效
js
<template>
<div>
<span class="text-[#ff0000]">{{ user }}</span>
<button @click="addStore">点击</button>
<el-button type="primary">Primary</el-button>
<el-button type="success">Success</el-button>
<el-button type="info">Info</el-button>
<el-button type="warning">Warning</el-button>
<el-button type="danger">Danger</el-button>
</div>
</template>
<script lang="ts" setup>
import { storeToRefs } from "pinia";
import { useUserInfoStore } from "@/store/use-user";
const userInfoStore = useUserInfoStore();
const { user } = storeToRefs(userInfoStore);
const addStore = () => {
userInfoStore.setUserInfo({
name: "张三",
age: Math.random() * 100 + "",
sex: "男"
});
};
</script>
此时如果 tailwind.css
报错 Unknown at rule @tailwindcss(unknownAtRules)
,在跟目录创建.vscode
下级settings.json
,可消除报错
js
{
"css.lint.unknownAtRules": "ignore"
}
eslint
恰逢eslint@9 及扁平化配置出来,技术有限,配置了半天没搞定扁平化配置,还是使用非扁平化的配置方式, package.json
中devDependencies
增加如下依赖 eslint,哪位大佬搞出扁平化配置了,踢我一脚
js
"@typescript-eslint/parser": "^7.7.0",
"@vue/eslint-config-standard": "^8.0.1",
"@vue/eslint-config-typescript": "^13.0.0",
"eslint": "^8.57.0",
"eslint-plugin-import": "^2.29.1",
"eslint-plugin-node": "^11.1.0",
"eslint-plugin-promise": "^6.1.1",
"eslint-plugin-vue": "^9.25.0",
"vite-plugin-eslint": "^1.8.1",
"prettier-eslint": "^16.3.0",
重新 npm i
安装依赖
根目录创建.eslintignore
js
**/iconfont.js
**/flexable.js
src/apis/modules/*
src/apis/**/model.ts
node_modules
.eslintrc.cjs
js
module.exports = {
root: true,
env: {
node: true,
},
extends: [
"plugin:vue/vue3-essential",
"@vue/standard",
"@vue/typescript/recommended",
],
parserOptions: {
ecmaVersion: 2020,
},
ignorePatterns: [
"*.config.*",
"dist/*",
"build/*",
"public/*",
"src/apis/modules/**",
],
rules: {
"no-console": "error"
},
globals: {
uap: "readonly",
uni: "readonly",
regist: "readonly",
defineProps: "readonly",
defineOptions: "readonly",
defineEmits: "readonly",
defineExpose: "readonly",
},
};
打开vscode 安装 eslint
插件,打开保存即可
在test
test1.vue
写一句console.log(1111)
eslint已经生效
安装axios
js
npm i axios -S
关于 axios
一个封装请求,尅要根据自己业务需要特定的封装,官方文档如下 axios
结尾
好了 结束