项目搭建
采用vite ``vue3 ts eslint pinia tailwindcss element-plus 等搭建项目,下面分布记录下
vite初始化项目
npm create vite
输入文件名称,回车vite-project
选vue
选ts
安装依赖 dev项目启动成功, 默认
http://localhost:5173/端口
安装sass
npm i -D sass
安装@types/node
解决vite.config.ts的 import path from "node:path"; ts报错问题
npm i @types/node -D
设置别名和sever 设置代理及端口设置
vite.config.ts文件做以下修改,此时端口已更改且默认打开浏览器
import { defineConfig } from 'vite'
import path from "node:path";
import vue from '@vitejs/plugin-vue'
// https://vitejs.dev/config/
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 做以下修改
{
"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路由
npm i vue-router -S
创建router文件夹,内部创建index.ts
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如下
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 引用路由
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/>
<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
npm i pinia -S
npm i pinia-plugin-persistedstate -S
pinia-plugin-persistedstate为了持久化pinia
创建 store文件夹,内部创建 use-user.ts,内容如下
// 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修改为
<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修改为
<template>
<div>
{{ JSON.stringify(user) }}
</div>
</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
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自动导入插件,可以按需引入不用此插件
npm i element-plus @element-plus/icons-vue -S
npm install unplugin-vue-components unplugin-auto-import -D
vite.config.ts做更改
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组件做更改
<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已经引入
安装tailwindcss
npm install -D tailwindcss postcss autoprefixer
npx tailwindcss init -p
两步骤操根目录生成 postcss.config.js
export default {
plugins: {
tailwindcss: {},
autoprefixer: {},
},
}
tailwind.config.js
/** @type {import('tailwindcss').Config} */
export default {
content: [],
theme: {
extend: {},
},
plugins: [],
}
有次两步文件及初始化成功,创建styles文件夹 下级创建index.css tailwind.css
index.css
@import url('tailwind.css');
tailwind.css
/* src/index.css */
@tailwind base;
@tailwind components;
@tailwind utilities;
main.ts 引入 tailwindcss
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
/** @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]" 样式已生效
<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 ,可消除报错
{
"css.lint.unknownAtRules": "ignore"
}
适配原理
我们可以看到tailwindcss尺寸都是基于rem的 如下
谷歌浏览器的
html 的font-size: 16px,所以1rem 对应16px,基于此我们可以更具屏幕宽度对应根文字大小,tailwindcss可基于html 的font-size来适配
在html文件中增加如下代码。默认1920是16px,动态计算宽度来适配,
<script>
window.addEventListener("resize", () => {
const screenWidth = window.innerWidth;
const baseFontSize = 16; // 当屏幕宽度为1920px时的字体大小
const baseScreenWidth = 1920;
const fontSize = (screenWidth / baseScreenWidth) * baseFontSize;
// 假设你想要改变的是body元素的字体大小
document.documentElement.style.fontSize = `${fontSize}px`;
});
// 初始设置
window.dispatchEvent(new Event("resize"));
</script>
安装postcss-pxtorem 插件,将px转为rem
npm i postcss-pxtorem -S postcss.config.js更改为
export default {
plugins: {
tailwindcss: {},
autoprefixer: {},
"postcss-pxtorem": {
rootValue: 16, // (Number | Function) 表示根元素字体大小或根据input参数返回根元素字体大小
unitPrecision: 5, // (数字)允许 REM 单位增长到的十进制数字
propList: ["*"], // 可以从 px 更改为 rem 的属性 使用通配符*启用所有属性
selectorBlackList: [], // (数组)要忽略并保留为 px 的选择器。
replace: true, // 替换包含 rems 的规则,而不是添加回退。
minPixelValue: 0, // 最小的转化单位
exclude: /node_modules/i, // 要忽略并保留为 px 的文件路径
},
},
};
这样可以按照标准设计稿1920对应的尺寸来开发了 如设计稿120px 可 写为 tailwindcss的 w-[120px]
eslint
恰逢eslint@9 及扁平化配置出来,技术有限,配置了半天没搞定扁平化配置,还是使用非扁平化的配置方式, package.json中devDependencies增加如下依赖 eslint,哪位大佬搞出扁平化配置了,踢我一脚
"@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
**/iconfont.js
**/flexable.js
src/apis/modules/*
src/apis/**/model.ts
node_modules
.eslintrc.cjs
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
npm i axios -S
关于 axios 一个封装请求,尅要根据自己业务需要特定的封装,官方文档如下 axios