项目同步git:vue3+vite+ts+pinia+vant+less: 空白的vue3架子,利用vant ui,适用于移动端一类的开发。 架子没有任何页面,基本无需删除任何代码,拉取便可直接用于开发。 假如有资助到各位朋友还请点个警惕心哦
以为有资助的小伙伴请点下警惕心哦
为避免赘述,过于基础的点会直接省略或贴图,比如创建文件夹/文件的路径/路由一类
配置相应功能,也只管只贴相关代码,并不代表整个文件内容
我会只管把每一步都记录下来,让跟随文档操作的朋友也能还原项目
项目不尽完善,但是主体功能应该都可以有所参考
一.当地初始情况
二.利用vite脚手架,创建vue3+ts
输入项目名,回车确认
选择Vue和TypeScript
文件目次如下,项目创建成功!
三.启动项目:根据提示进入项目运行项目,或自行利用编码器输入指令进行启动
- yarn // 安装依赖
- yarn dev // 运行项目
复制代码
浏览器打开地点,运行成功!
四.必备依赖
This package contains type definitions for Node.js (Node.js — Run JavaScript Everywhere)
- yarn add @types/node -S -D
复制代码
五.配置路径别名@
1.位置:直接改写vite.config.ts -- 顺便就添加alias
- // vite.config.ts
- import vue from "@vitejs/plugin-vue";
- import { resolve } from "path";
- function pathResolve(dir: string) {
- return resolve(process.cwd(), ".", dir);
- }
- // https://vitejs.dev/config/
- export default () => {
- return {
- resolve: {
- alias: [
- {
- find: "@",
- replacement: pathResolve("src"),
- },
- {
- find: "views",
- replacement: pathResolve("src/views"),
- },
- ],
- },
- plugins: [vue()],
- };
- };
复制代码
2.位置:tsconfig.json -- 修改baseUrl及paths
- // tsconfig.json
- {
- "compilerOptions": {
- ......
- "baseUrl": "./",
- "paths": {
- "@/*": ["src/*"],
- "views/*": ["src/views/*"],
- "components/*": ["src/components/*"],
- "assets/*": ["src/assets/*"]
- }
- },
- "include": ["src/**/*.ts", "src/**/*.d.ts", "src/**/*.tsx", "src/**/*.vue"],
- "references": [{ "path": "./tsconfig.node.json" }]
- }
复制代码
六.配置vue-router
推荐一个很好的插件nprogress【进度条】
- yarn add @types/nprogress nprogress -D
复制代码 main.ts引入router
- // main.ts
- import { createApp } from 'vue'
- import './style.css'
- import App from './App.vue'
- import router from "./router";
- const app = createApp(App as any);
- app.use(router)
- app.mount('#app')
复制代码 src下创建router文件夹,项目往往须要模块化,以是代码只管不要杂糅在一起
- /router/index.ts
- import { createRouter, createWebHashHistory, RouteRecordRaw } from "vue-router";
- import NProgress from "nprogress";
- import "nprogress/nprogress.css";
- const modules: any = import.meta.glob("./modules/**/*.ts", { eager: true });
- const routes: Array<RouteRecordRaw> = [];
- for (const key in modules) {
- routes.push(...modules[key].default);
- }
- const router = createRouter({
- history: createWebHashHistory(), // history 模式则使用 createWebHistory()
- routes,
- });
- router.beforeEach(async (_to, _from, next) => {
- NProgress.start();
- next();
- });
- router.afterEach((_to) => {
- NProgress.done();
- });
- export default router;
- /router/typings.d.ts 路由meta格式受控
- /router/typing.d.ts
- import "vue-router";
- declare module "vue-router" {
- interface RouteMeta {
- // options
- title?: string;
- // every route must declare
- show?: boolean; //
- }
- }
复制代码 然后就是test下随便创建一个路由,对应的,views下创建相应的vue文件,App.vue给上router-view
test/index.ts
app.vue
test/index.vue
查看页面
页面正确表现,路由摆设成功!
七.配置css预处理惩罚:less
- yarn add less less-loader -D
复制代码 为了配置全局的less样式文件,同时引入fs模块
进入项目根目次的配置文件
位置:vite.config.ts -- css
- // vite.config.ts
- import vue from "@vitejs/plugin-vue";
- import { resolve } from "path";
- import fs from 'fs'
- function pathResolve(dir: string) {
- return resolve(process.cwd(), ".", dir);
- }
- // https://vitejs.dev/config/
- export default () => {
- const lessResources: Array<String> = []
- fs.readdirSync('src/assets/styles').map((dirname) => {
- if (fs.statSync(`src/assets/styles/${dirname}`).isFile()) {
- lessResources.push(`@import "src/assets/styles/${dirname}";`)
- }
- })
- return {
- ......,
- // css
- css: {
- preprocessorOptions: {
- less: {
- charset: false,
- additionalData: lessResources.join(''),
- modifyVars: {
- 'primary-color': '#0080FF',
- 'link-color': '#0080FF',
- 'border-radius-base': '4px',
- },
- javascriptEnabled: true,
- },
- },
- },
- };
- };
复制代码
这里配置的公共less文件路径为src/assets/styles,创建styles文件夹和index.less文件
进入index.less声明全局样式,测试less配置是否成功
进入test/index.vue利用声明
查看页面
盒子背景颜色改变,less及全局less配置成功!
八.配置svg
- yarn add vite-plugin-svg-icons -D
- yarn add fast-glob -D
复制代码- // vite.config.ts
- import vue from "@vitejs/plugin-vue";
- import { createSvgIconsPlugin } from "vite-plugin-svg-icons";
- import path from "path";
复制代码- // https://vitejs.dev/config/
- export default () => {
- return {
- ......,
- plugins: [
- vue(),
- createSvgIconsPlugin({
- // 指定需要缓存的图标文件夹
- iconDirs: [path.resolve(process.cwd(), "src/assets/icons")],
- // 指定symbolId格式
- symbolId: "icon-[dir]-[name]",
- }),
- ],
- };
- };
复制代码 根据config配置创建存放svg的目次文件,并创建SvgIcon组件
SvgIcon组件
- // SvgIcon/index.vue
- <template>
- <svg aria-hidden="true" class="svg-icon">
- <use :xlink:href="symbolId" :fill="color" />
- </svg>
- </template>
- <script lang="ts" setup>
- import { computed } from "vue";
- const props = defineProps({
- prefix: {
- type: String,
- default: "icon",
- },
- name: {
- type: String,
- required: true,
- },
- color: {
- type: String,
- default: "#333",
- },
- });
- const symbolId = computed(() => `#${props.prefix}-${props.name}`);
- </script>
- <style lang="less" scoped>
- .svg-icon {
- width: 1em;
- height: 1em;
- fill: v-bind(color);
- vertical-align: middle;
- color: v-bind(color);
- }
- </style>
复制代码 在main.ts中注册SvgIcon为全局组件
- // main.ts
- import { createApp } from 'vue'
- import './style.css'
- import "virtual:svg-icons-register";
- import SvgIcon from "@/components/SvgIcon/index.vue";
- import App from './App.vue'
- import router from "./router";
- const app = createApp(App as any);
- app.use(router)
- app.mount('#app')
- app.component("SvgIcon", SvgIcon);
复制代码 在test/index.vue中引入组件
- // test/index.vue
- <svg-icon name="test-vue" />
复制代码 查看页面,测试是否成功
页面表现svg图标,svg组件配置成功!
九.配置pinia
- pinia: 类似vuex的仓库
- pinia-use-persist: 持久加密缓存pinia数据
复制代码- yarn add pinia pinia-use-persist -S
复制代码 main.ts中引入pinia
- // main.ts
- import { createApp } from 'vue'
- import { createPinia } from 'pinia'
- import { usePersist } from 'pinia-use-persist'
- import App from './App.vue'
- const app = createApp(App as any);
- const pinia = createPinia()
- pinia.use(usePersist)
- app.use(pinia)
复制代码 src下创建store目次存放相关文件
/store/modules下存放项目差异模块须要通过pinia通信的数据,冒充项目有一个test模块,存放了一个数据number
- // store/modules/test/index.ts
- import { defineStore } from "pinia";
- interface stateType {
- number: number;
- }
- const useTestStore = defineStore("user", {
- state: (): stateType => ({
- number: 0,
- }),
- getters: {},
- actions: {
- setNumber(number: number): void {
- this.number = number;
- },
- },
- persist: {
- enabled: true,
- encryptionKey: "vueTest",
- },
- });
- export { useTestStore };
复制代码 store/index.ts引入各模块
- // store/index.ts
- import { createPinia } from "pinia";
- import { useTestStore } from "./modules/test";
- const pinia = createPinia();
- export { useTestStore };
- export default pinia;
复制代码 回到test/index.vue,测试pinia配置是否成功
- // test/index.vue
- <template>
- <!-- 测试pinia -->
- <button @click="number += 1">{{ number }}</button>
- </div>
- </template>
- <script setup lang="ts">
- import { computed } from 'vue'
- import { useTestStore } from '@/store'
- const store = useTestStore()
- const number = computed<number>({
- get() {
- return store.number
- },
- set(value) {
- store.setNumber(value)
- },
- })
- </script>
复制代码 点击按钮,革新后查看页面是否变革
页面数据没有初始化,pinia配置成功!
十.配置vant ui
vant ui:https://vant-contrib.gitee.io/vant/v4/#/zh-CN/home
这里再推荐一个插件,unplugin-vue-components【自动引入】,引入ui可以省去很多贫苦
- yarn add unplugin-vue-components -D
复制代码 vite.config.ts中引入vant ui
- // vite.config.ts
- import vue from '@vitejs/plugin-vue';
- import Components from 'unplugin-vue-components/vite';
- import { VantResolver } from 'unplugin-vue-components/resolvers';
- export default {
- plugins: [
- vue(),
- Components({
- resolvers: [VantResolver()],
- }),
- ],
- };
复制代码 回到test/index.vue测试vant ui引入是否成功
- // test/index.vue
- <!-- 测试vant ui -->
- <div>
- <van-button type="primary">vant button</van-button>
- </div>
复制代码 革新页面查看
按钮有样式,vant ui引入成功!
但是官方描述:Vant 中有个别组件是以函数的形式提供的,包括 Toast,Dialog,Notify 和 ImagePreview 组件。在利用函数组件时,unplugin-vue-components 无法自动引入对应的样式,因此须要手动引入样式。
以是,这几个组件须要利用的话须要在main.ts中引入样式
- // main.ts
- // Toast
- import 'vant/es/toast/style';
- // Dialog
- import 'vant/es/dialog/style';
- // Notify
- import 'vant/es/notify/style';
- // ImagePreview
- import 'vant/es/image-preview/style';
复制代码 回到test/index.vue测试,示例toast
- // test/index.vue
- import { Toast } from 'vant'
- Toast('使用vant')
复制代码 查看页面
toast有样式,vant ui引入成功!
但是,利用vant ui多是移动端,以是还要做移动端做以下适配
参考: https://vant-contrib.gitee.io/vant/v4/#/zh-CN/advanced-usage
1.适配安全距离
根据vant ui提供,在根文件index.html修改
- // index.html
- <!-- 在 head 标签中添加 meta 标签,并设置 viewport-fit=cover 值 -->
- <meta name="viewport"
- content="width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, viewport-fit=cover" />
复制代码 2.Viewport 布局
postcss-px-to-viewport-8-plugin:postcss-px-to-viewport-8-plugin 是一款 PostCSS 插件,用于将 px 单元转化为 vw/vh 单元。
- yarn add postcss-px-to-viewport-8-plugin -D
复制代码 vite.config.ts中更改配置
- // vite.config.ts
- import pxtovw from 'postcss-px-to-viewport-8-plugin'
- const loder_pxtovw = pxtovw({
- //这里是设计稿宽度 自己修改
- viewportWidth: 375,
- viewportUnit: 'vw'
- })
- export default defineConfig({
- ......,
- css: {
- postcss: {
- plugins: [loder_pxtovw]
- }
- }
- })
复制代码 创建一个types/index.d.ts,用于处理惩罚包括postcss-px-to-viewport-8-plugin一类的没有声明文件的依赖
- // src/types/index.d.ts
- declare module "postcss-px-to-viewport-8-plugin"
复制代码 革新页面,F12查看样式
px已被转换,vant ui 及 移动端配置成功!
十一.配置axios
tsconfig.json:types里加上"vite/client"
- // tsconfig.json
- {
- "compilerOptions": {
- ......,
- "types": ["vite/client", "vite-plugin-svg-icons/client"]
- },
- "include": [
- "src/**/*.ts",
- "src/**/*.d.ts",
- "src/**/*.tsx",
- "src/**/*.vue",
- "*.ts",
- ],
- "exclude": ["node_modules", "dist"],
- "references": [{ "path": "./tsconfig.node.json" }]
- }
复制代码 src下创建axios哀求文件
创建axios
- // utils/http/axios/index.ts
- import axios, {
- AxiosInstance,
- AxiosRequestConfig,
- AxiosResponse,
- AxiosError,
- } from "axios";
- import { IResponse } from "./type";
- // 如果请求超过 `timeout` 的时间,请求将被中断
- axios.defaults.timeout = 5000;
- const axiosInstance: AxiosInstance = axios.create({
- baseURL: import.meta.env.VITE_APP_API_BASEURL + "",
- });
- // axios实例拦截请求
- axiosInstance.interceptors.request.use(
- (config: AxiosRequestConfig) => {
- // 配置headers
- config.headers = {
- ...config.headers,
- };
- return config;
- },
- (error: any) => {
- return Promise.reject(error);
- }
- );
- // axios实例拦截响应
- axiosInstance.interceptors.response.use(
- // 请求成功
- (response: AxiosResponse) => {
- return response;
- },
- // 请求失败
- (error: AxiosError) => {
- const { response } = error;
- console.error(response, "response error");
- if (response) {
- return Promise.reject(response.data);
- }
- }
- );
- const request = <T = any>(config: AxiosRequestConfig): Promise<T> => {
- const conf = config;
- return new Promise((resolve) => {
- axiosInstance
- .request<any, AxiosResponse<IResponse>>(conf)
- .then((res: AxiosResponse<IResponse>) => {
- const {
- data: { result },
- } = res;
- resolve(result as T);
- });
- });
- };
- export function get<T = any>(config: AxiosRequestConfig): Promise<T> {
- return request({ ...config, method: "GET" });
- }
- export function post<T = any>(config: AxiosRequestConfig): Promise<T> {
- return request({ ...config, method: "POST" });
- }
- export default request;
- export type { AxiosInstance, AxiosResponse };
- // utils/http/axios/type.ts
- export interface RequestOptions {
- // Whether to process the request result
- isTransformResponse?: boolean;
- }
- // 返回res.data的interface
- export interface IResponse<T = any> {
- code: number | string;
- result: T;
- data: T;
- message: string;
- status: string | number;
- }
复制代码 根目次创建.env.development配置开发哀求地点
- // .env.development
- # 开发环境
- VITE_APP_API_BASEURL = 你的请求地址
- NODE_ENV = development
- vite.config.ts配置server
- // vite.config.ts
- server: {
- hmr: { overlay: false }, // 禁用或配置 HMR 连接 设置 server.hmr.overlay 为 false 可以禁用服务器错误遮罩层
- // 服务配置
- port: 3030, // 类型: number 指定服务器端口;
- open: false, // 类型: boolean | string在服务器启动时自动在浏览器中打开应用程序;
- cors: false, // 类型: boolean | CorsOptions 为开发服务器配置 CORS。默认启用并允许任何源
- host: "0.0.0.0", // IP配置,支持从IP启动
- ["/api"]: {
- target: process.env.VITE_APP_API_BASEURL,
- changeOrigin: true,
- rewrite: (path: string) => path.replace(new RegExp("^/api"), ""),
- },
- },
复制代码 创建api存放目次
创建一个api
- // api/test/index.ts
- import { post } from "@/utils/http/axios";
- import { IResponse } from "@/utils/http/axios/type";
- export interface LoginData {
- username?: string;
- password?: string;
- }
- enum URL {
- login = "/api/user_center/testLogin",
- }
- /**
- * @description: 用户登录
- * @params {LoginData} params
- * @return {Promise}
- */
- const login = async (data: LoginData) =>
- post<IResponse>({ url: URL.login, data });
- export { login };
复制代码 回到test/index.vue调用api测试axios
- // test/index.vue
- <script setup lang="ts">
- import { login } from '@/api/test'
- login({})
- </script>
复制代码 回到页面,查看network
接口哀求成功,axios配置成功!
最后,配置一下打包
- // vite.config.ts
- import { UserConfig, ConfigEnv, loadEnv } from "vite";
- // https://vitejs.dev/config/
- export default ({ command, mode }: ConfigEnv): UserConfig => {
- const env = loadEnv(mode, __dirname);
- return {
- base: env.NODE_ENV === "development" ? "/" : "./",
- build: {
- outDir: "dist",
- assetsDir: "assets", //指定静态资源存放路径
- sourcemap: false, //是否构建source map 文件
- },
- };
- };
复制代码 启动dist,没问题!
结语:
项目到此主体功能就已经配置完毕了,细节之处大家多多查看官网和众多网友的分享
项目另有很多不美满甚至错误的地方,踩坑还会继续,后续有时间还会继续优化,现实利用中另有很多地方须要改进
项目同步git:https://gitee.com/lixin_ajax/vue3-vite-ts-pinia-vant-less.git
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |