跪拜 Guibai
← Back to the summary

The H5 Developer's Field Manual for uni-app

📌 Who is this for? You can write HTML/CSS/JS, but you are touching uni-app for the first time and know nothing about Vue, mini programs, or cross-platform development. This article is based on a deep reorganization of the uni-app official documentation 'Vernacular uni-app', using plain language to help you complete the cognitive upgrade from a "traditional web developer" to a "cross-platform developer."

📌 Reading gains: Figure out exactly how uni-app differs from traditional H5, why it differs, and how to write code correctly. All knowledge points are strictly organized according to the official documentation to ensure authority and no pitfalls.


1. First, figure out: What exactly is uni-app?

In one sentence: uni-app is a cross-platform development framework that lets you "write code once, run on all platforms."

You write one set of code, and it can compile out:

💡 Analogy: You can think of uni-app as a "universal translator." You write a manuscript in "Chinese" (Vue syntax), and it translates it into English, Japanese, French... every platform can understand it.

But note—the translator is not omnipotent. The "Chinese" you write must conform to its grammatical rules, otherwise the translated output will be wrong. So, if you previously wrote traditional web pages (H5), you will find that uni-app's writing style is very different from before.

This article is to help you smoothly migrate your "old knowledge" to the "new world."


2. The network model has changed: From "Server-Side Rendering" to "Front-End/Back-End Separation"

2.1 How does traditional H5 work?

In early web development, the backend (server) directly stuffed data into the HTML and then returned the whole thing to the browser. What the user saw was a "webpage already filled with content."

This model is called B/S mode (Browser/Server).

📖 What is B/S mode? B/S stands for Browser/Server architecture. The user only needs a browser; all business logic and data are processed on the server side, and the browser is only responsible for "display." The counterpart is C/S mode (Client/Server), like QQ or WeChat desktop apps on your computer, which require installing dedicated client software.

Simply put: B/S = open a browser to use; C/S = must install software to use.

In the traditional B/S mode, the backend uses technologies like JSP, PHP, ASP.NET to "render" data into HTML and then return it. Front-end and back-end code are mixed together.

2.2 How does uni-app work now?

uni-app adopts a front-end/back-end separation architecture:

The page loading process becomes:

1. The front-end first renders an "empty shell" page
2. After the page loads, JS initiates a network request (uni.request)
3. The backend returns JSON data
4. The front-end receives the data and fills it into the page

📖 What is JSON? JSON (JavaScript Object Notation) is a lightweight data format that looks like this: {"name": "Zhang San", "age": 25}. It is the current "universal language" for front-end/back-end data exchange.

📖 What is an HTTP request? It is the action of the browser/client "asking for data" from the server. Typing a URL into the browser address bar and hitting enter is essentially sending an HTTP request. In code, we use uni.request() to manually initiate requests.

🍔 An analogy: Before, the restaurant brought the dish directly to your table (server-side rendered and then given to you); now, the restaurant gives you an empty plate and a menu, and you go to the counter to get the food yourself (the front-end actively requests data and fills it onto the page itself).

2.3 How to use it in code?

// Initiating a network request in uni-app
uni.request({
  url: 'https://api.example.com/user/list',  // Backend API address
  method: 'GET',
  success: (res) => {
    // res.data is the JSON data returned by the backend
    this.userList = res.data;
  }
});

⚠️ Note: This uses uni.request(), not the $.ajax() (jQuery) or fetch() you were familiar with before. In uni-app, all APIs start with uni., which is for cross-platform compatibility. This will be detailed later.


3. File types have changed: From .html to .vue

3.1 The files you write are no longer HTML

Comparison Item Traditional H5 uni-app
File extension .html .vue
What you write during development HTML tags Vue template syntax
What it actually is at runtime HTML runs directly Converted by a compiler into code for each platform

3.2 What are "compiler" and "runtime"?

These are core concepts for understanding uni-app:

📖 What is a compiler? It "translates" the .vue source code you write into code that each platform can recognize. For example, compiling to WeChat Mini Program generates wxml + wxss + js; compiling to H5 generates html + css + js. You write once, it translates multiple times.

📖 What is a Runtime? When the compiled code actually executes on a device, it needs a set of "runtime environments" to support it. For example, Vue's reactivity system, component lifecycle management, etc., all belong to the runtime category.

🍔 Analogy: The compiler is like a "translator," translating your Chinese manuscript into various languages; the runtime is like "simultaneous interpretation equipment," ensuring the translated content can be "played back" correctly.


4. The internal file structure has changed: From "one building" to "three rooms"

4.1 The old HTML file

<!DOCTYPE html>
<html>
  <head>
    <script src="js/jquery.js"></script>
    <style>
      body { background: #fff; }
    </style>
  </head>
  <body>
    <div id="app">Page Content</div>
    <script>
      // JS Logic
    </script>
  </body>
</html>

Everything—structure, style, logic—is crammed into one big <html> shell, mixed together.

4.2 The current Vue Single File Component (SFC)

📖 What is SFC? SFC stands for Single File Component. It is a core concept of Vue: one .vue file = one component = one functional module. Each .vue file contains three top-level code blocks: <template>, <script>, <style>.

<template>
  <!-- ⚠️ Must have one root element (like view), and only one! -->
  <view class="container">
    <text>{{ message }}</text>
    <button @click="changeText">Click me to change text</button>
  </view>
</template>

<script>
export default {
  data() {
    return {
      message: 'Hello, uni-app!'
    };
  },
  methods: {
    changeText() {
      this.message = 'Text has been changed!';
    }
  }
}
</script>

<style scoped>
/* scoped means the style only applies to the current component, won't pollute other pages */
.container {
  padding: 20rpx;
}
</style>

🏠 Analogy: Before, it was a "studio apartment"—living room, bedroom, kitchen all in one space, interfering with each other. Now, it's a "three-bedroom apartment"—<template> is the living room (holds the interface structure), <script> is the study (holds business logic), <style> is the walk-in closet (holds styles), each with its own role, not interfering with each other.

4.3 The responsibilities of the three blocks (must remember)

Code Block Function Analogy
<template> Defines what the page looks like (structure) The floor plan of a house
<script> Defines how the page moves (logic) The electrical system in the house
<style> Defines whether the page looks good (style) The decoration of the house

4.4 A few key rules

  1. <template> must have one root element, and only one. Usually wrap with <view>.
  2. <script> must export default {} , this is ES6 module syntax, meaning "export this component."
  3. It is recommended to add scoped in <style> to prevent styles from leaking to other components.

📖 What are ES6 modules and export default? ES6 (ECMAScript 2015) was a major upgrade to JavaScript, introducing modular syntax. export default means "export this object as the default export," which other files can use after importing via import. You can understand it as "the product this file provides to the outside world."


5. The way external files are referenced has changed

5.1 Importing JS files

Before:

<script src="js/jquery.js"></script>
<script src="js/bootstrap.js"></script>

Now:

// Method 1: CommonJS specification (require)
const util = require('@/common/util.js');
const result = util.formatTime(new Date());

// Method 2: ES6 module specification (import) — Recommended
import { formatTime } from '@/common/util.js';
const result = formatTime(new Date());

📖 What is the @ symbol? In uni-app, @ represents the root directory of the project. @/common/util.js equals "util.js inside the common folder under the project root directory." Writing paths this way ensures no errors no matter how deeply nested the file is.

📖 What is the difference between require and import? Both are syntax for "importing external modules." require is the CommonJS specification (Node.js style), import is the ES6 module specification. In uni-app, using import is recommended because the compiler has better support for ES6 modules and supports Tree Shaking (automatically removing unused code to reduce bundle size).

5.2 Importing CSS files

Before:

<link href="css/bootstrap.css" rel="stylesheet" />

Now:

<style>
@import "@/common/uni.css";
</style>

⚠️ Note: The @import statement must be written at the very top inside the <style> tag, followed by a semicolon ;.

5.3 Where to write global styles?

There is an App.vue file in the project root directory, which is the "entry component" of the entire application.

<!-- App.vue -->
<script>
export default {
  onLaunch() {
    console.log('App launched');
  }
}
</script>

<style>
/* Styles written here are global and will take effect on all pages */
page {
  background-color: #f5f5f5;
}
</style>

⚠️ Important: There is no <template> in App.vue! It does not define any UI, only responsible for global logic and global styles. The UI of pages is defined by the various .vue files in the pages/ directory.

5.4 Component import (Key point!) — easycom mechanism explained

📖 What is a "component"? A component is packaging a section of "UI + logic + style" into a reusable module. For example, if you make a "star rating" UI, after encapsulating it into a component, any page can use it directly without writing repetitive code.

uni-app provides the easycom mechanism, which greatly simplifies component importing.

Traditional way (requires manual import + registration):

<script>
import MyComponent from '@/components/my-component.vue';

export default {
  components: {
    MyComponent  // Register component
  }
}
</script>

<template>
  <my-component />
</template>

easycom way (zero configuration, use directly):

📖 What is easycom? easycom is an automatic component import mechanism provided by uni-app. It allows you to skip manual import and manual registration; just write the component tag name in the template, and the compiler will automatically find and load the component. It translates to "easy component usage."

Core path rule (must be strictly followed):

components/component-name/component-name.vue

That is to say: the folder name and file name must be exactly the same, and both are in lowercase with hyphens (kebab-case) style.

Correct examples:

components/my-button/my-button.vue     →  Use <my-button /> in template
components/user-card/user-card.vue     →  Use <user-card /> in template
components/uni-list/uni-list.vue       →  Use <uni-list /> in template

Incorrect examples (will not take effect):

components/MyButton.vue                 ← Missing folder with the same name, ❌
components/my-button/index.vue          ← File name is not my-button.vue, ❌
components/my-button/MyButton.vue       ← Case mismatch, ❌

📖 Supplementary rule: If a component is installed under the uni_modules directory, easycom also supports automatic recognition, with the path format:

uni_modules/plugin-id/components/component-name/component-name.vue

For example, if you installed uni-ui through the plugin marketplace, it will automatically register components like uni-badge, uni-card, and you can use them directly by writing the tag name in the template.

Why would traditional Vue developers be confused?

If you have developed Web projects with Vue before, you are definitely used to import + components registration. When first using uni-app, seeing others write <uni-list> directly in the template without any import will instinctively make you think "this can't possibly work."

The answer is easycom. During the compilation phase, the compiler scans the components/ and uni_modules/ directories and automatically completes the import and registration. You just need to ensure the path conforms to the specification.

💡 Memory tip: "Same-name folder + same-name file = use directly."


6. A major tag overhaul: HTML tags → uni-app components

This is the most intuitive change that most affects daily coding. The HTML tags you are familiar with need to be replaced with corresponding components in uni-app.

6.1 Why can't HTML tags be used directly?

Because uni-app needs to be cross-platform. Tags like <div>, <span> are only recognized by browsers, not by WeChat Mini Programs or native Apps. So uni-app defines a set of cross-platform universal component tags, and the compiler is responsible for translating them into the native writing style of each platform.

📖 Tags vs Components, what's the difference?

  • Tag: "Factory built-in" to the browser, limited in number and fixed, like <div>, <p>, <img>.
  • Component: A UI module that developers can freely encapsulate and extend, like a function, packaging a piece of UI + logic for repeated use. Component tag names are custom, like <my-button>, <user-card>.

6.2 Core tag comparison table (must memorize)

Traditional HTML Tag uni-app Component Description
<div> <view> The most basic container component, equivalent to a "box"
<span> / <p> / <font> <text> Text display
<a href="..."> <navigator url="..."> Page navigation
<img src="..."> <image src="..."> Image display
<select> <picker> Dropdown selector
<iframe> <web-view> Embed external webpage
<ul> / <li> / <ol> ❌ Does not exist Use <view> nesting to implement lists
<input type="radio"> <radio> / <radio-group> Single selection
<input type="checkbox"> <checkbox> / <checkbox-group> Multiple selection
<input type="date"> <picker mode="date"> Date picker
<audio> Not recommended to use tag Use uni.createInnerAudioContext() API instead

6.3 uni-app's unique "mobile" components

These are not found in traditional web pages, designed specifically for mobile scenarios:

Component Use Use Case
<scroll-view> Scrollable area Lists, long content areas
<swiper> + <swiper-item> Carousel Homepage Banner
<switch> Switch "Enable notifications" on settings page
<slider> Slider Volume adjustment, brightness adjustment
<progress> Progress bar Download progress, loading progress
<camera> Camera Taking photos, scanning codes
<map> Map Location display, navigation
<video> Video player Video playback
<cover-view> / <cover-image> Overlay layer Overlay on top of native components like <video>, <map>

⚠️ About <cover-view>: On the mini-program side, <video>, <map>, <camera> are native components with the highest level, ordinary <view> cannot cover them. If you need to display buttons or text on top of a video, you must use <cover-view> and <cover-image>.

6.4 A complete comparison example

Previously writing an image list (HTML):

<div class="list">
  <img src="pic1.jpg" alt="Image 1" />
  <img src="pic2.jpg" alt="Image 2" />
</div>

Now writing in uni-app:

<template>
  <view class="list">
    <image src="/static/pic1.jpg" mode="widthFix" />
    <image src="/static/pic2.jpg" mode="widthFix" />
  </view>
</template>

<style>
.list {
  display: flex;
  flex-direction: column;
  padding: 20rpx;
}
image {
  width: 100%;
  margin-bottom: 20rpx;
}
</style>

💡 Note mode="widthFix": This is an attribute of the <image> component, meaning "fixed width, height adapts proportionally." The traditional <img> tag does not have this attribute and requires CSS to achieve.


7. Three major changes in JS (Core focus!)

7.1 The runtime environment has changed—Browser-specific APIs can no longer be used

Comparison Item Traditional H5 (in Browser) uni-app (App/Mini Program side)
Where JS runs Browser's JS engine V8 engine (App side) / Each mini program engine
window object ✅ Available ❌ Not available
document object ✅ Available ❌ Not available
navigator object ✅ Available ❌ Not available
location object ✅ Available ❌ Not available
localStorage ✅ Available ❌ Not available (use uni.setStorage)
Cookie ✅ Available ❌ Not available
jQuery / DOM manipulation libraries ✅ Available ❌ Not available

📖 What are window, document?

  • window: The "global object" provided by the browser, representing the current browser window. alert(), setTimeout(), location all hang off it.
  • document: Represents the DOM tree (Document Object Model) of the current webpage, through which you can find and manipulate any element on the page.

On the App and Mini Program side, there is no browser, so naturally there is no window or document.

⚠️ The only exception: When you compile uni-app to H5, the runtime environment is the browser, and window, document are available. But for cross-platform compatibility, it is recommended to never use them directly.

7.2 No more DOM manipulation, switch to "data binding" (MVVM)

This is the most core mental shift, please make sure to understand it thoroughly.

📖 What is DOM? DOM (Document Object Model) is a "tree" generated by the browser after parsing HTML. Each HTML tag is a node on the tree. Through methods like document.getElementById(), document.querySelector(), you can "find" a certain node and then modify its content, style, attributes.

📖 What is MVVM? MVVM stands for Model-View-ViewModel:

  • Model: Data (e.g., message: "Hello")
  • View: The interface the user sees
  • ViewModel: The "bridge" connecting data and the interface (in Vue, it's the binding relationship between data() and the template)

Core idea: You only need to modify the data, and the interface will update automatically. You don't need to manually "find an element and then change it."

❌ The old way (DOM manipulation):

<span id="myText">123</span>
<button onclick="changeText()">Modify</button>

<script>
function changeText() {
  // Step 1: Find the element by id
  // Step 2: Modify the element's text content
  document.getElementById("myText").innerText = "789";
}
</script>

You need to manually find the element → manually modify it.

✅ The new way (data binding):

<template>
  <view>
    <text>{{ message }}</text>
    <button @click="changeText">Modify</button>
  </view>
</template>

<script>
export default {
  data() {
    return {
      message: '123'  // ← This is "data"
    };
  },
  methods: {
    changeText() {
      this.message = '789';  // ← Just change the data, the interface updates automatically!
    }
  }
}
</script>

You just need to modify the variable in data, and all places in the interface referencing this variable will automatically update. No need to find elements, no need to manipulate DOM.

🍔 Analogy: Before, you were driving a "manual transmission"—every gear shift required you to press the clutch and move the gear stick yourself (find element, change attribute). Now, you are driving an "automatic transmission"—you just press the accelerator (change data), and the gearbox automatically shifts for you (updates the interface).

Key rules:

Rule Description
Data that needs to be bound to the interface must be written in the return {} of data() Otherwise, it cannot be recognized in the template
Modify data by direct assignment: this.xxx = newValue No need for WeChat Mini Program's setData()
Event binding uses @eventName="methodName" Like @click, @input, @longpress
Methods are defined in methods: {} Called via this.methodName()

📖 What is this? In a Vue component, this points to the current component instance. Through this, you can access data in data and call methods in methods. For example, this.message accesses the message variable in data.

7.3 All APIs have been replaced

The browser APIs you used before are all replaced with the uni.xxx() form in uni-app:

What you want to do Traditional H5 way uni-app way
Popup alert alert('Notice') uni.showToast({ title: 'Notice' })
Confirmation dialog confirm('Are you sure?') uni.showModal({ title: 'Notice', content: 'Are you sure?' })
Network request $.ajax() or fetch() uni.request()
Local storage (save) localStorage.setItem(k, v) uni.setStorageSync(k, v)
Local storage (get) localStorage.getItem(k) uni.getStorageSync(k)
Page navigation location.href = 'xxx' uni.navigateTo({ url: 'xxx' })
Go back to previous page history.back() uni.navigateBack()
Get screen width window.innerWidth uni.getSystemInfoSync().windowWidth

📖 Naming convention: uni-app's APIs basically changed WeChat Mini Program's wx.xxx to uni.xxx. If you have read WeChat Mini Program documentation, you will find it very familiar.

Actual code example:

// Initiate a network request
uni.request({
  url: 'https://api.example.com/data',
  method: 'GET',
  success: (res) => {
    console.log('Request successful:', res.data);
  },
  fail: (err) => {
    console.log('Request failed:', err);
  }
});

// Local storage
uni.setStorageSync('username', 'Zhang San');
const name = uni.getStorageSync('username'); // 'Zhang San'

// Popup dialog
uni.showModal({
  title: 'Notice',
  content: 'Are you sure you want to delete?',
  success: (res) => {
    if (res.confirm) {
      // User clicked "Confirm"
    }
  }
});

8. Page navigation explained: Five APIs each have their own role (Important!)

In uni-app, page navigation is no longer a simple location.href, but has 5 dedicated APIs, each with different use cases. Mixing them up will cause problems like "can't go back to the page" or "navigation has no response."

8.1 Comparison table of five navigation methods

API Function Page stack change Can pass params? Use case
uni.navigateTo Keep current page, open a new page Stack +1 layer Enter detail page from list, enter settings page from homepage
uni.redirectTo Close current page, open a new page Stack unchanged (replaced) Jump to homepage after login success (don't want user to return to login page)
uni.switchTab Close all non-Tab pages, switch to a Tab page Clear non-Tab stack Bottom navigation bar switch (Home/Mine/Messages)
uni.reLaunch Close all pages, open specified page Clear all stacks Return to login page after logout, reset entire app state
uni.navigateBack Go back to previous page (or N pages back) Stack -1 (or -N) layers User clicks back, return after submission

📖 What is a "page stack"? A page stack is a "Last In, First Out" structure. Every time a new page is opened, it is pushed onto the top of the stack; every time you go back, the top is popped off. Like a stack of plates—you can only take from the top. uni.navigateTo is "adding one" to this stack of plates, uni.navigateBack is "taking the top one away."

⚠️ Note: On the WeChat Mini Program side, the page stack has a maximum of 10 layers, beyond which you can no longer navigateTo.

8.2 Detailed explanation of each

uni.navigateTo—Most commonly used, "forward"

// Navigate from homepage to detail page (keep homepage, user can return)
uni.navigateTo({
  url: '/pages/detail/detail?id=123&title=hello'
});

Rules:

uni.redirectTo—"Replace", does not keep current page

// Jump to homepage after login success (user cannot return to login page)
uni.redirectTo({
  url: '/pages/home/home'
});

Rules:

🍔 Analogy: navigateTo is like "opening a new tab" (the old page is still there); redirectTo is like "typing a new URL in the current tab" (the old page is gone).

uni.switchTab—Specifically for switching Tab pages

// Switch to the "Mine" page on the bottom navigation bar
uni.switchTab({
  url: '/pages/user/user'
});

Rules:

⚠️ Common pitfall: If you use uni.navigateTo to jump to a tabBar page, it will directly error page is not found. You must use uni.switchTab.

uni.reLaunch—"Nuclear option" reset

// Log out, return to login page (close all pages)
uni.reLaunch({
  url: '/pages/login/login'
});

Rules:

uni.navigateBack—"Go back"

// Go back to the previous page (default delta=1)
uni.navigateBack();

// Go back two layers (if there are at least two layers in the stack)
uni.navigateBack({ delta: 2 });

Rules:

8.3 Practical scenario decision tree

I want to navigate to a new page?
│
├── Is the target page a tabBar page?
│   ├── Yes → Use uni.switchTab (cannot pass params)
│   └── No ↓
│
├── Does the user need to return to the current page?
│   ├── Yes → Use uni.navigateTo
│   └── No (current page can be closed) → Use uni.redirectTo
│
├── Need to close all pages and start over?
│   └── Yes → Use uni.reLaunch
│
└── User clicked the back button?
    └── Use uni.navigateBack

💡 One-sentence memory: 90% of daily development uses navigateTo, switch bottom Tab uses switchTab, login/logout scenarios use redirectTo or reLaunch.


9. Changes in CSS

Good news: Standard CSS syntax can basically all be used. But there are a few important differences:

9.1 Selector limitations

Selector Supported? Description
.class-name Class selector, most commonly used
#id ID selector
tag Tag selector, like view {}
* (wildcard) Not supported
body Changed to page
Descendant selector .a .b Supported
Child selector .a > .b ⚠️ Supported on some platforms

⚠️ Key point: Previously you wrote body { margin: 0; }, now you need to write page { margin: 0; }. Because on non-H5 platforms, there is no concept of body, page represents the entire page.

9.2 Units: Use rpx instead of px

📖 What is rpx? rpx (responsive pixel) is an adaptive unit introduced by uni-app.

Conversion rule: Regardless of the screen, the screen width is defined as = 750rpx.

  • If the design draft is 750px wide, then 1px = 1rpx, direct conversion.
  • If the design draft is 375px wide (iPhone 6/7/8), then 1px = 2rpx.

Benefit: You don't need to write any media queries (@media), rpx will automatically adapt to all screen widths.

/* Old way */
.box {
  width: 100px;
  font-size: 14px;
  padding: 10px 20px;
}

/* New recommended way (assuming design draft is 750px wide) */
.box {
  width: 200rpx;
  font-size: 28rpx;
  padding: 20rpx 40rpx;
}

💡 Practical usage suggestion: If your UI design draft is 750px wide, directly replace px with rpx. If it's 375px wide, multiply the value by 2 and write rpx.

9.3 Layout: Flex is strongly recommended

📖 What is Flex layout? Flex (Flexible Box) is a one-dimensional layout method introduced in CSS3. By setting display: flex on the parent element, child elements will automatically arrange, supporting alignment, distribution, wrapping, etc. It is currently the most mainstream and best-compatible layout scheme for mobile.

/* Horizontal arrangement, justified to ends, vertically centered */
.row {
  display: flex;
  flex-direction: row;
  justify-content: space-between;
  align-items: center;
}

/* Vertical arrangement */
.column {
  display: flex;
  flex-direction: column;
}

✅ Flex layout is perfectly supported on all uni-app platforms (H5, App, various mini programs), use with confidence.

9.4 Other notes

Note Description
Background images / Font files Recommended not to exceed 40KB, otherwise it affects compilation performance. For large images, recommend using network URLs or base64
position: fixed Behaves differently on some mini-program platforms, use with caution
Percentage height Requires the parent element to have an explicit height to take effect

10. Project structure and page management

10.1 Project directory structure (must understand)

├── pages/                  ← All pages go here
│   ├── index/
│   │   └── index.vue       ← Homepage
│   └── user/
│       └── user.vue        ← User page
├── components/             ← Custom components (easycom scan directory)
├── static/                 ← Static assets (images, fonts, etc., not compiled)
├── uni_modules/            ← Plugins/component libraries (easycom also scans here)
├── App.vue                 ← App entry (global logic + global styles)
├── main.js                 ← App initialization file
├── pages.json              ← Page routing and window configuration (Important!)
├── manifest.json           ← App configuration (appid, version, permissions, etc.)
└── uni.scss                ← Global SCSS variables

10.2 pages.json—Your "page dispatch center"

📖 In traditional web pages, navigation between pages relies on <a href="xxx.html"> links. In uni-app, every page must be registered in pages.json, otherwise it cannot be accessed.

{
  "pages": [
    {
      "path": "pages/index/index",
      "style": {
        "navigationBarTitleText": "Home"
      }
    },
    {
      "path": "pages/user/user",
      "style": {
        "navigationBarTitleText": "Profile"
      }
    }
  ],
  "globalStyle": {
    "navigationBarTextStyle": "black",
    "navigationBarTitleText": "My App",
    "navigationBarBackgroundColor": "#ffffff"
  },
  "tabBar": {
    "list": [
      {
        "pagePath": "pages/index/index",
        "text": "Home",
        "iconPath": "static/home.png",
        "selectedIconPath": "static/home-active.png"
      },
      {
        "pagePath": "pages/user/user",
        "text": "Mine",
        "iconPath": "static/user.png",
        "selectedIconPath": "static/user-active.png"
      }
    ]
  }
}

Key rules:

Rule Description
The first item in the pages array is the homepage No extra configuration needed
Newly created pages must be registered here Otherwise, the route cannot be found
navigationBarTitleText Title of the top navigation bar of the page
tabBar Bottom tab bar (similar to WeChat's bottom "Chats/Contacts/Discover/Me")
Pages in tabBar.list can only be navigated to using switchTab Using navigateTo will cause an error

10.3 Correspondence with Mini Programs

If you have read WeChat Mini Program documentation, this correspondence can help you understand quickly:

WeChat Mini Program uni-app Description
app.json (page config part) pages.json Manages page routing and window styles
app.json (app config part) manifest.json Manages appid, version number, permissions
app.js + app.wxss App.vue Global logic + Global styles
.wxml <template> in .vue Page structure
.wxss <style> in .vue Page styles
.js <script> in .vue Page logic

11. Lifecycle—The process of a page from birth to death

📖 What is a lifecycle? Every page/component goes through a series of stages from "creation → display → hide → destruction". At each stage, uni-app automatically calls the corresponding function (hook), and you can write specific logic inside these functions.

Page lifecycle (written in the <script> of .vue):

Hook Function Trigger Timing Typical Use
onLoad(options) When the page loads (executes only once) Receive parameters, initiate initial requests
onShow() Every time the page is displayed Refresh data (when returning from another page)
onReady() When the page's initial rendering is complete Operate canvas, initialize map
onHide() When the page is hidden (navigated to another page) Pause timers, save temporary data
onUnload() When the page is unloaded (completely closed) Clear timers, release resources
<script>
export default {
  onLoad(options) {
    // options contains the parameters passed from the previous page
    // e.g.: uni.navigateTo({ url: '/pages/detail/detail?id=123' })
    // Here options.id === '123'
    console.log('Page loaded, parameters:', options);
    this.loadData();
  },
  onShow() {
    console.log('Page displayed');
  },
  methods: {
    loadData() {
      // Initiate request to get data
    }
  }
}
</script>

⚠️ Note: These lifecycle hooks (onLoad, onShow, etc.) are uni-app extensions, written directly inside export default {}, at the same level as data, methods, not inside methods!


12. A summary table: Complete migration checklist from H5 to uni-app

No. Traditional H5 uni-app Note
1 .html file .vue file Single File Component
2 <div> <view> Container
3 <span> / <p> <text> Text
4 <img> <image> Image
5 <a> <navigator> Navigation
6 document.getElementById() Data binding (MVVM) No more DOM manipulation
7 onclick="fn()" @click="fn" Event binding
8 alert() / confirm() uni.showToast() / uni.showModal() Popups
9 $.ajax() / fetch() uni.request() Network request
10 localStorage uni.setStorageSync() / uni.getStorageSync() Local storage
11 location.href uni.navigateTo() Page navigation
12 history.back() uni.navigateBack() Go back
13 px / rem rpx Size unit
14 <script src="..."> import / require Import JS
15 <link rel="stylesheet"> @import Import CSS
16 body selector page selector Global style
17 URL routing / Links pages.json config Page management
18 Manual import + register components easycom auto-recognition Component import

13. Study advice for beginners

If you are a newcomer familiar with H5 but haven't touched Vue and mini programs, just remember three sentences:

  1. Don't manipulate DOM, just change the data. This is the most core mental shift. Once understood, everything else becomes clear.
  2. Swap one set of tags, swap one set of APIs. But the programming mindset remains the same, only the "syntax" differs. It's like switching from writing a Chinese essay to an English essay—the ideas are the same, the words and grammar are different.
  3. Look at pages.json for all page configuration. It is your "page dispatch center"; creating new pages, configuring the navigation bar, setting up the TabBar all happen here.

Recommended learning path:

Step 1: Get a uni-app project running (create with HBuilderX)
    ↓
Step 2: Understand the three-part structure of a .vue file (template / script / style)
    ↓
Step 3: Master data binding (data → template's {{}} syntax)
    ↓
Step 4: Learn common components (view, text, image, button, input)
    ↓
Step 5: Learn page navigation and parameter passing (navigateTo + onLoad)
    ↓
Step 6: Learn network requests (uni.request)
    ↓
Step 7: Learn list rendering (v-for) and conditional rendering (v-if)
    ↓
Step 8: Start a complete small project (like a Todo List, news list)

Final words

The learning curve for uni-app is not steep, especially for those with an HTML/CSS/JS foundation. It is essentially Vue syntax + a set of cross-platform components and APIs. Once you understand Vue's data binding and componentization concepts, the rest is just getting familiar with the differences across platforms and uni-app's specific APIs.

Don't be afraid of "differences," embrace "differences." It is precisely these differences that allow uni-app to achieve writing one set of code that runs on all platforms, greatly improving development efficiency.

Wishing you a smooth journey on the road of cross-platform development! 🚀


📚 References:

📝 This article is an original technical summary, deeply reorganized based on official documentation and personal understanding. All technical points are strictly based on the uni-app official documentation to ensure accuracy and authority. Please indicate the source when reprinting.


If this article was helpful to you, welcome to like, bookmark, and follow! Feel free to communicate in the comments if you have questions~ 👋