Skip to content

Getting Started with uni-app

uni-app is a cross-platform framework developed by DCloud that allows developers to build applications for multiple platforms including iOS, Android, Web, and various mini programs (WeChat, Alipay, Baidu, etc.) using a single codebase. This guide will walk you through the process of setting up, developing, and deploying your first uni-app project.

Introduction to uni-app

What is uni-app?

uni-app is a framework that uses Vue.js to develop applications that can run on multiple platforms. It follows the "write once, deploy everywhere" philosophy, allowing developers to maintain a single codebase while targeting multiple platforms.

Key Features

  • Cross-Platform: Build for iOS, Android, Web, and various mini programs with one codebase
  • Vue-Powered: Uses Vue.js syntax and components for development
  • Rich Ecosystem: Access to a vast library of plugins and components
  • Performance Optimized: Native rendering capabilities for mobile platforms
  • IDE Support: Dedicated IDE (HBuilderX) with specialized tools and features
  • Hot Reload: Instant preview of code changes during development
  • Conditional Compilation: Platform-specific code when needed

Supported Platforms

uni-app currently supports the following platforms:

  • iOS
  • Android
  • Web (H5)
  • WeChat Mini Program
  • Alipay Mini Program
  • Baidu Smart Program
  • ByteDance Mini Program
  • QQ Mini Program
  • Kuaishou Mini Program
  • DingTalk Mini Program
  • 360 Mini Program
  • Quick App
  • Harmony OS (HarmonyOS)

Installation and Setup

HBuilderX is the official IDE for uni-app development, offering specialized tools and features.

  1. Download HBuilderX:

  2. Create a New Project:

    • Open HBuilderX
    • Click "File" > "New" > "Project"
    • Select "uni-app" as the project type
    • Choose a template (default template is recommended for beginners)
    • Enter a project name and location
    • Click "Create" to generate the project

Method 2: Using CLI (For Advanced Users)

If you prefer using your own editor and command-line tools:

  1. Install Vue CLI:

    bash
    npm install -g @vue/cli
  2. Install uni-app CLI Plugin:

    bash
    npm install -g @dcloudio/vue-cli-plugin-uni
  3. Create a New Project:

    bash
    vue create -p dcloudio/uni-preset-vue my-uni-app

    During the creation process, you'll be prompted to select a template:

    • hello-uni-app: A comprehensive demo with multiple examples
    • uni-ui: A project with the uni-ui component library
    • simple: A minimal template for quick starts
  4. Start Development Server:

    bash
    cd my-uni-app
    npm run dev:h5
    # or for WeChat Mini Program
    npm run dev:mp-weixin

Project Structure

A typical uni-app project structure looks like this:

my-uni-app/
├── pages/                 # Application pages
│   ├── index/             # Index page
│   │   ├── index.vue      # Page component
│   │   └── index.nvue     # Native rendering page (optional)
├── static/                # Static assets (images, fonts, etc.)
├── components/            # Reusable components
├── store/                 # Vuex store (optional)
├── common/                # Common utilities and styles
│   ├── uni.css            # Common styles
│   └── util.js            # Utility functions
├── App.vue                # App entry component
├── main.js                # App entry script
├── manifest.json          # App configuration
├── pages.json             # Page configuration
└── uni.scss               # Global SCSS variables and mixins

Key Configuration Files

pages.json

This file configures the pages, navigation bar, tabs, and other global window elements:

json
{
  "pages": [
    {
      "path": "pages/index/index",
      "style": {
        "navigationBarTitleText": "Home"
      }
    },
    {
      "path": "pages/user/user",
      "style": {
        "navigationBarTitleText": "User"
      }
    }
  ],
  "globalStyle": {
    "navigationBarTextStyle": "black",
    "navigationBarTitleText": "uni-app",
    "navigationBarBackgroundColor": "#F8F8F8",
    "backgroundColor": "#F8F8F8"
  },
  "tabBar": {
    "color": "#7A7E83",
    "selectedColor": "#3cc51f",
    "borderStyle": "black",
    "backgroundColor": "#ffffff",
    "list": [
      {
        "pagePath": "pages/index/index",
        "iconPath": "static/tab-home.png",
        "selectedIconPath": "static/tab-home-active.png",
        "text": "Home"
      },
      {
        "pagePath": "pages/user/user",
        "iconPath": "static/tab-user.png",
        "selectedIconPath": "static/tab-user-active.png",
        "text": "User"
      }
    ]
  }
}

manifest.json

This file contains application configuration, including app name, appID, version, and platform-specific settings:

json
{
  "name": "My uni-app",
  "appid": "__UNI__XXXXXXX",
  "description": "My first uni-app project",
  "versionName": "1.0.0",
  "versionCode": "100",
  "transformPx": false,
  "app-plus": {
    "usingComponents": true,
    "nvueCompiler": "uni-app",
    "splashscreen": {
      "alwaysShowBeforeRender": true,
      "waiting": true,
      "autoclose": true,
      "delay": 0
    }
  },
  "mp-weixin": {
    "appid": "wx1234567890",
    "setting": {
      "urlCheck": false
    },
    "usingComponents": true
  },
  "mp-alipay": {
    "usingComponents": true
  },
  "mp-baidu": {
    "usingComponents": true
  },
  "mp-toutiao": {
    "usingComponents": true
  },
  "h5": {
    "router": {
      "base": "/"
    }
  }
}

Development Basics

Creating Pages

In uni-app, each page is a Vue component. To create a new page:

  1. Create a new directory in the pages folder (e.g., pages/about/)
  2. Create a Vue file in this directory (e.g., about.vue)
  3. Register the page in pages.json

Example page component:

vue
<template>
  <view class="container">
    <text class="title">About Page</text>
    <button @click="navigateBack">Go Back</button>
  </view>
</template>

<script>
export default {
  data() {
    return {
      title: 'About Page'
    }
  },
  onLoad() {
    console.log('Page loaded')
  },
  methods: {
    navigateBack() {
      uni.navigateBack()
    }
  }
}
</script>

<style>
.container {
  padding: 20px;
}
.title {
  font-size: 18px;
  color: #333;
  margin-bottom: 20px;
}
</style>

Register the page in pages.json:

json
{
  "pages": [
    {
      "path": "pages/index/index",
      "style": {
        "navigationBarTitleText": "Home"
      }
    },
    {
      "path": "pages/about/about",
      "style": {
        "navigationBarTitleText": "About"
      }
    }
  ]
}

Using Components

uni-app provides a set of built-in components that map to native components on each platform:

vue
<template>
  <view class="container">
    <text>This is a text component</text>
    <image src="/static/logo.png" mode="aspectFit"></image>
    <button type="primary" @click="showToast">Click Me</button>
  </view>
</template>

<script>
export default {
  methods: {
    showToast() {
      uni.showToast({
        title: 'Button clicked',
        icon: 'success'
      })
    }
  }
}
</script>

Creating Custom Components

To create a reusable component:

  1. Create a new file in the components directory (e.g., components/CustomCard.vue)
  2. Define your component using Vue syntax
  3. Import and use it in your pages

Example custom component:

vue
<!-- components/CustomCard.vue -->
<template>
  <view class="card">
    <view class="card-header">
      <text class="card-title">{{ title }}</text>
    </view>
    <view class="card-body">
      <slot></slot>
    </view>
    <view class="card-footer" v-if="showFooter">
      <slot name="footer"></slot>
    </view>
  </view>
</template>

<script>
export default {
  name: 'CustomCard',
  props: {
    title: {
      type: String,
      default: 'Card Title'
    },
    showFooter: {
      type: Boolean,
      default: false
    }
  }
}
</script>

<style>
.card {
  background-color: #fff;
  border-radius: 8px;
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
  margin: 10px;
  overflow: hidden;
}
.card-header {
  padding: 10px 15px;
  border-bottom: 1px solid #eee;
}
.card-title {
  font-size: 16px;
  font-weight: bold;
}
.card-body {
  padding: 15px;
}
.card-footer {
  padding: 10px 15px;
  border-top: 1px solid #eee;
  background-color: #f9f9f9;
}
</style>

Using the custom component:

vue
<template>
  <view class="container">
    <custom-card title="My Card">
      <text>This is the card content</text>
      <template #footer>
        <button size="mini" type="primary">Action</button>
      </template>
    </custom-card>
  </view>
</template>

<script>
import CustomCard from '@/components/CustomCard.vue'

export default {
  components: {
    CustomCard
  }
}
</script>

uni-app provides APIs for navigating between pages:

js
// Navigate to a page
uni.navigateTo({
  url: '/pages/detail/detail?id=123',
  success: function(res) {
    console.log('Navigation successful')
  },
  fail: function(err) {
    console.error('Navigation failed', err)
  }
})

// Redirect (replace current page)
uni.redirectTo({
  url: '/pages/login/login'
})

// Navigate back
uni.navigateBack({
  delta: 1 // Number of pages to go back
})

// Switch tab
uni.switchTab({
  url: '/pages/home/home'
})

Accessing Page Parameters

To access URL parameters:

js
export default {
  onLoad(options) {
    // Access the 'id' parameter from the URL
    const id = options.id
    console.log('Received ID:', id)
    
    // Fetch data based on the ID
    this.fetchData(id)
  },
  methods: {
    fetchData(id) {
      // Implementation
    }
  }
}

API Usage

Network Requests

uni-app provides a unified API for making network requests:

js
// GET request
uni.request({
  url: 'https://api.example.com/data',
  method: 'GET',
  data: {
    param1: 'value1',
    param2: 'value2'
  },
  header: {
    'content-type': 'application/json'
  },
  success: (res) => {
    console.log('Request successful:', res.data)
  },
  fail: (err) => {
    console.error('Request failed:', err)
  },
  complete: () => {
    console.log('Request completed')
  }
})

// Using Promise
uni.request({
  url: 'https://api.example.com/data',
  method: 'POST',
  data: {
    name: 'uni-app',
    version: '2.x'
  }
})
  .then(res => console.log(res[1].data))
  .catch(err => console.error(err))

Data Storage

uni-app provides APIs for data persistence:

js
// Store data
uni.setStorage({
  key: 'userInfo',
  data: {
    name: 'John',
    age: 30,
    token: 'abc123'
  },
  success: function() {
    console.log('Data stored successfully')
  }
})

// Get data
uni.getStorage({
  key: 'userInfo',
  success: function(res) {
    console.log('Retrieved data:', res.data)
  }
})

// Using sync APIs
try {
  uni.setStorageSync('key', 'value')
  const value = uni.getStorageSync('key')
  console.log(value)
} catch (e) {
  console.error(e)
}

// Remove data
uni.removeStorage({
  key: 'userInfo'
})

// Clear all storage
uni.clearStorage()

System Information

Get device and system information:

js
// Get system info
uni.getSystemInfo({
  success: (res) => {
    console.log('System info:', res)
    console.log('Platform:', res.platform)
    console.log('Screen width:', res.screenWidth)
    console.log('Screen height:', res.screenHeight)
    console.log('Window width:', res.windowWidth)
    console.log('Window height:', res.windowHeight)
    console.log('Status bar height:', res.statusBarHeight)
    console.log('Language:', res.language)
    console.log('System version:', res.system)
    console.log('Platform version:', res.version)
    console.log('Device brand:', res.brand)
    console.log('Device model:', res.model)
    console.log('Device orientation:', res.deviceOrientation)
    console.log('Device pixel ratio:', res.pixelRatio)
  }
})

// Get network type
uni.getNetworkType({
  success: (res) => {
    console.log('Network type:', res.networkType)
  }
})

UI Components and Styling

Built-in Components

uni-app provides a rich set of built-in components:

vue
<template>
  <view class="container">
    <!-- Basic components -->
    <view class="box">View component (similar to div)</view>
    <text class="text">Text component</text>
    <button type="primary">Button</button>
    <image src="/static/logo.png" mode="aspectFit"></image>
    
    <!-- Form components -->
    <input type="text" v-model="inputValue" placeholder="Input component" />
    <textarea v-model="textareaValue" placeholder="Textarea component"></textarea>
    <switch :checked="switchValue" @change="onSwitchChange" />
    <checkbox-group @change="onCheckboxChange">
      <checkbox value="option1" :checked="checkboxValues.includes('option1')" />
      <checkbox value="option2" :checked="checkboxValues.includes('option2')" />
    </checkbox-group>
    
    <!-- Media components -->
    <video src="https://example.com/video.mp4" controls></video>
    <audio src="https://example.com/audio.mp3" controls></audio>
    
    <!-- Container components -->
    <scroll-view scroll-y style="height: 200px;">
      <view v-for="(item, index) in scrollItems" :key="index" class="scroll-item">
        {{ item }}
      </view>
    </scroll-view>
    
    <swiper indicator-dots autoplay :interval="3000" :duration="500">
      <swiper-item v-for="(item, index) in swiperItems" :key="index">
        <view class="swiper-item">{{ item }}</view>
      </swiper-item>
    </swiper>
  </view>
</template>

<script>
export default {
  data() {
    return {
      inputValue: '',
      textareaValue: '',
      switchValue: false,
      checkboxValues: ['option1'],
      scrollItems: ['Item 1', 'Item 2', 'Item 3', 'Item 4', 'Item 5'],
      swiperItems: ['Slide 1', 'Slide 2', 'Slide 3']
    }
  },
  methods: {
    onSwitchChange(e) {
      this.switchValue = e.detail.value
    },
    onCheckboxChange(e) {
      this.checkboxValues = e.detail.value
    }
  }
}
</script>

Styling with CSS

uni-app supports various CSS features:

vue
<style>
/* Global styles */
.container {
  padding: 20px;
}

/* Box model */
.box {
  width: 100%;
  height: 80px;
  margin: 10px 0;
  padding: 15px;
  border: 1px solid #ddd;
  border-radius: 5px;
}

/* Typography */
.text {
  font-size: 16px;
  font-weight: bold;
  color: #333;
  line-height: 1.5;
}

/* Flexbox layout */
.flex-container {
  display: flex;
  flex-direction: row;
  justify-content: space-between;
  align-items: center;
}

.flex-item {
  flex: 1;
  text-align: center;
}

/* Grid layout */
.grid-container {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  grid-gap: 10px;
}

/* Media queries */
@media screen and (min-width: 480px) {
  .container {
    padding: 30px;
  }
}
</style>

Using SCSS/SASS

uni-app supports SCSS/SASS preprocessing:

vue
<style lang="scss">
$primary-color: #007aff;
$secondary-color: #6c757d;
$border-radius: 5px;

.container {
  padding: 20px;
  
  .header {
    margin-bottom: 20px;
    
    .title {
      font-size: 20px;
      color: $primary-color;
    }
    
    .subtitle {
      font-size: 16px;
      color: $secondary-color;
    }
  }
  
  .button {
    background-color: $primary-color;
    color: white;
    border-radius: $border-radius;
    padding: 10px 15px;
    
    &:active {
      opacity: 0.8;
    }
    
    &.secondary {
      background-color: $secondary-color;
    }
  }
}
</style>

Using uni-ui Component Library

uni-ui is a UI component library specifically designed for uni-app:

  1. Install uni-ui:

    bash
    npm install @dcloudio/uni-ui
  2. Configure easycom in pages.json:

    json
    {
      "easycom": {
        "autoscan": true,
        "custom": {
          "^uni-(.*)": "@dcloudio/uni-ui/lib/uni-$1/uni-$1.vue"
        }
      }
    }
  3. Use uni-ui components:

    vue
    <template>
      <view class="container">
        <uni-card title="Card Title" sub-title="Card Subtitle" extra="Extra Info">
          <text>Card Content</text>
        </uni-card>
        
        <uni-section title="Form Components" type="line">
          <uni-forms>
            <uni-forms-item label="Name">
              <uni-easyinput v-model="formData.name" placeholder="Enter your name" />
            </uni-forms-item>
            <uni-forms-item label="Email">
              <uni-easyinput v-model="formData.email" placeholder="Enter your email" />
            </uni-forms-item>
          </uni-forms>
        </uni-section>
        
        <uni-section title="Data Display" type="line">
          <uni-list>
            <uni-list-item title="Item 1" note="Description for item 1" />
            <uni-list-item title="Item 2" note="Description for item 2" />
            <uni-list-item title="Item 3" note="Description for item 3" />
          </uni-list>
        </uni-section>
        
        <uni-pagination :total="50" :current="currentPage" @change="onPageChange" />
      </view>
    </template>
    
    <script>
    export default {
      data() {
        return {
          formData: {
            name: '',
            email: ''
          },
          currentPage: 1
        }
      },
      methods: {
        onPageChange(e) {
          this.currentPage = e.current
        }
      }
    }
    </script>

State Management

Using Vuex

  1. Create a Vuex store:
js
// store/index.js
import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex)

const store = new Vuex.Store({
  state: {
    count: 0,
    user: null,
    products: []
  },
  mutations: {
    INCREMENT(state) {
      state.count++
    },
    DECREMENT(state) {
      state.count--
    },
    SET_USER(state, user) {
      state.user = user
    },
    SET_PRODUCTS(state, products) {
      state.products = products
    }
  },
  actions: {
    increment({ commit }) {
      commit('INCREMENT')
    },
    decrement({ commit }) {
      commit('DECREMENT')
    },
    login({ commit }, userData) {
      // Perform login API call
      return new Promise((resolve, reject) => {
        uni.request({
          url: 'https://api.example.com/login',
          method: 'POST',
          data: userData,
          success: (res) => {
            commit('SET_USER', res.data.user)
            resolve(res.data)
          },
          fail: (err) => {
            reject(err)
          }
        })
      })
    },
    fetchProducts({ commit }) {
      return new Promise((resolve, reject) => {
        uni.request({
          url: 'https://api.example.com/products',
          method: 'GET',
          success: (res) => {
            commit('SET_PRODUCTS', res.data)
            resolve(res.data)
          },
          fail: (err) => {
            reject(err)
          }
        })
      })
    }
  },
  getters: {
    doubleCount: state => state.count * 2,
    isLoggedIn: state => !!state.user,
    username: state => state.user ? state.user.name : 'Guest'
  }
})

export default store
  1. Register the store in main.js:
js
// main.js
import Vue from 'vue'
import App from './App'
import store from './store'

Vue.config.productionTip = false

App.mpType = 'app'

const app = new Vue({
  store,
  ...App
})
app.$mount()
  1. Use the store in components:
vue
<template>
  <view class="container">
    <view class="counter">
      <button @click="decrement">-</button>
      <text>{{ count }}</text>
      <button @click="increment">+</button>
    </view>
    <view class="double">Double: {{ doubleCount }}</view>
    
    <view class="user-info">
      <text>Welcome, {{ username }}</text>
      <button v-if="!isLoggedIn" @click="login">Login</button>
      <button v-else @click="logout">Logout</button>
    </view>
    
    <view class="products">
      <text class="section-title">Products</text>
      <button @click="loadProducts">Load Products</button>
      <view v-for="(product, index) in products" :key="index" class="product-item">
        <text>{{ product.name }} - ${{ product.price }}</text>
      </view>
    </view>
  </view>
</template>

<script>
import { mapState, mapGetters, mapActions } from 'vuex'

export default {
  computed: {
    ...mapState(['count', 'user', 'products']),
    ...mapGetters(['doubleCount', 'isLoggedIn', 'username'])
  },
  methods: {
    ...mapActions(['increment', 'decrement', 'login', 'fetchProducts']),
    logout() {
      this.$store.commit('SET_USER', null)
    },
    loadProducts() {
      this.fetchProducts()
        .then(() => {
          uni.showToast({
            title: 'Products loaded',
            icon: 'success'
          })
        })
        .catch(err => {
          uni.showToast({
            title: 'Failed to load products',
            icon: 'none'
          })
        })
    }
  }
}
</script>

Building and Deployment

Building for Different Platforms

Using HBuilderX

  1. Open your project in HBuilderX
  2. Click "Run" > "Run to [Platform]" where [Platform] is your target platform
  3. Follow the platform-specific instructions

Using CLI

bash
# Build for H5
npm run build:h5

# Build for WeChat Mini Program
npm run build:mp-weixin

# Build for App (Android/iOS)
npm run build:app-plus

# Build for Alipay Mini Program
npm run build:mp-alipay

# Build for Baidu Smart Program
npm run build:mp-baidu

# Build for ByteDance Mini Program
npm run build:mp-toutiao

Platform-Specific Deployment

WeChat Mini Program

  1. Build the project for WeChat Mini Program
  2. Open WeChat Developer Tools
  3. Import the project from the dist/dev/mp-weixin or dist/build/mp-weixin directory
  4. Test the mini program in the simulator
  5. Upload to WeChat for review and publication

H5 (Web)

  1. Build the project for H5
  2. Deploy the contents of the dist/dev/h5 or dist/build/h5 directory to your web server
  3. Configure your web server properly (e.g., set up proper MIME types, enable compression)

Native App (Android/iOS)

  1. Build the project for App
  2. Open the project in HBuilderX
  3. Click "Tools" > "App Package" > "Cloud Package" or "Local Package"
  4. Follow the packaging instructions
  5. Submit the generated APK/IPA to app stores

Advanced Topics

Conditional Compilation

uni-app supports conditional compilation to handle platform-specific code:

js
// Platform-specific code using preprocessor directives
const platform = 'unknown';

// #ifdef APP-PLUS
platform = 'App';
// #endif

// #ifdef H5
platform = 'H5';
// #endif

// #ifdef MP-WEIXIN
platform = 'WeChat Mini Program';
// #endif

// #ifdef MP-ALIPAY
platform = 'Alipay Mini Program';
// #endif

console.log(`Current platform: ${platform}`);

You can also use conditional compilation in templates and styles:

vue
<template>
  <view class="container">
    <!-- Common content for all platforms -->
    <text>This appears on all platforms</text>
    
    <!-- Platform-specific content -->
    <!-- #ifdef APP-PLUS -->
    <text>This appears only in the App</text>
    <!-- #endif -->
    
    <!-- #ifdef H5 -->
    <text>This appears only in H5</text>
    <!-- #endif -->
    
    <!-- #ifdef MP-WEIXIN -->
    <text>This appears only in WeChat Mini Program</text>
    <!-- #endif -->
  </view>
</template>

<style>
/* Common styles */
.container {
  padding: 20px;
}

/* Platform-specific styles */
/* #ifdef APP-PLUS */
.container {
  background-color: #f8f8f8;
}
/* #endif */

/* #ifdef H5 */
.container {
  background-color: #ffffff;
}
/* #endif */
</style>

Native Development

For performance-critical features, uni-app supports native development using nvue:

  1. Create an nvue file (e.g., pages/native/native.nvue)
  2. Use weex components and APIs for native rendering
vue
<template>
  <div class="container">
    <text class="title">Native Page</text>
    <div class="list">
      <div v-for="(item, index) in items" :key="index" class="list-item">
        <text class="item-text">{{ item }}</text>
      </div>
    </div>
  </div>
</template>

<script>
export default {
  data() {
    return {
      items: ['Item 1', 'Item 2', 'Item 3', 'Item 4', 'Item 5']
    }
  },
  created() {
    // Native page lifecycle
    console.log('Native page created')
  },
  methods: {
    // Methods
  }
}
</script>

<style>
/* Note: nvue only supports a subset of CSS */
.container {
  flex: 1;
  padding: 20px;
  background-color: #f8f8f8;
}

.title {
  font-size: 20px;
  margin-bottom: 20px;
}

.list {
  flex: 1;
}

.list-item {
  padding: 12px;
  border-bottom-width: 1px;
  border-bottom-color: #eeeeee;
}

.item-text {
  font-size: 16px;
}
</style>

Best Practices

Performance Optimization

  1. Use v-if and v-show appropriately:

    • Use v-if when the condition rarely changes
    • Use v-show when the element toggles frequently
  2. Optimize list rendering:

    • Always use :key with v-for
    • Avoid complex operations in v-for loops
    • Consider using virtual lists for long lists
  3. Lazy loading:

    • Load images only when they enter the viewport
    • Use uni.preloadPage() to preload pages that will likely be visited
  4. Reduce unnecessary re-renders:

    • Use computed properties for derived data
    • Avoid deep watchers when possible
    • Use functional components for simple UI elements
  5. Optimize startup time:

    • Minimize the size of the main bundle
    • Defer non-critical component loading
    • Use code splitting for large features

Security Best Practices

  1. Data validation:

    • Always validate user input on both client and server
    • Use parameterized queries to prevent SQL injection
    • Sanitize HTML content to prevent XSS attacks
  2. Secure storage:

    • Don't store sensitive information in local storage
    • Encrypt sensitive data before storing
    • Use secure HTTP-only cookies for authentication tokens
  3. API security:

    • Use HTTPS for all API requests
    • Implement proper authentication and authorization
    • Set appropriate CORS headers
  4. Code protection:

    • Obfuscate your code for production builds
    • Use source maps only in development
    • Implement app integrity checks

Project Organization

  1. Directory structure:

    my-uni-app/
    ├── api/                  # API services
    │   ├── user.js           # User-related API calls
    │   └── product.js        # Product-related API calls
    ├── components/           # Reusable components
    │   ├── common/           # Common UI components
    │   └── business/         # Business-specific components
    ├── pages/                # Application pages
    ├── static/               # Static assets
    ├── store/                # Vuex store modules
    ├── utils/                # Utility functions
    │   ├── request.js        # HTTP request wrapper
    │   └── validation.js     # Form validation helpers
    └── config/               # Configuration files
        ├── env.js            # Environment variables
        └── constants.js      # Application constants
  2. Naming conventions:

    • Use PascalCase for component names
    • Use kebab-case for file names
    • Use camelCase for variables and functions
    • Use UPPER_SNAKE_CASE for constants
  3. Code splitting:

    • Split large components into smaller ones
    • Use dynamic imports for code splitting
    • Create separate modules for different features

Troubleshooting

Common Issues and Solutions

  1. White screen on startup:

    • Check for JavaScript errors in the console
    • Verify that all required permissions are granted
    • Check for infinite loops or blocking operations
  2. Styling inconsistencies across platforms:

    • Use platform-specific styles with conditional compilation
    • Test on all target platforms regularly
    • Use relative units (rpx) instead of absolute units
  3. Network request failures:

    • Check network connectivity
    • Verify API endpoints and parameters
    • Check for CORS issues in H5 mode
    • Add proper error handling
  4. Performance issues:

    • Use the Vue DevTools to identify bottlenecks
    • Optimize rendering with v-once for static content
    • Reduce unnecessary component nesting
    • Use native components (nvue) for performance-critical screens

Debugging Techniques

  1. Console logging:

    js
    console.log('Debug info:', variable)
    console.error('Error occurred:', error)
  2. Using the debugger statement:

    js
    function problematicFunction() {
      debugger; // Execution will pause here when dev tools are open
      // Rest of the function
    }
  3. Platform-specific debugging:

    • WeChat DevTools for WeChat Mini Program
    • Chrome DevTools for H5
    • HBuilderX debugging for App
  4. Remote debugging:

    • Enable remote debugging in HBuilderX
    • Connect to the device using the provided URL
    • Use the network inspector to monitor requests

Resources and Community

Official Resources

Community Resources

Learning Resources

Next Steps

Now that you're familiar with uni-app, you might want to explore:

Connecting Multiple Platforms, Empowering Innovation