本文章使用了pnpm创建的uniappV3项目,需要node版本>20

1.创建项目

因为用到的vscode,所以我们需要使用命令行创建uniapp的项目
可以在uniapp官网查看命令行创建uni-app
本文章使用了ts,所以需要如下命令行,my-vue3-project是项目名称

npx degit dcloudio/uni-preset-vue#vite-ts my-vue3-project

在这里插入图片描述

1.1 下载依赖

命令行创建完成后cd my-vue3-project 并使用pnpm下载依赖

在这里插入图片描述

看配置项可以根据项目运行程序,一般就是h5和wx了

在这里插入图片描述

1.2运行项目
pnpm run dev:h5

如下图就是h5启动成功了
在这里插入图片描述

2.解决项目代码在vscode中爆红问题

vscode中下载多个扩展,如果要运行到微信小程序,请看我的另外一篇文章vscode开发小程序项目并在微信开发者工具运行

1.uni-app-schemas
2.uni-app-snippets
3.uni-cloud-snippets
4.uni-create-view,在该扩展中可以同名创建文件
5.uni-helper
6.uni-highlight
7.uni-ui-snippets
8.uniapp小程序扩展
9.Wot Design Uni Snippets (语法插件,可用可不用,一般)
在这里插入图片描述

可以设置文件名和文件夹同名

在这里插入图片描述
在这里插入图片描述

2.1 pages.json备注爆红问题

首先打开文件>首选项>设置

在这里插入图片描述

搜索Associations,添加manifest.json和pages.json就可以了

在这里插入图片描述

3.下载项目依赖

下载项目需要的依赖,pinia(需要降低版本,不然会报错Failed to resolve import “@vue/devtools-api” from “node_modules/pinia/dist/pinia.mjs?v=3b6fdd05”. Does the file exist?)、sass(需要降低版本,不然不兼容wot-design-uni组件库)、wot-design-uni,命令行如下

pnpm install pinia@^2.1.7
pnpm install pinia-plugin-persistedstate@^2.3.0
pnpm add sass@1.78.0 -S
pnpm add sass-loader@v8.x
pnpm add wot-design-uni

4.main.ts配置

/*
* @Description:
* @Author: 请叫我欧皇i
* @Date: 2025-10-16 13:57:15
* @FilePath: \uniappV3\uni-vue3-project\src\main.ts
*/
import { createSSRApp } from "vue";
import App from "./App.vue";
import { createPinia } from "pinia";
import piniaPluginPersistedstate from "pinia-plugin-persistedstate"; // 状态持久化
const pinia = createPinia();
pinia.use(piniaPluginPersistedstate);
export function createApp() {
const app = createSSRApp(App);
app.use(pinia);
return {
app,
};
}

5.配置自动导入插件

下载插件,必须降低版本,不然会报错,也是因为不兼容

pnpm add unplugin-auto-import@19.2.0 -S
pnpm add unplugin-vue-components@28.8.0 -S
5.1在vite.config.ts中配置

配置完成后会自动生成auto-imports.d.ts和components.d.ts文件,里面可以查看引入的文件

/*
* @Description:
* @Author: 请叫我欧皇i
* @Date: 2025-10-16 13:57:15
* @FilePath: \uni-vue3-project\vite.config.ts
*/
import { defineConfig } from "vite";
import uni from "@dcloudio/vite-plugin-uni";
// 加上下面这一行
import AutoImport from "unplugin-auto-import/vite";
import Components from "unplugin-vue-components/vite";
// https://vitejs.dev/config/
export default defineConfig({
plugins: [
uni(), // 加上下面的配置
AutoImport({
include: [
/\.[tj]sx?$/, // .ts, .tsx, .js, .jsx
/\.vue$/,
/\.vue\?vue/, // .vue
],
imports: [
"vue",
"uni-app",
{
// Pinia 自动导入
pinia: ["createPinia", "storeToRefs", "defineStore"],
// 如果需要,可以添加 Pinia 的持久化插件
"pinia-plugin-persistedstate": ["createPersistedState"],
},
],
dts: "src/auto-imports.d.ts",
dirs: [
"src/stores", // 自动导入 stores 目录下的所有 store
"src/composables", // 自动导入 composables 目录下的组合式函数
],
// 针对 uni-app 的配置
vueTemplate: true,
}),
Components({
// dirs 指定组件所在位置,默认为 src/components
// 可以让我们使用自己定义组件的时候免去 import 的麻烦
dirs: ["src/components"],
// 配置需要将哪些后缀类型的文件进行自动按需引入,'vue'为默认值
// extensions: ['vue'],
// // 解析组件,这里以 Element Plus 为例
// // resolvers: [],
// // 生成components.d.ts
dts: "components.d.ts",
// // 遍历子目录
// deep: true,
}),
],
});

6.pinia使用

创建stores/index.ts和user.ts
在这里插入图片描述
index.ts

import { createPinia } from "pinia";
import persist from "pinia-plugin-persistedstate";
// 创建 pinia 实例
const pinia = createPinia();
pinia.use(persist);
export default pinia;
// 统一导出所有 store
export * from "./user";
export * from "./equip";

user.ts以下是简单的例子文件

/*
* @Description:
* @Author: 请叫我欧皇i
* @Date: 2025-10-20 14:16:14
* @FilePath: \uni-vue3-project\src\stores\user.ts
*/
/*
* @Description: 用户状态管理 - Option Store风格
*/
interface UserInfo {
name: string;
avatar: string;
}
interface UserState {
token: string;
userInfo: UserInfo | null;
}
export const useUserStore = defineStore("user", {
state: (): UserState => ({
token: "222254654",
userInfo: null,
}),
getters: {
isLogin: (state) => !!state.token,
userName: (state) => state.userInfo?.name || "游客",
},
actions: {
setToken(token: string) {
this.token = token;
},
},
// 状态保存
persist: {
key: "user-store",
paths: ["token", "userInfo"],
},
});

重点!!!!页面使用

<template>
  <wd-input
  v-model="token"
  prefix-icon="dong"
  suffix-icon="list"
  @input="handleChange"
  />
  <wd-button type="primary" @click="clickBtn" size="small">
    按钮文字
    </wd-button>
      </template>
        <script lang="ts" setup>
          // 无需手动导入 store,自动导入插件会处理
          const userStore = useUserStore();
          // 使用 storeToRefs 保持响应式(也已自动导入)
          const { token, userInfo } = storeToRefs(userStore);
          const clickBtn = () => {
          userStore.setToken("3247382");
          };
          </script>
            <style scoped lang="scss"></style>

7.组件页面使用

注意!!!经过测试,微信开发者工具中引入只能是文件夹和文件名同名才可以引入成功,否则不显示,h5的都可以,为避免要打包成小程序,请使用同名创建,例子如下
在这里插入图片描述

页面使用

<!--
* @Description:
* @Author: 请叫我欧皇i
* @Date: 2025-10-17 16:07:00
* @FilePath: \uni-vue3-project\src\pages\personal\index.vue
-->
<template>
  <view class="app-box"></view>
    {{aa}}
    <NavHeader />
      </template>
        <script setup>
          let aa = ref<number>(0)
            </script>
              <style scoped lang="scss">
                .app-box {
                // #ifdef MP-WEIXIN
                height: 25px;
                background-color: #eee;
                // #endif
                }
                </style>

8.配置wot-design-uni

点开pages.json
在这里插入图片描述

配置语句如下:“^wd-(.*)”: “wot-design-uni/components/wd-$1/wd-$1.vue”,
官网wot-design-uni

在这里插入图片描述

9.接口请求封装

创建util/request.ts文件

//request.ts
export interface RequestParams {
url: string;
method?:
| "GET"
| "POST"
| "PUT"
| "DELETE"
| "get"
| "post"
| "put"
| "delete";
data?: any;
}
export interface ResponseData<T = any> {
  code: number;
  message: string;
  data: T;
  }
  // request.ts
  const BASE_URL = import.meta.env.DEV ? "/api" : "https://xx.com";
  export default <T = any>(params: RequestParams): Promise<T> => {
    const { url, method = "GET", data = {} } = params;
    console.log(BASE_URL + url, "9999999");
    const header: Record<string, string> = {};
      // 设置请求头
      if (method.toUpperCase() === "POST") {
      header["Content-Type"] = "application/json";
      }
      return new Promise((resolve, reject) => {
      uni.request({
      // 小程序运行使用
      // url: "https://xx.com" + url,
      url: BASE_URL + url, //h5运行使用
      method: method.toUpperCase() as any,
      header,
      data,
      success: (response) => {
      const res = response;
      console.log(res.statusCode);
      if (res.statusCode === 200) {
      resolve(res.data as T);
      } else {
      switch (res.statusCode) {
      case 401:
      uni.showModal({
      title: "提示",
      content: "请登录",
      showCancel: false,
      success: () => {
      setTimeout(() => {
      uni.navigateTo({
      url: "/pages/login/index",
      });
      }, 1000);
      },
      });
      break;
      case 404:
      uni.showToast({
      title: "请求地址不存在...",
      duration: 2000,
      });
      break;
      default:
      uni.showToast({
      title: "请重试...",
      duration: 2000,
      });
      break;
      }
      reject(res);
      }
      },
      fail: (err) => {
      console.log(err);
      if (err.errMsg.indexOf("request:fail") !== -1) {
      uni.showToast({
      title: "网络异常",
      icon: "error",
      duration: 2000,
      });
      } else {
      uni.showToast({
      title: "未知异常",
      duration: 2000,
      });
      }
      reject(err);
      },
      complete: () => {
      // 不管成功还是失败都会执行
      uni.hideLoading();
      uni.hideToast();
      },
      });
      });
      };

创建api/type.ts和api/index.ts文件

type.ts

/*
* @Description:
* @Author: 请叫我欧皇i
* @Date: 2025-10-17 15:11:49
* @FilePath: \uni-vue3-project\src\api\setting\type.ts
*/
// 需要先声明后端数据会返回什么值,是什么类型的,例子如下:
export interface SaleAttr {
date?: string | number; //表示参数可有可无,可以是字符串或数组类型
desc: string;
id: number;
image: string;
reply: number;
time: number;
title: string;
url: string;
username: string;
}
export interface SpuData {
next: number;
page: number;
list: SaleAttr[];
title: string;
}

index.ts

/*
* @Description:
* @Author: 请叫我欧皇i
* @Date: 2025-10-17 15:11:43
* @FilePath: \uni-vue3-project\src\api\setting\index.ts
*/
import request from "@/utils/request";
import type { SpuData } from "./type";
enum API {
getData = "/news/oschina-news",
}
export const reqGetData = (data: any) =>
request<SpuData>({//返回的ts类型
  url: API.getData,
  method: "GET",
  data,
  });

页面使用

<!--
* @Description:
* @Author: 请叫我欧皇i
* @Date: 2025-10-16 13:57:15
* @FilePath: \uni-vue3-project\src\pages\index\index.vue
-->
<template>
  <view class="">
    </view>
      </template>
        <script setup>
          import { reqGetData } from "@/api/index";
          const getApi = async () => {
          const res = await reqGetData({ type: 1 });
          console.log(res);
          };
          onShow(() => {
          getApi();
          });
          </script>
            <style scoped lang="scss"></style>

10.打包

注意!!!如果vscode创建项目的编译器版本低于hubuildX的版本的话打包后手机app会出现提示框,在项目中更新编译器版本就行了,更新版本命令如下:

npx @dcloudio/uvm@latest

在这里插入图片描述

h5打包可以直接使用命令打包

pnpm run dev:h5

打包成app

直接把项目导入在hubuildx里打包就行了,不然整复杂了,亲测可以打包成功

打包成小程序

使用Pnpm run dev:map-weix,之后导入到微信开发者工具,之后在微信开发者工具上传到小程序就行了

文章到此结束希望对你有所帮助~