mirror of
https://github.com/sunniejs/vue-h5-template.git
synced 2026-04-29 18:34:09 +08:00
docs: update docs
This commit is contained in:
parent
235386120f
commit
5b32fedd9a
31
docs/.vitepress/cache/deps/_metadata.json
vendored
31
docs/.vitepress/cache/deps/_metadata.json
vendored
@ -1,31 +0,0 @@
|
|||||||
{
|
|
||||||
"hash": "239dbc0d",
|
|
||||||
"configHash": "0cbf0876",
|
|
||||||
"lockfileHash": "05441bb6",
|
|
||||||
"browserHash": "dec8ef8e",
|
|
||||||
"optimized": {
|
|
||||||
"vue": {
|
|
||||||
"src": "../../../../node_modules/vue/dist/vue.runtime.esm-bundler.js",
|
|
||||||
"file": "vue.js",
|
|
||||||
"fileHash": "c8a520fe",
|
|
||||||
"needsInterop": false
|
|
||||||
},
|
|
||||||
"vitepress > @vue/devtools-api": {
|
|
||||||
"src": "../../../../node_modules/@vue/devtools-api/dist/index.js",
|
|
||||||
"file": "vitepress___@vue_devtools-api.js",
|
|
||||||
"fileHash": "b3eaab79",
|
|
||||||
"needsInterop": false
|
|
||||||
},
|
|
||||||
"vitepress > @vueuse/core": {
|
|
||||||
"src": "../../../../node_modules/@vueuse/core/index.mjs",
|
|
||||||
"file": "vitepress___@vueuse_core.js",
|
|
||||||
"fileHash": "e7d34837",
|
|
||||||
"needsInterop": false
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"chunks": {
|
|
||||||
"chunk-RMNUDMGF": {
|
|
||||||
"file": "chunk-RMNUDMGF.js"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
7
docs/.vitepress/cache/deps_temp_0f62c440/chunk-DKDEFF44.js.map
vendored
Normal file
7
docs/.vitepress/cache/deps_temp_0f62c440/chunk-DKDEFF44.js.map
vendored
Normal file
File diff suppressed because one or more lines are too long
@ -1,4 +1,4 @@
|
|||||||
// node_modules/@vue/devtools-shared/dist/index.js
|
// node_modules/.pnpm/@vue+devtools-shared@7.7.7/node_modules/@vue/devtools-shared/dist/index.js
|
||||||
var __create = Object.create;
|
var __create = Object.create;
|
||||||
var __defProp = Object.defineProperty;
|
var __defProp = Object.defineProperty;
|
||||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||||
@ -258,7 +258,7 @@ function isUrlString(str) {
|
|||||||
}
|
}
|
||||||
var deepClone = (0, import_rfdc.default)({ circles: true });
|
var deepClone = (0, import_rfdc.default)({ circles: true });
|
||||||
|
|
||||||
// node_modules/perfect-debounce/dist/index.mjs
|
// node_modules/.pnpm/perfect-debounce@1.0.0/node_modules/perfect-debounce/dist/index.mjs
|
||||||
var DEBOUNCE_DEFAULTS = {
|
var DEBOUNCE_DEFAULTS = {
|
||||||
trailing: true
|
trailing: true
|
||||||
};
|
};
|
||||||
@ -315,7 +315,7 @@ async function _applyPromised(fn, _this, args) {
|
|||||||
return await fn.apply(_this, args);
|
return await fn.apply(_this, args);
|
||||||
}
|
}
|
||||||
|
|
||||||
// node_modules/hookable/dist/index.mjs
|
// node_modules/.pnpm/hookable@5.5.3/node_modules/hookable/dist/index.mjs
|
||||||
function flatHooks(configHooks, hooks2 = {}, parentName) {
|
function flatHooks(configHooks, hooks2 = {}, parentName) {
|
||||||
for (const key in configHooks) {
|
for (const key in configHooks) {
|
||||||
const subHook = configHooks[key];
|
const subHook = configHooks[key];
|
||||||
@ -520,11 +520,11 @@ function createHooks() {
|
|||||||
return new Hookable();
|
return new Hookable();
|
||||||
}
|
}
|
||||||
|
|
||||||
// node_modules/birpc/dist/index.mjs
|
// node_modules/.pnpm/birpc@2.5.0/node_modules/birpc/dist/index.mjs
|
||||||
var { clearTimeout: clearTimeout2, setTimeout: setTimeout2 } = globalThis;
|
var { clearTimeout: clearTimeout2, setTimeout: setTimeout2 } = globalThis;
|
||||||
var random = Math.random.bind(Math);
|
var random = Math.random.bind(Math);
|
||||||
|
|
||||||
// node_modules/@vue/devtools-kit/dist/index.js
|
// node_modules/.pnpm/@vue+devtools-kit@7.7.7/node_modules/@vue/devtools-kit/dist/index.js
|
||||||
var __create2 = Object.create;
|
var __create2 = Object.create;
|
||||||
var __defProp2 = Object.defineProperty;
|
var __defProp2 = Object.defineProperty;
|
||||||
var __getOwnPropDesc2 = Object.getOwnPropertyDescriptor;
|
var __getOwnPropDesc2 = Object.getOwnPropertyDescriptor;
|
||||||
File diff suppressed because one or more lines are too long
@ -35,9 +35,9 @@ import {
|
|||||||
unref,
|
unref,
|
||||||
watch,
|
watch,
|
||||||
watchEffect
|
watchEffect
|
||||||
} from "./chunk-RMNUDMGF.js";
|
} from "./chunk-DKDEFF44.js";
|
||||||
|
|
||||||
// node_modules/@vueuse/shared/index.mjs
|
// node_modules/.pnpm/@vueuse+shared@12.8.2/node_modules/@vueuse/shared/index.mjs
|
||||||
function computedEager(fn, options) {
|
function computedEager(fn, options) {
|
||||||
var _a;
|
var _a;
|
||||||
const result = shallowRef();
|
const result = shallowRef();
|
||||||
@ -1569,7 +1569,7 @@ function whenever(source, cb, options) {
|
|||||||
return stop;
|
return stop;
|
||||||
}
|
}
|
||||||
|
|
||||||
// node_modules/@vueuse/core/index.mjs
|
// node_modules/.pnpm/@vueuse+core@12.8.2/node_modules/@vueuse/core/index.mjs
|
||||||
function computedAsync(evaluationCallback, initialState, optionsOrRef) {
|
function computedAsync(evaluationCallback, initialState, optionsOrRef) {
|
||||||
let options;
|
let options;
|
||||||
if (isRef(optionsOrRef)) {
|
if (isRef(optionsOrRef)) {
|
||||||
File diff suppressed because one or more lines are too long
@ -2,7 +2,10 @@ import {
|
|||||||
BaseTransition,
|
BaseTransition,
|
||||||
BaseTransitionPropsValidators,
|
BaseTransitionPropsValidators,
|
||||||
Comment,
|
Comment,
|
||||||
|
DeprecationTypes,
|
||||||
EffectScope,
|
EffectScope,
|
||||||
|
ErrorCodes,
|
||||||
|
ErrorTypeStrings,
|
||||||
Fragment,
|
Fragment,
|
||||||
KeepAlive,
|
KeepAlive,
|
||||||
ReactiveEffect,
|
ReactiveEffect,
|
||||||
@ -10,8 +13,10 @@ import {
|
|||||||
Suspense,
|
Suspense,
|
||||||
Teleport,
|
Teleport,
|
||||||
Text,
|
Text,
|
||||||
|
TrackOpTypes,
|
||||||
Transition,
|
Transition,
|
||||||
TransitionGroup,
|
TransitionGroup,
|
||||||
|
TriggerOpTypes,
|
||||||
VueElement,
|
VueElement,
|
||||||
assertNumber,
|
assertNumber,
|
||||||
callWithAsyncErrorHandling,
|
callWithAsyncErrorHandling,
|
||||||
@ -51,12 +56,17 @@ import {
|
|||||||
effectScope,
|
effectScope,
|
||||||
getCurrentInstance,
|
getCurrentInstance,
|
||||||
getCurrentScope,
|
getCurrentScope,
|
||||||
|
getCurrentWatcher,
|
||||||
getTransitionRawChildren,
|
getTransitionRawChildren,
|
||||||
guardReactiveProps,
|
guardReactiveProps,
|
||||||
h,
|
h,
|
||||||
handleError,
|
handleError,
|
||||||
hasInjectionContext,
|
hasInjectionContext,
|
||||||
hydrate,
|
hydrate,
|
||||||
|
hydrateOnIdle,
|
||||||
|
hydrateOnInteraction,
|
||||||
|
hydrateOnMediaQuery,
|
||||||
|
hydrateOnVisible,
|
||||||
initCustomFormatter,
|
initCustomFormatter,
|
||||||
initDirectivesForSSR,
|
initDirectivesForSSR,
|
||||||
inject,
|
inject,
|
||||||
@ -89,6 +99,7 @@ import {
|
|||||||
onServerPrefetch,
|
onServerPrefetch,
|
||||||
onUnmounted,
|
onUnmounted,
|
||||||
onUpdated,
|
onUpdated,
|
||||||
|
onWatcherCleanup,
|
||||||
openBlock,
|
openBlock,
|
||||||
popScopeId,
|
popScopeId,
|
||||||
provide,
|
provide,
|
||||||
@ -129,9 +140,13 @@ import {
|
|||||||
useAttrs,
|
useAttrs,
|
||||||
useCssModule,
|
useCssModule,
|
||||||
useCssVars,
|
useCssVars,
|
||||||
|
useHost,
|
||||||
|
useId,
|
||||||
useModel,
|
useModel,
|
||||||
useSSRContext,
|
useSSRContext,
|
||||||
|
useShadowRoot,
|
||||||
useSlots,
|
useSlots,
|
||||||
|
useTemplateRef,
|
||||||
useTransitionState,
|
useTransitionState,
|
||||||
vModelCheckbox,
|
vModelCheckbox,
|
||||||
vModelDynamic,
|
vModelDynamic,
|
||||||
@ -153,12 +168,15 @@ import {
|
|||||||
withMemo,
|
withMemo,
|
||||||
withModifiers,
|
withModifiers,
|
||||||
withScopeId
|
withScopeId
|
||||||
} from "./chunk-RMNUDMGF.js";
|
} from "./chunk-DKDEFF44.js";
|
||||||
export {
|
export {
|
||||||
BaseTransition,
|
BaseTransition,
|
||||||
BaseTransitionPropsValidators,
|
BaseTransitionPropsValidators,
|
||||||
Comment,
|
Comment,
|
||||||
|
DeprecationTypes,
|
||||||
EffectScope,
|
EffectScope,
|
||||||
|
ErrorCodes,
|
||||||
|
ErrorTypeStrings,
|
||||||
Fragment,
|
Fragment,
|
||||||
KeepAlive,
|
KeepAlive,
|
||||||
ReactiveEffect,
|
ReactiveEffect,
|
||||||
@ -166,8 +184,10 @@ export {
|
|||||||
Suspense,
|
Suspense,
|
||||||
Teleport,
|
Teleport,
|
||||||
Text,
|
Text,
|
||||||
|
TrackOpTypes,
|
||||||
Transition,
|
Transition,
|
||||||
TransitionGroup,
|
TransitionGroup,
|
||||||
|
TriggerOpTypes,
|
||||||
VueElement,
|
VueElement,
|
||||||
assertNumber,
|
assertNumber,
|
||||||
callWithAsyncErrorHandling,
|
callWithAsyncErrorHandling,
|
||||||
@ -207,12 +227,17 @@ export {
|
|||||||
effectScope,
|
effectScope,
|
||||||
getCurrentInstance,
|
getCurrentInstance,
|
||||||
getCurrentScope,
|
getCurrentScope,
|
||||||
|
getCurrentWatcher,
|
||||||
getTransitionRawChildren,
|
getTransitionRawChildren,
|
||||||
guardReactiveProps,
|
guardReactiveProps,
|
||||||
h,
|
h,
|
||||||
handleError,
|
handleError,
|
||||||
hasInjectionContext,
|
hasInjectionContext,
|
||||||
hydrate,
|
hydrate,
|
||||||
|
hydrateOnIdle,
|
||||||
|
hydrateOnInteraction,
|
||||||
|
hydrateOnMediaQuery,
|
||||||
|
hydrateOnVisible,
|
||||||
initCustomFormatter,
|
initCustomFormatter,
|
||||||
initDirectivesForSSR,
|
initDirectivesForSSR,
|
||||||
inject,
|
inject,
|
||||||
@ -245,6 +270,7 @@ export {
|
|||||||
onServerPrefetch,
|
onServerPrefetch,
|
||||||
onUnmounted,
|
onUnmounted,
|
||||||
onUpdated,
|
onUpdated,
|
||||||
|
onWatcherCleanup,
|
||||||
openBlock,
|
openBlock,
|
||||||
popScopeId,
|
popScopeId,
|
||||||
provide,
|
provide,
|
||||||
@ -285,9 +311,13 @@ export {
|
|||||||
useAttrs,
|
useAttrs,
|
||||||
useCssModule,
|
useCssModule,
|
||||||
useCssVars,
|
useCssVars,
|
||||||
|
useHost,
|
||||||
|
useId,
|
||||||
useModel,
|
useModel,
|
||||||
useSSRContext,
|
useSSRContext,
|
||||||
|
useShadowRoot,
|
||||||
useSlots,
|
useSlots,
|
||||||
|
useTemplateRef,
|
||||||
useTransitionState,
|
useTransitionState,
|
||||||
vModelCheckbox,
|
vModelCheckbox,
|
||||||
vModelDynamic,
|
vModelDynamic,
|
||||||
@ -3,8 +3,8 @@ export default {
|
|||||||
collapsible: true,
|
collapsible: true,
|
||||||
items: [
|
items: [
|
||||||
{ text: "启动项目", link: "/guide/vue3/start" },
|
{ text: "启动项目", link: "/guide/vue3/start" },
|
||||||
{ text: "vite.config.ts 基础配置", link: "/guide/vue3/base" },
|
{ text: "vite.config.mts 基础配置", link: "/guide/vue3/base" },
|
||||||
{ text: "vite插件集成", link: "/guide/vue3/vite" },
|
{ text: "Vite 插件集成", link: "/guide/vue3/vite" },
|
||||||
{ text: "多环境变量", link: "/guide/vue3/env" },
|
{ text: "多环境变量", link: "/guide/vue3/env" },
|
||||||
{ text: "viewport 适配方案", link: "/guide/vue3/viewport" },
|
{ text: "viewport 适配方案", link: "/guide/vue3/viewport" },
|
||||||
{ text: "UI组件库", link: "/guide/vue3/ui" },
|
{ text: "UI组件库", link: "/guide/vue3/ui" },
|
||||||
|
|||||||
@ -3,7 +3,6 @@
|
|||||||
欢迎有意愿参与到开源的朋友,加入到本文档的编写,书写文档不仅是教会别人知识,更是用自己的表达方式概括自己所学习知识的一种方式,这对个人来说是不可多得的成长机会。
|
欢迎有意愿参与到开源的朋友,加入到本文档的编写,书写文档不仅是教会别人知识,更是用自己的表达方式概括自己所学习知识的一种方式,这对个人来说是不可多得的成长机会。
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
|
|
||||||
# 拉取项目
|
# 拉取项目
|
||||||
git clone https://github.com/sunniejs/vue-h5-template
|
git clone https://github.com/sunniejs/vue-h5-template
|
||||||
|
|
||||||
@ -11,9 +10,11 @@ git clone https://github.com/sunniejs/vue-h5-template
|
|||||||
git checkout -b docs origin/docs
|
git checkout -b docs origin/docs
|
||||||
|
|
||||||
# 安装依赖
|
# 安装依赖
|
||||||
yarn install
|
pnpm install
|
||||||
|
|
||||||
# 启动项目
|
# 启动项目
|
||||||
yarn start
|
pnpm start
|
||||||
|
|
||||||
|
# 打包
|
||||||
|
pnpm build
|
||||||
```
|
```
|
||||||
|
|||||||
@ -1,12 +1,12 @@
|
|||||||
# 快速上手
|
# 快速上手
|
||||||
|
|
||||||
## node 版本要求
|
## Node 版本要求
|
||||||
|
|
||||||
推荐 20.19.0+以上的版本,毕竟 2025 年了,别掐着 16+的版本了,你也可以使用[nvm](https://github.com/nvm-sh/nvm)或[nvm-windows](https://github.com/coreybutler/nvm-windows)在同一台电脑上管理多个 node 版本。
|
推荐 Node.js 20.10.0+ 以上的版本,你可以使用 [nvm](https://github.com/nvm-sh/nvm) 或 [nvm-windows](https://github.com/coreybutler/nvm-windows) 在同一台电脑上管理多个 Node 版本。
|
||||||
|
|
||||||
## 包管理器
|
## 包管理器
|
||||||
|
|
||||||
尽量使用 yarn 或者 pnpm,本项目仅保证在 yarn 或 pnpm 下正确运行,npm 涉及到网络环境等各种情况的限制不做过多考虑。
|
推荐使用 pnpm(>= 9.12.0),本项目仅保证在 pnpm 下正确运行。
|
||||||
|
|
||||||
## 启动项目
|
## 启动项目
|
||||||
|
|
||||||
|
|||||||
@ -1,67 +1,123 @@
|
|||||||
# axios 封装及接口管理
|
# axios 封装及接口管理
|
||||||
|
|
||||||
`utils/request.js` 封装 axios , 开发者需要根据后台接口做修改。
|
`utils/request/index.ts` 封装 axios,开发者需要根据后台接口做修改。
|
||||||
|
|
||||||
- `service.interceptors.request.use` 里可以设置请求头,比如设置 `token`
|
- `service.interceptors.request.use` 里可以设置请求头,比如设置 `token`
|
||||||
- `config.hideloading` 是在 api 文件夹下的接口参数里设置,下文会讲
|
|
||||||
- `service.interceptors.response.use` 里可以对接口返回数据处理,比如 401 删除本地信息,重新登录
|
- `service.interceptors.response.use` 里可以对接口返回数据处理,比如 401 删除本地信息,重新登录
|
||||||
|
|
||||||
```javascript
|
## Axios 封装
|
||||||
|
|
||||||
|
```typescript
|
||||||
import axios from "axios";
|
import axios from "axios";
|
||||||
import store from "@/store";
|
import type {
|
||||||
import { Toast } from "vant";
|
AxiosError,
|
||||||
// 根据环境不同引入不同api地址
|
AxiosInstance,
|
||||||
import { baseApi } from "@/config";
|
AxiosRequestConfig,
|
||||||
// create an axios instance
|
AxiosResponse,
|
||||||
const service = axios.create({
|
InternalAxiosRequestConfig,
|
||||||
baseURL: baseApi, // url = base api url + request url
|
} from "axios";
|
||||||
withCredentials: true, // send cookies when cross-domain requests
|
import { showToast } from "vant";
|
||||||
timeout: 5000, // request timeout
|
|
||||||
|
const service: AxiosInstance = axios.create({
|
||||||
|
baseURL: import.meta.env.VITE_API_BASE_URL || "",
|
||||||
|
withCredentials: false,
|
||||||
|
timeout: 10000,
|
||||||
});
|
});
|
||||||
|
|
||||||
// request 拦截器 request interceptor
|
|
||||||
service.interceptors.request.use(
|
service.interceptors.request.use(
|
||||||
(config) => {
|
(config: InternalAxiosRequestConfig) => {
|
||||||
// 不传递默认开启loading
|
|
||||||
if (!config.hideloading) {
|
|
||||||
// loading
|
|
||||||
Toast.loading({
|
|
||||||
forbidClick: true,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
if (store.getters.token) {
|
|
||||||
config.headers["X-Token"] = "";
|
|
||||||
}
|
|
||||||
return config;
|
return config;
|
||||||
},
|
},
|
||||||
(error) => {
|
(error: AxiosError) => {
|
||||||
// do something with request error
|
|
||||||
console.log(error); // for debug
|
|
||||||
return Promise.reject(error);
|
return Promise.reject(error);
|
||||||
}
|
},
|
||||||
);
|
);
|
||||||
// respone拦截器
|
|
||||||
service.interceptors.response.use(
|
service.interceptors.response.use(
|
||||||
(response) => {
|
(response: AxiosResponse) => {
|
||||||
Toast.clear();
|
|
||||||
const res = response.data;
|
const res = response.data;
|
||||||
if (res.status && res.status !== 200) {
|
if (res.code !== 200) {
|
||||||
// 登录超时,重新登录
|
showToast(res.msg);
|
||||||
if (res.status === 401) {
|
return Promise.reject(res.msg || "Error");
|
||||||
store.dispatch("FedLogOut").then(() => {
|
|
||||||
location.reload();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
return Promise.reject(res || "error");
|
|
||||||
} else {
|
} else {
|
||||||
return Promise.resolve(res);
|
return res.data;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
(error) => {
|
(error: AxiosError) => {
|
||||||
Toast.clear();
|
showToast(error.message);
|
||||||
console.log("err" + error); // for debug
|
return Promise.reject(error.message);
|
||||||
return Promise.reject(error);
|
},
|
||||||
}
|
|
||||||
);
|
);
|
||||||
|
|
||||||
|
export const http = {
|
||||||
|
get<T = any>(url: string, config?: AxiosRequestConfig): Promise<T> {
|
||||||
|
return service.get(url, config);
|
||||||
|
},
|
||||||
|
post<T = any>(
|
||||||
|
url: string,
|
||||||
|
data?: object,
|
||||||
|
config?: AxiosRequestConfig,
|
||||||
|
): Promise<T> {
|
||||||
|
return service.post(url, data, config);
|
||||||
|
},
|
||||||
|
put<T = any>(
|
||||||
|
url: string,
|
||||||
|
data?: object,
|
||||||
|
config?: AxiosRequestConfig,
|
||||||
|
): Promise<T> {
|
||||||
|
return service.put(url, data, config);
|
||||||
|
},
|
||||||
|
delete<T = any>(url: string, config?: AxiosRequestConfig): Promise<T> {
|
||||||
|
return service.delete(url, config);
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
export default service;
|
export default service;
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## useFetchApi 封装
|
||||||
|
|
||||||
|
项目同时提供了基于 `@vueuse/core` 的 `createFetch` 封装,支持响应式的请求:
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
import { createFetch } from "@vueuse/core";
|
||||||
|
import { useCookies } from "@vueuse/integrations/useCookies";
|
||||||
|
import { showNotify } from "vant";
|
||||||
|
|
||||||
|
const useFetchApi = createFetch({
|
||||||
|
baseUrl: "",
|
||||||
|
options: {
|
||||||
|
async beforeFetch({ options }) {
|
||||||
|
const myToken =
|
||||||
|
useCookies().get(
|
||||||
|
(import.meta.env.VITE_TOKEN_KEY as string) || "Authorization",
|
||||||
|
) || "";
|
||||||
|
options.headers = {
|
||||||
|
...options.headers,
|
||||||
|
Authorization: `Bearer ${myToken}`,
|
||||||
|
};
|
||||||
|
return { options };
|
||||||
|
},
|
||||||
|
afterFetch(ctx) {
|
||||||
|
// 处理响应数据...
|
||||||
|
return ctx;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
export default useFetchApi;
|
||||||
|
```
|
||||||
|
|
||||||
|
## 接口管理
|
||||||
|
|
||||||
|
在 `src/api/index.ts` 中统一管理接口:
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
import { http } from "@/utils/request";
|
||||||
|
|
||||||
|
export function loginPassword() {
|
||||||
|
return http.post("/mock-api/login", {
|
||||||
|
data: { name: "123" },
|
||||||
|
});
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
# vite.config.ts 基础配置
|
# vite.config.mts 基础配置
|
||||||
|
|
||||||
如果你的 `Vue Router` 模式是 hash
|
如果你的 `Vue Router` 模式是 hash
|
||||||
|
|
||||||
@ -6,7 +6,7 @@
|
|||||||
base: './',
|
base: './',
|
||||||
```
|
```
|
||||||
|
|
||||||
如果你的 `Vue Router` 模式是 history 这里的 publicPath 和你的 `Vue Router` `base` **保持一致**
|
如果你的 `Vue Router` 模式是 history 这里的 base 和你的 `Vue Router` `base` **保持一致**
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
base: '/app/',
|
base: '/app/',
|
||||||
@ -46,10 +46,9 @@ export default function ({ command, mode }: ConfigEnv): UserConfig {
|
|||||||
css: {
|
css: {
|
||||||
preprocessorOptions: {
|
preprocessorOptions: {
|
||||||
scss: {
|
scss: {
|
||||||
quietDeps: true,
|
|
||||||
silenceDeprecations: ["legacy-js-api"],
|
|
||||||
// 配置 nutui 全局 scss 变量
|
// 配置 nutui 全局 scss 变量
|
||||||
additionalData: `@use "@nutui/nutui/dist/styles/variables.scss" as *; @use '@/styles/vant.scss' as *;`,
|
additionalData: `@use "@/styles/variable.scss" as *;@use "@nutui/nutui/dist/styles/variables.scss" as *;`,
|
||||||
|
quietDeps: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|||||||
@ -1,13 +1,48 @@
|
|||||||
`package.json` 里的 `scripts` 配置 `dev` `dev:test` `dev:prod` ,通过 `--mode xxx` 来执行不同环境
|
# 多环境变量
|
||||||
|
|
||||||
- 通过 `yarn dev` 启动本地环境参数 , 执行 `development`
|
`package.json` 里的 `scripts` 配置 `dev` `build`,通过 `--mode xxx` 来执行不同环境
|
||||||
- 通过 `yarn dev:test` 启动测试环境参数 , 执行 `test`
|
|
||||||
- 通过 `yarn dev:prod` 启动正式环境参数 , 执行 `prod`
|
|
||||||
|
|
||||||
```javascript
|
- 通过 `pnpm dev` 启动本地环境参数,执行 `development`
|
||||||
|
- 通过 `pnpm build` 打包正式环境参数,执行 `production`
|
||||||
|
|
||||||
|
```json
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "vite",
|
"dev": "vite",
|
||||||
"dev:test": "vite --mode test",
|
"build": "vite build"
|
||||||
"dev:prod": "vite --mode production",
|
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## 环境变量配置
|
||||||
|
|
||||||
|
项目中有三个环境变量文件:
|
||||||
|
|
||||||
|
- `.env.development` - 开发环境
|
||||||
|
- `.env.test` - 测试环境
|
||||||
|
- `.env.production` - 生产环境
|
||||||
|
|
||||||
|
可配置的变量:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 是否开启数据mock
|
||||||
|
VITE_USE_MOCK=true
|
||||||
|
|
||||||
|
# Token Key
|
||||||
|
VITE_TOKEN_KEY=Authorization
|
||||||
|
|
||||||
|
# 是否开启调试工具
|
||||||
|
VITE_USE_ERUDA=true
|
||||||
|
|
||||||
|
# 是否开启压缩
|
||||||
|
VITE_USE_COMPRESS=false
|
||||||
|
|
||||||
|
# 是否开启打包后生成报告
|
||||||
|
VITE_USE_REPORT=false
|
||||||
|
|
||||||
|
# 是否开启https
|
||||||
|
VITE_USE_HTTPS=false
|
||||||
|
|
||||||
|
# 是否开启PWA
|
||||||
|
VITE_USE_PWA=false
|
||||||
|
```
|
||||||
|
|
||||||
|
在代码中通过 `import.meta.env.VITE_XXX` 访问环境变量。
|
||||||
|
|||||||
@ -1,51 +1,96 @@
|
|||||||
<!--
|
|
||||||
* @Author: Vinton
|
|
||||||
* @Date: 2022-08-22 11:08:11
|
|
||||||
* @Description: file content
|
|
||||||
-->
|
|
||||||
# i18n 文本多语言解决方案
|
# i18n 文本多语言解决方案
|
||||||
|
|
||||||
```javascript
|
项目采用 `vue-i18n` 实现多语言,并支持按需懒加载语言包,提升首屏加载速度。
|
||||||
import { createI18n } from 'vue-i18n'; // 引入第三方最新的i18n注意版本
|
|
||||||
|
|
||||||
/**
|
## 目录结构
|
||||||
* @description: 加载当前配置的语言配置目录,随意添加
|
|
||||||
*/
|
|
||||||
export function loadLang() {
|
|
||||||
const modules: Record<string, any> = import.meta.glob('./lang/*.ts', { eager: true });
|
|
||||||
const langs: Record<string, any> = {};
|
|
||||||
|
|
||||||
for (const path in modules) {
|
```bash
|
||||||
const name = path.replace(/(\.\/lang\/|\.ts)/g, '');
|
├── locales
|
||||||
langs[name] = modules[path].lang;
|
│ ├── index.ts # i18n 配置和初始化
|
||||||
}
|
│ ├── lang-base.ts # 基础语言配置
|
||||||
return langs;
|
│ └── langs
|
||||||
}
|
│ ├── en-US
|
||||||
|
│ │ └── common.json
|
||||||
|
│ └── zh-CN
|
||||||
|
│ └── common.json
|
||||||
|
```
|
||||||
|
|
||||||
|
## 核心实现
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
import { createI18n } from "vue-i18n";
|
||||||
|
import type { App } from "vue";
|
||||||
|
|
||||||
|
const LOCALE_KEY = "lang";
|
||||||
|
const DEFAULT_LOCALE = "zh-CN";
|
||||||
|
|
||||||
|
// 扫描所有语言文件(懒加载)
|
||||||
|
const modules = import.meta.glob("./langs/**/*.json");
|
||||||
|
|
||||||
|
// i18n 实例(初始不加载 messages,按需加载)
|
||||||
export const i18n = createI18n({
|
export const i18n = createI18n({
|
||||||
// globalInjection: true,
|
legacy: false,
|
||||||
// legacy: false,
|
globalInjection: true,
|
||||||
locale: 'zh-cn', // 默认语言,当前这里的数据要跟配置的lang目录下面的文件名字前缀一致
|
locale: "",
|
||||||
fallbackLocale: 'zh-cn',
|
fallbackLocale: DEFAULT_LOCALE,
|
||||||
messages: loadLang(), // 记载当前引入的语言目录的处理过后的数据
|
messages: {},
|
||||||
});
|
});
|
||||||
|
|
||||||
/**
|
// 设置语言
|
||||||
* @description: 切换当前多语言
|
export async function setLang(locale?: string) {
|
||||||
*/
|
const target = locale || localStorage.getItem(LOCALE_KEY) || DEFAULT_LOCALE;
|
||||||
export function setLang(locale?: string) {
|
|
||||||
if (locale) {
|
if (!i18n.global.availableLocales.includes(target)) {
|
||||||
localStorage.setItem('lang', locale);
|
// 按需加载语言包
|
||||||
|
const loader = localeLoaders[target];
|
||||||
|
if (loader) {
|
||||||
|
const messages = await loader();
|
||||||
|
i18n.global.setLocaleMessage(target, messages);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
i18n.global.locale = locale || localStorage.getItem('lang') || '';
|
|
||||||
|
i18n.global.locale.value = target;
|
||||||
|
localStorage.setItem(LOCALE_KEY, target);
|
||||||
|
document.documentElement.lang = target;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 初始化(main.ts 调用)
|
||||||
|
export async function setupI18n(app: App) {
|
||||||
|
app.use(i18n);
|
||||||
|
await setLang();
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
# css图片解决方案
|
## 在组件中切换语言
|
||||||
|
|
||||||
目前在业务开发中,CSS 的样式多语言也会经常用到,可能一些图片的字体比较复杂,代码很难实现。或者我们为了减少多语言的配置,加快开发效率也会使用多语言的配置,目前这里提供 scss 的图片多语言的方案
|
```html
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { setLang } from "@/locales";
|
||||||
|
|
||||||
```css
|
const changeLang = (type: string) => {
|
||||||
|
setLang(type);
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<button @click="changeLang('zh-CN')">中文</button>
|
||||||
|
<button @click="changeLang('en-US')">English</button>
|
||||||
|
</template>
|
||||||
|
```
|
||||||
|
|
||||||
|
## 在模板中使用
|
||||||
|
|
||||||
|
```html
|
||||||
|
<template>
|
||||||
|
<div>{{ $t('common.title') }}</div>
|
||||||
|
</template>
|
||||||
|
```
|
||||||
|
|
||||||
|
# CSS 图片多语言方案
|
||||||
|
|
||||||
|
目前在业务开发中,CSS 的样式多语言也会经常用到。这里提供 scss 的图片多语言方案:
|
||||||
|
|
||||||
|
```scss
|
||||||
@mixin main-lang-bg($width, $height, $preUrl, $posUrl) {
|
@mixin main-lang-bg($width, $height, $preUrl, $posUrl) {
|
||||||
width: $width;
|
width: $width;
|
||||||
height: $height;
|
height: $height;
|
||||||
@ -53,37 +98,29 @@ export function setLang(locale?: string) {
|
|||||||
background-size: 100% 100%;
|
background-size: 100% 100%;
|
||||||
@include loop-lang-bg($preUrl, $posUrl);
|
@include loop-lang-bg($preUrl, $posUrl);
|
||||||
}
|
}
|
||||||
// 背景图多语言
|
|
||||||
@mixin loop-lang-bg($preUrl, $posUrl) {
|
@mixin loop-lang-bg($preUrl, $posUrl) {
|
||||||
$list: zh-cn, en-us; // 配置需要的多语言,根据项目来
|
$list: zh-CN, en-US;
|
||||||
@each $i in $list {
|
@each $i in $list {
|
||||||
&.#{$i} {
|
&.#{$i} {
|
||||||
background-image: url('#{$preUrl}/#{$i}/#{$posUrl}');
|
background-image: url("#{$preUrl}/#{$i}/#{$posUrl}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
## 定义图片的目录格式
|
|
||||||
```bash
|
|
||||||
├── button
|
|
||||||
│ ├── en-us
|
|
||||||
│ │ └── confirm.png
|
|
||||||
│ ├── zh-cn
|
|
||||||
│ │ └── confirm.png
|
|
||||||
```
|
|
||||||
|
|
||||||
## HTML的使用方式
|
## 使用方式
|
||||||
|
|
||||||
```html
|
```html
|
||||||
<template>
|
<template>
|
||||||
<div :class="['btn-confirm', i18n.global.locale]"></div>
|
<div :class="['btn-confirm', i18n.global.locale.value]"></div>
|
||||||
</template>
|
</template>
|
||||||
<script lang="ts" setup name="HomePage">
|
<script lang="ts" setup>
|
||||||
import { i18n } from '/@/i18n';
|
import { i18n } from "@/locales";
|
||||||
</script>
|
</script>
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
.btn-confirm {
|
.btn-confirm {
|
||||||
@include main-lang-bg(302px, 82px, '/@/assets/button', 'confirm.png');
|
@include main-lang-bg(302px, 82px, "@/assets/button", "confirm.png");
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
```
|
```
|
||||||
|
|||||||
@ -1,3 +1,18 @@
|
|||||||
# Eslint + Pettier + Stylelint 统一开发规范
|
# ESLint + Prettier + Stylelint 统一开发规范
|
||||||
|
|
||||||
根目录下的 `.eslintrc.js`、`.stylelint.config.js`、`.prettier.config.js` 内置了 lint 规则,帮助你规范地开发代码,有助于提高团队的代码质量和协作性,可以根据团队的规则进行修改
|
根目录下的 `eslint.config.mjs`、`stylelint.config.js`、`prettier.config.js` 内置了 lint 规则,帮助你规范地开发代码,有助于提高团队的代码质量和协作性,可以根据团队的规则进行修改。
|
||||||
|
|
||||||
|
项目使用 ESLint flat config(`eslint.config.mjs`),配合 `husky` + `lint-staged` 在 git commit 时自动执行代码检查。
|
||||||
|
|
||||||
|
## 常用命令
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# ESLint 检查并修复
|
||||||
|
pnpm lint:eslint
|
||||||
|
|
||||||
|
# Prettier 格式化
|
||||||
|
pnpm lint:prettier
|
||||||
|
|
||||||
|
# Stylelint 检查并修复
|
||||||
|
pnpm lint:stylelint
|
||||||
|
```
|
||||||
|
|||||||
@ -1,34 +1,30 @@
|
|||||||
<!--
|
|
||||||
* @Author: Vinton
|
|
||||||
* @Date: 2022-08-22 10:39:13
|
|
||||||
* @Description: file content
|
|
||||||
-->
|
|
||||||
# Pinia 状态管理
|
# Pinia 状态管理
|
||||||
|
|
||||||
下一代 vuex,使用极其方便,ts 兼容好
|
下一代 vuex,使用极其方便,ts 兼容好。项目使用 `pinia-plugin-persistedstate` 实现状态持久化。
|
||||||
|
|
||||||
目录结构
|
目录结构
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
├── store
|
├── store
|
||||||
│ ├── modules
|
│ ├── modules
|
||||||
│ │ └── user.js
|
│ │ └── user.ts
|
||||||
│ ├── index.js
|
│ ├── index.ts
|
||||||
```
|
```
|
||||||
目前pinia分为两种编程模式,Options API 和 Composition API,我们这边都会列举出来实现的业务逻辑效果是一样的,提供大家思路
|
|
||||||
|
|
||||||
### Options API:
|
### Options API(当前项目使用):
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
import { loginPassword } from "@/api";
|
||||||
|
import { defineStore } from "pinia";
|
||||||
|
|
||||||
```javascript
|
|
||||||
interface StoreUser {
|
interface StoreUser {
|
||||||
token: string;
|
token: string;
|
||||||
info: Record<any, any>;
|
info: Record<any, any>;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const useUserStore = defineStore({
|
export const useUserStore = defineStore("user", {
|
||||||
id: 'app-user',
|
|
||||||
state: (): StoreUser => ({
|
state: (): StoreUser => ({
|
||||||
token: token,
|
token: "",
|
||||||
info: {},
|
info: {},
|
||||||
}),
|
}),
|
||||||
getters: {
|
getters: {
|
||||||
@ -38,51 +34,63 @@ export const useUserStore = defineStore({
|
|||||||
},
|
},
|
||||||
actions: {
|
actions: {
|
||||||
setInfo(info: any) {
|
setInfo(info: any) {
|
||||||
this.info = info ? info : '';
|
this.info = info ?? "";
|
||||||
},
|
},
|
||||||
login() {
|
async login() {
|
||||||
return new Promise((resolve) => {
|
try {
|
||||||
const { data } = loginPassword();
|
const res = await loginPassword();
|
||||||
watch(data, () => {
|
this.setInfo(res);
|
||||||
this.setInfo(data.value);
|
this.token = res.token;
|
||||||
// useCookies().set(VITE_TOKEN_KEY as string, data.value.token);
|
return res;
|
||||||
resolve(data.value);
|
} catch (error) {
|
||||||
});
|
console.error("Login failed", error);
|
||||||
});
|
throw error;
|
||||||
|
}
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
persist: {
|
||||||
|
pick: ["token"],
|
||||||
|
storage: localStorage,
|
||||||
|
},
|
||||||
});
|
});
|
||||||
```
|
```
|
||||||
|
|
||||||
### Composition API:
|
### Composition API:
|
||||||
```javascript
|
|
||||||
export const useUserStore = defineStore('app-user', () => {
|
```typescript
|
||||||
const Token = ref(token);
|
export const useUserStore = defineStore(
|
||||||
const info = ref<Record<any, any>>({});
|
"user",
|
||||||
const setInfo = (info: any) => {
|
() => {
|
||||||
info.value = info ? info : '';
|
const token = ref("");
|
||||||
};
|
const info = ref<Record<any, any>>({});
|
||||||
const getUserInfo = () => {
|
|
||||||
return info || {};
|
const getUserInfo = () => info.value || {};
|
||||||
};
|
|
||||||
const login = () => {
|
const setInfo = (data: any) => {
|
||||||
return new Promise((resolve) => {
|
info.value = data ?? "";
|
||||||
const { data } = loginPassword();
|
};
|
||||||
watch(data, () => {
|
|
||||||
setInfo(data.value);
|
const login = async () => {
|
||||||
// useCookies().set(VITE_TOKEN_KEY as string, data.value.token);
|
try {
|
||||||
resolve(data.value);
|
const res = await loginPassword();
|
||||||
});
|
setInfo(res);
|
||||||
});
|
token.value = res.token;
|
||||||
};
|
return res;
|
||||||
return {
|
} catch (error) {
|
||||||
Token,
|
console.error("Login failed", error);
|
||||||
info,
|
throw error;
|
||||||
setInfo,
|
}
|
||||||
login,
|
};
|
||||||
getUserInfo,
|
|
||||||
};
|
return { token, info, getUserInfo, setInfo, login };
|
||||||
})
|
},
|
||||||
|
{
|
||||||
|
persist: {
|
||||||
|
pick: ["token"],
|
||||||
|
storage: localStorage,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
);
|
||||||
```
|
```
|
||||||
|
|
||||||
使用
|
使用
|
||||||
|
|||||||
@ -2,27 +2,57 @@
|
|||||||
|
|
||||||
本案例采用 `hash` 模式,开发者根据需求修改 `mode` `base`
|
本案例采用 `hash` 模式,开发者根据需求修改 `mode` `base`
|
||||||
|
|
||||||
**注意**:如果你使用了 `history` 模式, `vue.config.js` 中的 `publicPath` 要做对应的**修改**
|
**注意**:如果你使用了 `history` 模式, `vite.config.mts` 中的 `base` 要做对应的**修改**
|
||||||
|
|
||||||
前往: [vite.config.js 基础配置](#base)
|
前往: [vite.config.mts 基础配置](/guide/vue3/base)
|
||||||
|
|
||||||
```javascript
|
```typescript
|
||||||
import Vue from "vue";
|
import type { RouteRecordRaw } from "vue-router";
|
||||||
import { createRouter, createWebHistory, Router } from "vue-router";
|
|
||||||
|
|
||||||
Vue.use(Router);
|
export const routes: RouteRecordRaw[] = [
|
||||||
export const router = [
|
|
||||||
{
|
{
|
||||||
name: "root",
|
|
||||||
path: "/",
|
path: "/",
|
||||||
redirect: "/home",
|
redirect: "/home",
|
||||||
component: () => import("@/layout/basic/index.vue"),
|
component: () => import("@/layout/index.vue"),
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
path: "home",
|
||||||
|
component: () => import("@/views/home/index.vue"),
|
||||||
|
meta: {
|
||||||
|
title: "common.tabbar.home",
|
||||||
|
keepAlive: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
// ... 其他子路由
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "login",
|
||||||
|
path: "/login",
|
||||||
|
component: () => import("@/views/login/index.vue"),
|
||||||
|
meta: {
|
||||||
|
title: "",
|
||||||
|
keepAlive: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
// 匹配不到重定向到首页
|
||||||
|
{
|
||||||
|
path: "/:pathMatch(.*)",
|
||||||
|
redirect: "/home",
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
```
|
||||||
|
|
||||||
const router: Router = createRouter({
|
路由实例创建:
|
||||||
history: createWebHistory(),
|
|
||||||
routes: routes,
|
```typescript
|
||||||
|
import { createRouter, createWebHashHistory } from "vue-router";
|
||||||
|
import routes from "./routes";
|
||||||
|
|
||||||
|
const router = createRouter({
|
||||||
|
history: createWebHashHistory(),
|
||||||
|
routes,
|
||||||
|
scrollBehavior: () => ({ left: 0, top: 0 }),
|
||||||
});
|
});
|
||||||
|
|
||||||
export default router;
|
export default router;
|
||||||
|
|||||||
@ -1,16 +1,26 @@
|
|||||||
# 启动项目
|
# 启动项目
|
||||||
|
|
||||||
```bash
|
## 环境要求
|
||||||
|
|
||||||
|
- Node.js >= 20.10.0
|
||||||
|
- pnpm >= 9.12.0
|
||||||
|
|
||||||
|
```bash
|
||||||
# 拉取项目
|
# 拉取项目
|
||||||
git clone https://github.com/sunniejs/vue-h5-template
|
git clone https://github.com/sunniejs/vue-h5-template
|
||||||
|
|
||||||
|
# 进入项目目录
|
||||||
|
cd vue-h5-template
|
||||||
|
|
||||||
# 安装依赖
|
# 安装依赖
|
||||||
- pnpm install
|
pnpm install
|
||||||
- yarn install
|
|
||||||
|
|
||||||
# 启动项目
|
# 启动项目
|
||||||
- pnpm dev
|
pnpm dev
|
||||||
- yarn dev
|
|
||||||
|
|
||||||
|
# 打包
|
||||||
|
pnpm build
|
||||||
|
|
||||||
|
# 预览打包结果
|
||||||
|
pnpm preview
|
||||||
```
|
```
|
||||||
|
|||||||
@ -1,37 +1,32 @@
|
|||||||
# 多 UI 组件库供选择
|
# 多 UI 组件库供选择
|
||||||
|
|
||||||
Vite 构建工具,`使用 vite-plugin-style-import` 和 `unplugin-vue-components/vite` 实现按需引入。
|
使用 `unplugin-vue-components` 和 `unplugin-auto-import` 实现按需引入,无需手动注册组件。
|
||||||
|
|
||||||
## 安装插件
|
|
||||||
|
|
||||||
```bash
|
|
||||||
pnpm add unplugin-vue-components/vite -D
|
|
||||||
```
|
|
||||||
|
|
||||||
## 使用组件库
|
## 使用组件库
|
||||||
|
|
||||||
vant 、 varlet 和 nutUI 可以使用组件按需加载
|
Vant、Varlet 和 NutUI 三个组件库均已配置按需加载。
|
||||||
|
|
||||||
在`config/vite/plugins/component.ts`下
|
在 `build/vite/plugins/component.ts` 下配置:
|
||||||
|
|
||||||
```javascript
|
```typescript
|
||||||
import { VantResolver, VarletUIResolver } from 'unplugin-vue-components/resolvers';
|
import { VantResolver, VarletUIResolver } from 'unplugin-vue-components/resolvers';
|
||||||
import NutUIResolver from '@nutui/auto-import-resolver';
|
import NutUIResolver from '@nutui/auto-import-resolver';
|
||||||
...
|
|
||||||
|
// ...
|
||||||
resolvers: [VantResolver(), VarletUIResolver(), NutUIResolver()],
|
resolvers: [VantResolver(), VarletUIResolver(), NutUIResolver()],
|
||||||
...
|
// ...
|
||||||
```
|
```
|
||||||
|
|
||||||
## 不需要某个组件库
|
## 不需要某个组件库
|
||||||
|
|
||||||
只需删除对应的 resolvers 即可
|
只需删除对应的 resolvers 即可。
|
||||||
|
|
||||||
删除后需全局搜索删除不需要的组件,避免报错
|
删除后需全局搜索删除不需要的组件,避免报错。
|
||||||
|
|
||||||
## 参考文档
|
## 参考文档
|
||||||
|
|
||||||
- [nutUI](https://nutui.jd.com/#/zh-CN/component/button)
|
- [NutUI](https://nutui.jd.com/#/zh-CN/component/button)
|
||||||
|
|
||||||
- [vant](https://vant-contrib.gitee.io/vant/#/zh-CN)
|
- [Vant](https://vant-ui.github.io/vant/#/zh-CN)
|
||||||
|
|
||||||
- [varlet](https://varlet-varletjs.vercel.app/#/zh-CN/button)
|
- [Varlet](https://varlet.pages.dev/#/zh-CN/button)
|
||||||
|
|||||||
@ -1,17 +1,20 @@
|
|||||||
# vite
|
# Vite 插件集成
|
||||||
|
|
||||||
基于原生 ES 模块提供了丰富的内建功能,如速度快到惊人的模块热更新(HMR),使用 Rollup 打包你的代码,并且它是预配置的,可输出用于生产环境的高度优化过的静态资源。更多关于[vite](https://cn.vitejs.dev/guide/)
|
基于原生 ES 模块提供了丰富的内建功能,如速度快到惊人的模块热更新(HMR),使用 Rollup 打包你的代码,并且它是预配置的,可输出用于生产环境的高度优化过的静态资源。更多关于 [Vite](https://cn.vitejs.dev/guide/)
|
||||||
|
|
||||||
模版集成了如下的 vite 插件
|
模版集成了如下的 vite 插件(配置目录:`build/vite/plugins/`)
|
||||||
|
|
||||||
- unplugin-auto-import(按需加载,自动引入)
|
- unplugin-auto-import(按需加载,自动引入)
|
||||||
- unplugin-vue-components(按需加载,自动引入组件)
|
- unplugin-vue-components(按需加载,自动引入组件)
|
||||||
- vite-plugin-compression(开启.gz 压缩)
|
- vite-plugin-compression(开启 .gz 压缩)
|
||||||
- vite-plugin-eruda(控制台,方便移动端调试)
|
- @zhaojjiang/vite-plugin-eruda(控制台,方便移动端调试)
|
||||||
- vite-plugin-imagemin(图片压缩)
|
- vite-plugin-imagemin(图片压缩)
|
||||||
- vite-plugin-mock(引入 mockjs,本地模拟接口)
|
- vite-plugin-mock(引入 mockjs,本地模拟接口)
|
||||||
- vite-plugin-pages(动态生成路由)
|
- vite-plugin-pages(动态生成路由)
|
||||||
- vite-plugin-progress(构建显示进度条)
|
- vite-plugin-progress(构建显示进度条)
|
||||||
- vite-plugin-restart(监听配置文件修改自动重启 Vite)
|
- vite-plugin-restart(监听配置文件修改自动重启 Vite)
|
||||||
- vite-plugin-style-import(按需引入样式文件)
|
|
||||||
- vite-plugin-svg-icons(加载 SVG 文件,自动引入)
|
- vite-plugin-svg-icons(加载 SVG 文件,自动引入)
|
||||||
|
- vite-plugin-pwa(PWA 支持)
|
||||||
|
- vite-plugin-qrcode(开发时生成二维码,方便移动端调试)
|
||||||
|
- @vitejs/plugin-basic-ssl(本地 HTTPS 开发支持)
|
||||||
|
- rollup-plugin-visualizer(打包分析报告)
|
||||||
|
|||||||
92
types/auto-imports.d.ts
vendored
Normal file
92
types/auto-imports.d.ts
vendored
Normal file
@ -0,0 +1,92 @@
|
|||||||
|
/* eslint-disable */
|
||||||
|
/* prettier-ignore */
|
||||||
|
// @ts-nocheck
|
||||||
|
// noinspection JSUnusedGlobalSymbols
|
||||||
|
// Generated by unplugin-auto-import
|
||||||
|
// biome-ignore lint: disable
|
||||||
|
export {}
|
||||||
|
declare global {
|
||||||
|
const EffectScope: typeof import('vue').EffectScope
|
||||||
|
const Snackbar: typeof import('@varlet/ui').Snackbar
|
||||||
|
const acceptHMRUpdate: typeof import('pinia').acceptHMRUpdate
|
||||||
|
const computed: typeof import('vue').computed
|
||||||
|
const createApp: typeof import('vue').createApp
|
||||||
|
const createPinia: typeof import('pinia').createPinia
|
||||||
|
const customRef: typeof import('vue').customRef
|
||||||
|
const defineAsyncComponent: typeof import('vue').defineAsyncComponent
|
||||||
|
const defineComponent: typeof import('vue').defineComponent
|
||||||
|
const defineStore: typeof import('pinia').defineStore
|
||||||
|
const effectScope: typeof import('vue').effectScope
|
||||||
|
const getActivePinia: typeof import('pinia').getActivePinia
|
||||||
|
const getCurrentInstance: typeof import('vue').getCurrentInstance
|
||||||
|
const getCurrentScope: typeof import('vue').getCurrentScope
|
||||||
|
const getCurrentWatcher: typeof import('vue').getCurrentWatcher
|
||||||
|
const h: typeof import('vue').h
|
||||||
|
const inject: typeof import('vue').inject
|
||||||
|
const isProxy: typeof import('vue').isProxy
|
||||||
|
const isReactive: typeof import('vue').isReactive
|
||||||
|
const isReadonly: typeof import('vue').isReadonly
|
||||||
|
const isRef: typeof import('vue').isRef
|
||||||
|
const isShallow: typeof import('vue').isShallow
|
||||||
|
const mapActions: typeof import('pinia').mapActions
|
||||||
|
const mapGetters: typeof import('pinia').mapGetters
|
||||||
|
const mapState: typeof import('pinia').mapState
|
||||||
|
const mapStores: typeof import('pinia').mapStores
|
||||||
|
const mapWritableState: typeof import('pinia').mapWritableState
|
||||||
|
const markRaw: typeof import('vue').markRaw
|
||||||
|
const nextTick: typeof import('vue').nextTick
|
||||||
|
const onActivated: typeof import('vue').onActivated
|
||||||
|
const onBeforeMount: typeof import('vue').onBeforeMount
|
||||||
|
const onBeforeRouteLeave: typeof import('vue-router').onBeforeRouteLeave
|
||||||
|
const onBeforeRouteUpdate: typeof import('vue-router').onBeforeRouteUpdate
|
||||||
|
const onBeforeUnmount: typeof import('vue').onBeforeUnmount
|
||||||
|
const onBeforeUpdate: typeof import('vue').onBeforeUpdate
|
||||||
|
const onDeactivated: typeof import('vue').onDeactivated
|
||||||
|
const onErrorCaptured: typeof import('vue').onErrorCaptured
|
||||||
|
const onMounted: typeof import('vue').onMounted
|
||||||
|
const onRenderTracked: typeof import('vue').onRenderTracked
|
||||||
|
const onRenderTriggered: typeof import('vue').onRenderTriggered
|
||||||
|
const onScopeDispose: typeof import('vue').onScopeDispose
|
||||||
|
const onServerPrefetch: typeof import('vue').onServerPrefetch
|
||||||
|
const onUnmounted: typeof import('vue').onUnmounted
|
||||||
|
const onUpdated: typeof import('vue').onUpdated
|
||||||
|
const onWatcherCleanup: typeof import('vue').onWatcherCleanup
|
||||||
|
const provide: typeof import('vue').provide
|
||||||
|
const reactive: typeof import('vue').reactive
|
||||||
|
const readonly: typeof import('vue').readonly
|
||||||
|
const ref: typeof import('vue').ref
|
||||||
|
const resolveComponent: typeof import('vue').resolveComponent
|
||||||
|
const setActivePinia: typeof import('pinia').setActivePinia
|
||||||
|
const setMapStoreSuffix: typeof import('pinia').setMapStoreSuffix
|
||||||
|
const shallowReactive: typeof import('vue').shallowReactive
|
||||||
|
const shallowReadonly: typeof import('vue').shallowReadonly
|
||||||
|
const shallowRef: typeof import('vue').shallowRef
|
||||||
|
const showToast: typeof import('vant/es').showToast
|
||||||
|
const storeToRefs: typeof import('pinia').storeToRefs
|
||||||
|
const toRaw: typeof import('vue').toRaw
|
||||||
|
const toRef: typeof import('vue').toRef
|
||||||
|
const toRefs: typeof import('vue').toRefs
|
||||||
|
const toValue: typeof import('vue').toValue
|
||||||
|
const triggerRef: typeof import('vue').triggerRef
|
||||||
|
const unref: typeof import('vue').unref
|
||||||
|
const useAttrs: typeof import('vue').useAttrs
|
||||||
|
const useCssModule: typeof import('vue').useCssModule
|
||||||
|
const useCssVars: typeof import('vue').useCssVars
|
||||||
|
const useId: typeof import('vue').useId
|
||||||
|
const useLink: typeof import('vue-router').useLink
|
||||||
|
const useModel: typeof import('vue').useModel
|
||||||
|
const useRoute: typeof import('vue-router').useRoute
|
||||||
|
const useRouter: typeof import('vue-router').useRouter
|
||||||
|
const useSlots: typeof import('vue').useSlots
|
||||||
|
const useTemplateRef: typeof import('vue').useTemplateRef
|
||||||
|
const watch: typeof import('vue').watch
|
||||||
|
const watchEffect: typeof import('vue').watchEffect
|
||||||
|
const watchPostEffect: typeof import('vue').watchPostEffect
|
||||||
|
const watchSyncEffect: typeof import('vue').watchSyncEffect
|
||||||
|
}
|
||||||
|
// for type re-export
|
||||||
|
declare global {
|
||||||
|
// @ts-ignore
|
||||||
|
export type { Component, Slot, Slots, ComponentPublicInstance, ComputedRef, DirectiveBinding, ExtractDefaultPropTypes, ExtractPropTypes, ExtractPublicPropTypes, InjectionKey, PropType, Ref, ShallowRef, MaybeRef, MaybeRefOrGetter, VNode, WritableComputedRef } from 'vue'
|
||||||
|
import('vue')
|
||||||
|
}
|
||||||
60
types/components.d.ts
vendored
Normal file
60
types/components.d.ts
vendored
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
/* eslint-disable */
|
||||||
|
// @ts-nocheck
|
||||||
|
// biome-ignore lint: disable
|
||||||
|
// oxlint-disable
|
||||||
|
// ------
|
||||||
|
// Generated by unplugin-vue-components
|
||||||
|
// Read more: https://github.com/vuejs/core/pull/3399
|
||||||
|
import { GlobalComponents } from 'vue'
|
||||||
|
|
||||||
|
export {}
|
||||||
|
|
||||||
|
/* prettier-ignore */
|
||||||
|
declare module 'vue' {
|
||||||
|
export interface GlobalComponents {
|
||||||
|
NutAvatar: typeof import('@nutui/nutui')['Avatar']
|
||||||
|
NutButton: typeof import('@nutui/nutui')['Button']
|
||||||
|
NutCard: typeof import('@nutui/nutui')['Card']
|
||||||
|
NutCell: typeof import('@nutui/nutui')['Cell']
|
||||||
|
NutCellGroup: typeof import('@nutui/nutui')['CellGroup']
|
||||||
|
NutForm: typeof import('@nutui/nutui')['Form']
|
||||||
|
NutFormItem: typeof import('@nutui/nutui')['FormItem']
|
||||||
|
NutGrid: typeof import('@nutui/nutui')['Grid']
|
||||||
|
NutGridItem: typeof import('@nutui/nutui')['GridItem']
|
||||||
|
NutInput: typeof import('@nutui/nutui')['Input']
|
||||||
|
NutSwiper: typeof import('@nutui/nutui')['Swiper']
|
||||||
|
NutSwiperItem: typeof import('@nutui/nutui')['SwiperItem']
|
||||||
|
NutTabbar: typeof import('@nutui/nutui')['Tabbar']
|
||||||
|
NutTabbarItem: typeof import('@nutui/nutui')['TabbarItem']
|
||||||
|
RouterLink: typeof import('vue-router')['RouterLink']
|
||||||
|
RouterView: typeof import('vue-router')['RouterView']
|
||||||
|
VanButton: typeof import('vant/es')['Button']
|
||||||
|
VanNavBar: typeof import('vant/es')['NavBar']
|
||||||
|
VarButton: typeof import('@varlet/ui')['_ButtonComponent']
|
||||||
|
VarSpace: typeof import('@varlet/ui')['_SpaceComponent']
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// For TSX support
|
||||||
|
declare global {
|
||||||
|
const NutAvatar: typeof import('@nutui/nutui')['Avatar']
|
||||||
|
const NutButton: typeof import('@nutui/nutui')['Button']
|
||||||
|
const NutCard: typeof import('@nutui/nutui')['Card']
|
||||||
|
const NutCell: typeof import('@nutui/nutui')['Cell']
|
||||||
|
const NutCellGroup: typeof import('@nutui/nutui')['CellGroup']
|
||||||
|
const NutForm: typeof import('@nutui/nutui')['Form']
|
||||||
|
const NutFormItem: typeof import('@nutui/nutui')['FormItem']
|
||||||
|
const NutGrid: typeof import('@nutui/nutui')['Grid']
|
||||||
|
const NutGridItem: typeof import('@nutui/nutui')['GridItem']
|
||||||
|
const NutInput: typeof import('@nutui/nutui')['Input']
|
||||||
|
const NutSwiper: typeof import('@nutui/nutui')['Swiper']
|
||||||
|
const NutSwiperItem: typeof import('@nutui/nutui')['SwiperItem']
|
||||||
|
const NutTabbar: typeof import('@nutui/nutui')['Tabbar']
|
||||||
|
const NutTabbarItem: typeof import('@nutui/nutui')['TabbarItem']
|
||||||
|
const RouterLink: typeof import('vue-router')['RouterLink']
|
||||||
|
const RouterView: typeof import('vue-router')['RouterView']
|
||||||
|
const VanButton: typeof import('vant/es')['Button']
|
||||||
|
const VanNavBar: typeof import('vant/es')['NavBar']
|
||||||
|
const VarButton: typeof import('@varlet/ui')['_ButtonComponent']
|
||||||
|
const VarSpace: typeof import('@varlet/ui')['_SpaceComponent']
|
||||||
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user