我们可以从实际开发流程的每个环节,详细对比 uni-appVue 的核心差异。两者虽语法同源,但因定位(通用Web vs 跨端)不同,在项目结构、API、组件、路由等方面存在本质区别。

🧠 开发思路

Vue

  • 核心思路:围绕 Web DOM 构建单页应用(SPA),专注于Web端的组件化开发,通过虚拟DOM优化渲染效率。
  • 关注点:Web端的交互体验、浏览器兼容性、前端工程化(如构建工具、代码分割)。

uni-app

  • 核心思路“一套代码,多端运行”,基于Vue语法,但需同时兼容Web、小程序、App等多端特性。
  • 关注点:跨端兼容性(条件编译)、各端原生能力调用、性能优化(如App端原生渲染、小程序分包)。

🔑 核心概念

Vue

  • 核心概念:组件化、虚拟DOM、响应式数据(Proxy/Object.defineProperty)、Vue Router(路由)、Pinia(状态管理)。
  • 渲染底层:依赖Web DOM,通过操作DOM元素更新页面。

uni-app

  • 核心概念:除Vue的核心概念外,新增:
    • 条件编译:通过 #ifdef#ifndef 等指令,为不同端编写专属代码。
    • 原生组件viewtextimage 等跨端组件(替代Web的 divspan)。
    • 页面生命周期onLoadonShowonHide 等(兼容小程序/App的页面逻辑)。
  • 渲染底层
    • Web端:Web DOM(同Vue);
    • 小程序端:转换为对应平台的原生组件;
    • App端:默认WebView渲染,可选 uvue原生渲染(直接调用iOS/Android原生控件)。

🚀 第一步:项目初始化

📁 1. 创建项目目录

Vue
  • 创建工具:Vite(推荐)或 Vue CLI。
  • 命令示例
    npm create vite@latest my-vue-app -- --template vue
    
  • 初始目录
    my-vue-app/
    ├── src/
    │   ├── components/  # 组件
    │   ├── views/       # 页面
    │   ├── App.vue      # 根组件
    │   └── main.js      # 入口文件
    ├── index.html       # HTML模板
    └── package.json
    
uni-app
  • 创建工具:HBuilderX(官方推荐,可视化操作)或 uni CLI(命令行)。
  • 命令示例(uni CLI):
    npx degit dcloudio/uni-preset-vue#vite my-uni-app
    
  • 初始目录(跨端特有结构):
    my-uni-app/
    ├── src/
    │   ├── pages/       # 页面(需在pages.json注册)
    │   ├── static/      # 静态资源(图片、字体等)
    │   ├── components/  # 组件
    │   ├── App.vue      # 应用配置(生命周期、全局样式)
    │   ├── main.js      # 入口文件
    │   └── pages.json   # 【核心】页面路由、窗口样式、tabbar配置
    ├── manifest.json    # 【核心】各端配置(AppID、权限、原生插件)
    └── package.json
    

📦 2. 项目结构规划

Vue
  • 结构逻辑:按Web应用功能划分(如 viewscomponentsrouterstore),无需考虑跨端。
  • 关键文件router/index.js(路由配置)、store/index.js(状态管理)。
uni-app
  • 结构逻辑:按跨端需求划分,需重点关注:
    • pages.json:统一管理所有端的页面路由、窗口样式(如导航栏颜色、下拉刷新)。
    • manifest.json:配置各端的专属信息(如微信小程序AppID、Android权限)。
    • 条件编译目录:可创建 platforms/mp-weixin 等目录,存放端专属代码。

📦 第二步:安装项目依赖

🔧 1. 安装生产依赖

Vue
  • 核心依赖vuevue-router(路由)、pinia(状态管理)。
  • 可选依赖axios(HTTP请求)、element-plus(Web UI库)、sass(CSS预处理器)。
  • 示例
    npm install vue vue-router pinia axios
    
uni-app
  • 核心依赖@dcloudio/uni-app(uni-app核心)、@dcloudio/uni-mp-weixin(小程序端适配)等(根据目标端选择)。
  • 可选依赖
    • HTTP请求:不能直接用 axios(部分端不支持),需用 uni.request 或封装 @dcloudio/uni-ajax
    • UI库:需用跨端UI库,如 uView Plusuni-ui(替代Web的Element Plus)。
    • 状态管理:仍可用 pinia,但需配合 uni.setStorageSync 做跨端持久化。
  • 示例
    npm install @dcloudio/uni-app uview-plus pinia
    

🔧 2. 安装开发依赖

Vue
  • 核心依赖vite(构建工具)、@vitejs/plugin-vue(Vue插件)、eslintprettier
  • 示例
    npm install -D vite @vitejs/plugin-vue eslint prettier
    
uni-app
  • 核心依赖@dcloudio/vite-plugin-uni(uni-app构建插件)、@dcloudio/types(uni-app类型定义)。
  • 示例
    npm install -D @dcloudio/vite-plugin-uni @dcloudio/types
    

🤔 为什么选择这些技术栈?

Vue
  • 选择 vue-routerpinia:Web生态成熟,专注于单页应用的路由和状态管理。
  • 选择 axios:Web端HTTP请求的标准库,支持拦截器、取消请求等高级功能。
uni-app
  • 选择 uni.request 替代 axios:兼容所有端(Web、小程序、App),无需处理跨端适配。
  • 选择 uView Plus:专为uni-app设计,组件样式和API在各端一致。
  • 选择 pinia + uni.setStorageSync:既保留Vue的状态管理逻辑,又能实现跨端数据持久化。

⚙️ 第三步:配置开发环境

📝 1. 更新package.json的脚本

Vue
  • 脚本逻辑:仅针对Web端,分为开发、构建、预览。
  • 示例
    {
      "scripts": {
        "dev": "vite",           // 启动Web开发服务器
        "build": "vite build",   // 构建Web生产版本
        "preview": "vite preview"// 预览构建结果
      }
    }
    
uni-app
  • 脚本逻辑:按端拆分,每个端有独立的开发和构建命令。
  • 示例
    {
      "scripts": {
        "dev:h5": "uni -p h5",                // 开发H5端
        "dev:mp-weixin": "uni -p mp-weixin",  // 开发微信小程序
        "dev:app": "uni -p app",               // 开发App端
        "build:h5": "uni build -p h5",         // 构建H5端
        "build:mp-weixin": "uni build -p mp-weixin", // 构建微信小程序
        "build:app": "uni build -p app"        // 构建App端
      }
    }
    

📝 2. 创建Prettier配置文件

Vue & uni-app
  • 配置基本一致:都可通过 .prettierrc 配置代码格式化规则。
  • uni-app额外注意:需在配置中忽略 manifest.jsonpages.json 等uni-app核心配置文件(避免格式化破坏结构)。
  • 示例
    {
      "semi": false,
      "singleQuote": true,
      "ignorePath": ".gitignore"
    }
    

📝 3. 创建环境变量文件

Vue
  • 文件命名.env(通用)、.env.development(开发)、.env.production(生产)。
  • 变量前缀:需以 VITE_ 开头(Vite规定)。
  • 示例.env.development):
    VITE_API_BASE_URL=http://localhost:3000/api
    
uni-app
  • 文件命名:支持按端拆分,如 .env.mp-weixin(微信小程序环境)、.env.app(App端环境)。
  • 变量前缀:需以 VITE_UNI_ 开头。
  • 示例.env.mp-weixin):
    UNI_API_BASE_URL=https://api.example.com/mp
    

🎯 第四步:创建基础类型定义

📝 1. 创建通用类型

Vue
  • 类型范围:针对Web API和Vue生态,如 RouterPiniaStoreAxiosResponse
  • 示例src/types/index.ts):
    export interface User {
      id: number;
      name: string;
    }
    
    export interface ApiResponse<T> {
      code: number;
      data: T;
      message: string;
    }
    
uni-app
  • 类型范围:除Vue的类型外,需包含 uni-app API类型(如 UniRequestOptionsUniLoginSuccess)和 端专属类型
  • 示例src/types/index.ts):
    // 引入uni-app类型定义
    import type { UniRequestOptions } from '@dcloudio/types';
    
    export interface User {
      id: number;
      name: string;
    }
    
    // 封装uni.request的响应类型
    export interface UniApiResponse<T> {
      code: number;
      data: T;
      message: string;
    }
    

🔧 第五步:创建API服务层

📝 1. 创建HTTP客户端配置

Vue
  • 实现方式:用 axios 封装,支持拦截器、baseURL配置。
  • 示例src/utils/request.ts):
    import axios from 'axios';
    
    const request = axios.create({
      baseURL: import.meta.env.VITE_API_BASE_URL,
      timeout: 10000
    });
    
    // 请求拦截器
    request.interceptors.request.use(config => {
      const token = localStorage.getItem('token');
      if (token) config.headers.Authorization = `Bearer ${token}`;
      return config;
    });
    
    // 响应拦截器
    request.interceptors.response.use(
      res => res.data,
      err => Promise.reject(err)
    );
    
    export default request;
    
uni-app
  • 实现方式:用 uni.request 封装(不能用axios),需兼容各端的请求逻辑。
  • 示例src/utils/request.ts):
    const baseURL = import.meta.env.UNI_API_BASE_URL;
    
    const request = <T>(options: UniRequestOptions): Promise<UniApiResponse<T>> => {
      return new Promise((resolve, reject) => {
        uni.request({
          url: baseURL + options.url,
          method: options.method || 'GET',
          data: options.data,
          header: {
            'Content-Type': 'application/json',
            'Authorization': `Bearer ${uni.getStorageSync('token')}` || ''
          },
          success: (res) => {
            if (res.statusCode === 200) {
              resolve(res.data as UniApiResponse<T>);
            } else {
              reject(res);
            }
          },
          fail: (err) => reject(err)
        });
      });
    };
    
    export default request;
    

📝 2. 创建认证服务

Vue
  • 实现方式:用封装好的 axios 调用登录、注册接口,token存储在 localStorage
  • 示例src/api/auth.ts):
    import request from '@/utils/request';
    
    export const login = (data: { username: string; password: string }) => {
      return request.post('/auth/login', data);
    };
    
    export const register = (data: { username: string; password: string }) => {
      return request.post('/auth/register', data);
    };
    
uni-app
  • 实现方式:用封装好的 uni.request 调用接口,token存储在 uni.setStorageSync(跨端存储);若为小程序/App端,还需调用 uni.login 获取平台登录凭证。
  • 示例src/api/auth.ts):
    import request from '@/utils/request';
    
    // 普通登录
    export const login = (data: { username: string; password: string }) => {
      return request<User>('/auth/login', { method: 'POST', data });
    };
    
    // 微信小程序一键登录
    export const wechatLogin = () => {
      return new Promise((resolve, reject) => {
        uni.login({
          provider: 'weixin',
          success: (loginRes) => {
            request<User>('/auth/wechat', {
              method: 'POST',
              data: { code: loginRes.code }
            }).then(resolve).catch(reject);
          },
          fail: reject
        });
      });
    };
    

📝 3. 创建文章服务

Vue & uni-app
  • 逻辑基本一致:都是调用HTTP接口获取文章列表、详情等。
  • 唯一区别:Vue用 axios,uni-app用 uni.request

🎨 第六步:创建全局状态管理

📝 1. 创建认证状态管理

Vue
  • 实现方式:用 pinia 管理用户信息、token,token持久化到 localStorage
  • 示例src/stores/auth.ts):
    import { defineStore } from 'pinia';
    import { ref } from 'vue';
    
    export const useAuthStore = defineStore('auth', () => {
      const user = ref<User | null>(null);
      const token = ref<string>(localStorage.getItem('token') || '');
    
      const setUser = (newUser: User) => {
        user.value = newUser;
      };
    
      const setToken = (newToken: string) => {
        token.value = newToken;
        localStorage.setItem('token', newToken);
      };
    
      const logout = () => {
        user.value = null;
        token.value = '';
        localStorage.removeItem('token');
      };
    
      return { user, token, setUser, setToken, logout };
    });
    
uni-app
  • 实现方式:仍用 pinia,但token持久化到 uni.setStorageSync(跨端存储)。
  • 示例src/stores/auth.ts):
    import { defineStore } from 'pinia';
    import { ref } from 'vue';
    
    export const useAuthStore = defineStore('auth', () => {
      const user = ref<User | null>(null);
      const token = ref<string>(uni.getStorageSync('token') || '');
    
      const setUser = (newUser: User) => {
        user.value = newUser;
      };
    
      const setToken = (newToken: string) => {
        token.value = newToken;
        uni.setStorageSync('token', newToken);
      };
    
      const logout = () => {
        user.value = null;
        token.value = '';
        uni.removeStorageSync('token');
      };
    
      return { user, token, setUser, setToken, logout };
    });
    

📝 2. 创建文章状态管理

Vue & uni-app
  • 逻辑基本一致:用 pinia 管理文章列表、详情等状态。

🏗️ 第七步:创建基础组件

📝 1. 创建布局组件

Vue
  • 组件元素:用Web的 divheaderfootermain 等语义化标签。
  • 示例src/components/Layout.vue):
    <template>
      <div class="layout">
        <header class="header">头部</header>
        <main class="main"><slot /></main>
        <footer class="footer">页脚</footer>
      </div>
    </template>
    
    <style scoped>
    .layout { display: flex; flex-direction: column; min-height: 100vh; }
    .header { height: 60px; background: #333; color: #fff; }
    .main { flex: 1; padding: 20px; }
    .footer { height: 40px; background: #eee; }
    </style>
    
uni-app
  • 组件元素:必须用uni-app的跨端组件 viewtext 等(不能用Web的 divspan)。
  • 示例src/components/Layout.vue):
    <template>
      <view class="layout">
        <view class="header">头部</view>
        <view class="main"><slot /></view>
        <view class="footer">页脚</view>
      </view>
    </template>
    
    <style scoped>
    /* 用rpx单位适配多端屏幕(750rpx = 屏幕宽度) */
    .layout { display: flex; flex-direction: column; min-height: 100vh; }
    .header { height: 120rpx; background: #333; color: #fff; }
    .main { flex: 1; padding: 40rpx; }
    .footer { height: 80rpx; background: #eee; }
    </style>
    

📝 2. 创建主布局组件

Vue
  • 布局逻辑:用 vue-router<router-view /> 渲染页面内容。
uni-app
  • 布局逻辑:无需 <router-view />,页面内容由 pages.json 配置的路由自动渲染;主布局通常通过 App.vue 的全局样式或自定义组件实现。

📝 3. 创建页脚组件

Vue & uni-app
  • 逻辑基本一致:用对应框架的组件实现,注意uni-app需用跨端组件和rpx单位。

🔐 第八步:创建认证页面

📝 1. 创建登录页面

Vue
  • 页面元素:用 forminputbutton 等Web表单元素,路由跳转用 router.push
  • 示例src/views/Login.vue):
    <template>
      <div class="login">
        <form @submit.prevent="handleLogin">
          <input v-model="username" placeholder="用户名" />
          <input v-model="password" type="password" placeholder="密码" />
          <button type="submit">登录</button>
        </form>
      </div>
    </template>
    
    <script setup>
    import { ref } from 'vue';
    import { useRouter } from 'vue-router';
    import { useAuthStore } from '@/stores/auth';
    import { login } from '@/api/auth';
    
    const router = useRouter();
    const authStore = useAuthStore();
    const username = ref('');
    const password = ref('');
    
    const handleLogin = async () => {
      const res = await login({ username: username.value, password: password.value });
      authStore.setToken(res.data.token);
      authStore.setUser(res.data.user);
      router.push('/');
    };
    </script>
    
uni-app
  • 页面元素:用 forminputbutton 等uni-app表单组件,路由跳转用 uni.switchTabuni.navigateTo 等(不能用 router.push)。
  • 示例src/pages/login/login.vue):
    <template>
      <view class="login">
        <form @submit="handleLogin">
          <input v-model="username" placeholder="用户名" />
          <input v-model="password" type="password" placeholder="密码" />
          <button form-type="submit">登录</button>
        </form>
        <!-- 微信小程序一键登录按钮(条件编译) -->
        <button v-if="def.mp-weixin" @click="handleWechatLogin">微信一键登录</button>
      </view>
    </template>
    
    <script setup>
    import { ref } from 'vue';
    import { useAuthStore } from '@/stores/auth';
    import { login, wechatLogin } from '@/api/auth';
    
    const authStore = useAuthStore();
    const username = ref('');
    const password = ref('');
    
    const handleLogin = async () => {
      const res = await login({ username: username.value, password: password.value });
      authStore.setToken(res.data.token);
      authStore.setUser(res.data.user);
      uni.switchTab({ url: '/pages/index/index' }); // 跳转到tabbar页面
    };
    
    const handleWechatLogin = async () => {
      const res = await wechatLogin();
      authStore.setToken(res.data.token);
      authStore.setUser(res.data.user);
      uni.switchTab({ url: '/pages/index/index' });
    };
    </script>
    

📝 2. 创建注册页面

Vue & uni-app
  • 逻辑同登录页面:Vue用Web表单和 router.push,uni-app用跨端表单和 uni.navigateTo

🏠 第九步:创建首页和文章页面

📝 1. 创建首页组件

Vue
  • 页面逻辑:用 axios 获取文章列表,用 v-for 渲染,点击跳转用 router-link
  • 示例src/views/Home.vue):
    <template>
      <div class="home">
        <h1>文章列表</h1>
        <div v-for="article in articles" :key="article.id" class="article-item">
          <router-link :to="`/article/${article.id}`">
            <h2>{{ article.title }}</h2>
            <p>{{ article.summary }}</p>
          </router-link>
        </div>
      </div>
    </template>
    
    <script setup>
    import { ref, onMounted } from 'vue';
    import { getArticles } from '@/api/article';
    
    const articles = ref([]);
    
    onMounted(async () => {
      const res = await getArticles();
      articles.value = res.data;
    });
    </script>
    
uni-app
  • 页面逻辑:用 uni.request 获取文章列表,用 scroll-view 渲染长列表(优化性能),点击跳转用 uni.navigateTo
  • 示例src/pages/index/index.vue):
    <template>
      <view class="home">
        <text class="title">文章列表</text>
        <!-- scroll-view优化长列表滚动 -->
        <scroll-view scroll-y class="article-list">
          <view v-for="article in articles" :key="article.id" class="article-item" @click="goToDetail(article.id)">
            <text class="article-title">{{ article.title }}</text>
            <text class="article-summary">{{ article.summary }}</text>
          </view>
        </scroll-view>
      </view>
    </template>
    
    <script setup>
    import { ref, onLoad } from 'vue';
    import { getArticles } from '@/api/article';
    
    const articles = ref([]);
    
    // 用onLoad替代onMounted(uni-app页面生命周期)
    onLoad(async () => {
      const res = await getArticles();
      articles.value = res.data;
    });
    
    const goToDetail = (id: number) => {
      uni.navigateTo({ url: `/pages/article/detail?id=${id}` });
    };
    </script>
    

📝 2. 创建文章详情页面

Vue
  • 路由参数:用 useRoute().params 获取文章ID。
uni-app
  • 路由参数:用 onLoad 的参数获取文章ID(如 onLoad((options) => { const id = options.id; }))。

📝 3. 创建文章编辑页面

Vue & uni-app
  • 逻辑同登录页面:注意uni-app需用跨端组件和API。

🔗 第十步:配置路由系统

📝 1. 创建路由配置

Vue
  • 实现方式:用 vue-router 单独创建路由配置文件。
  • 示例src/router/index.ts):
    import { createRouter, createWebHistory } from 'vue-router';
    import Home from '@/views/Home.vue';
    import Login from '@/views/Login.vue';
    
    const routes = [
      { path: '/', component: Home },
      { path: '/login', component: Login },
      { path: '/article/:id', component: () => import('@/views/ArticleDetail.vue') }
    ];
    
    const router = createRouter({
      history: createWebHistory(),
      routes
    });
    
    export default router;
    
uni-app
  • 实现方式:无需单独的路由文件,所有路由在 pages.json 中配置。
  • 示例src/pages.json):
    {
      "pages": [
        {
          "path": "pages/index/index", // 首页(第一个为默认页)
          "style": { "navigationBarTitleText": "首页" }
        },
        {
          "path": "pages/login/login",
          "style": { "navigationBarTitleText": "登录" }
        },
        {
          "path": "pages/article/detail",
          "style": { "navigationBarTitleText": "文章详情" }
        }
      ],
      "tabBar": { // 底部tabbar配置
        "list": [
          { "pagePath": "pages/index/index", "text": "首页" },
          { "pagePath": "pages/user/index", "text": "我的" }
        ]
      }
    }
    

📝 2. 创建路由保护组件

Vue
  • 实现方式:用 vue-routerbeforeEach 全局前置守卫。
  • 示例src/router/index.ts):
    router.beforeEach((to, from, next) => {
      const token = localStorage.getItem('token');
      if (to.path !== '/login' && !token) {
        next('/login');
      } else {
        next();
      }
    });
    
uni-app
  • 实现方式:没有内置的路由守卫,需通过 App.vueonLaunchonShow 或页面的 onLoad 实现。
  • 示例src/App.vue):
    <script setup>
    import { onLaunch } from '@dcloudio/uni-app';
    
    onLaunch(() => {
      const token = uni.getStorageSync('token');
      if (!token) {
        uni.reLaunch({ url: '/pages/login/login' });
      }
    });
    </script>
    

🎨 第十一步:创建样式和主题

📝 1. 创建全局样式

Vue
  • 样式单位:用 pxremem 等Web常用单位。
  • 样式文件:在 src/styles/global.css 中定义,在 main.js 中引入。
  • 示例
    * { margin: 0; padding: 0; box-sizing: border-box; }
    body { font-family: Arial, sans-serif; }
    
uni-app
  • 样式单位:推荐用 rpx(响应式像素,750rpx = 屏幕宽度,自动适配多端)。
  • 样式文件:在 src/styles/global.css 中定义,在 App.vue<style> 中引入。
  • 示例
    /* 全局样式 */
    page { font-family: Arial, sans-serif; background: #f5f5f5; }
    .container { padding: 40rpx; }
    

📝 2. 更新主入口文件

Vue
  • 入口文件src/main.js,引入路由、状态管理、全局样式。
  • 示例
    import { createApp } from 'vue';
    import App from './App.vue';
    import router from './router';
    import pinia from './stores';
    import './styles/global.css';
    
    const app = createApp(App);
    app.use(router);
    app.use(pinia);
    app.mount('#app');
    
uni-app
  • 入口文件src/main.js,引入状态管理、全局样式(无需引入路由)。
  • 示例
    import { createSSRApp } from 'vue';
    import App from './App.vue';
    import pinia from './stores';
    import './styles/global.css';
    
    export function createApp() {
      const app = createSSRApp(App);
      app.use(pinia);
      return { app };
    }
    

🚀 第十二步:启动和测试

📝 1. 启动开发服务器

Vue
  • 启动命令npm run dev,在浏览器中访问 http://localhost:5173
uni-app
  • 分端启动
    • H5端:npm run dev:h5,在浏览器访问;
    • 微信小程序:npm run dev:mp-weixin,用微信开发者工具打开项目目录;
    • App端:npm run dev:app,用HBuilderX连接真机或模拟器预览。

📝 2. 功能测试清单

Vue
  • 测试重点:Web端的交互、浏览器兼容性、响应式布局。
uni-app
  • 测试重点
    • 多端兼容性:H5、小程序、App端的功能是否一致;
    • 端专属功能:如微信小程序的一键登录、App端的原生渲染;
    • 性能:长列表滚动、动画是否流畅。

🎯 第十三步:优化和部署

📝 1. 性能优化

Vue
  • 优化方向:代码分割、路由懒加载、组件缓存(keep-alive)、图片懒加载。
uni-app
  • 优化方向
    • 小程序端:分包加载(在 pages.json 中配置 subPackages)、减少主包体积;
    • App端:用 uvue 替代普通Vue页面(原生渲染,提升性能);
    • 通用:图片压缩、使用 scroll-view 优化长列表、避免频繁的 uni.setStorageSync

📝 2. 构建生产版本

Vue
  • 构建命令npm run build,生成 dist 目录,部署到Web服务器。
uni-app
  • 分端构建
    • H5端:npm run build:h5,生成 dist/build/h5 目录,部署到Web服务器;
    • 微信小程序:npm run build:mp-weixin,生成 dist/build/mp-weixin 目录,用微信开发者工具上传代码;
    • App端:npm run build:app,用HBuilderX打包成 ipa(iOS)或 apk(Android)。

📝 3. 部署配置

Vue
  • 部署方式:将 dist 目录部署到Nginx、Apache等Web服务器,配置反向代理解决跨域。
uni-app
  • 部署方式
    • H5端:同Vue;
    • 小程序端:上传到微信公众平台、支付宝开放平台等,提交审核;
    • App端:上传到App Store(iOS)、应用宝(Android)等应用市场。

总结:核心差异对比表

环节 Vue uni-app
定位 通用Web框架 跨端框架(Web/小程序/App)
渲染底层 Web DOM Web端:DOM;小程序:原生组件;App:WebView/uvue原生
项目结构 src/views、router/index.js src/pages、pages.json、manifest.json
路由 vue-router pages.json配置
HTTP请求 axios uni.request
组件 div、span等Web组件 view、text等跨端组件
样式单位 px、rem rpx(推荐)
状态管理 pinia + localStorage pinia + uni.setStorageSync
启动/构建 仅Web端 分端(H5/小程序/App)
Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐