Skip to content

Global Configuration

In uni-app development, global configuration refers to application-level settings, including basic application information, page routing, window styles, permission requests, etc. This guide will detail global configuration methods and common configuration items in uni-app.

pages.json

pages.json is the global configuration file for uni-app projects, used to configure uni-app globally, determining page file paths, window styles, native navigation bars, native bottom tabbar, etc.

Basic Structure

A basic pages.json file structure looks like this:

json
{
  "pages": [{
    "path": "pages/index/index",
    "style": {
      "navigationBarTitleText": "Home"
    }
  }, {
    "path": "pages/detail/detail",
    "style": {
      "navigationBarTitleText": "Detail"
    }
  }],
  "globalStyle": {
    "navigationBarTextStyle": "white",
    "navigationBarTitleText": "uni-app",
    "navigationBarBackgroundColor": "#007AFF",
    "backgroundColor": "#F8F8F8"
  },
  "tabBar": {
    "color": "#7A7E83",
    "selectedColor": "#007AFF",
    "borderStyle": "black",
    "backgroundColor": "#ffffff",
    "list": [{
      "pagePath": "pages/index/index",
      "iconPath": "static/tab-home.png",
      "selectedIconPath": "static/tab-home-active.png",
      "text": "Home"
    }, {
      "pagePath": "pages/mine/mine",
      "iconPath": "static/tab-mine.png",
      "selectedIconPath": "static/tab-mine-active.png",
      "text": "Mine"
    }]
  }
}

Main Configuration Items

1. pages

The pages array is used to configure application page routes, with each item being an object corresponding to a page.

json
"pages": [{
  "path": "pages/index/index", // Page path
  "style": {                   // Page window appearance
    "navigationBarTitleText": "Home", // Navigation bar title
    "enablePullDownRefresh": true     // Enable pull-to-refresh
  }
}]

TIP

The first item in the pages array represents the application's default startup page.

2. globalStyle

globalStyle is used to set the application's global styles, which will apply to every page. If a page has specific style requirements, it can be configured separately in the page's style, which will override global styles.

json
"globalStyle": {
  "navigationBarTextStyle": "white",        // Navigation bar title color, only supports black/white
  "navigationBarTitleText": "uni-app",      // Navigation bar title text
  "navigationBarBackgroundColor": "#007AFF", // Navigation bar background color
  "backgroundColor": "#F8F8F8",             // Window background color
  "backgroundTextStyle": "light",           // Pull-to-refresh background font and loading icon style, only supports dark/light
  "enablePullDownRefresh": false,           // Enable pull-to-refresh
  "usingComponents": {}                     // Reference mini-program components
}

3. tabBar

tabBar is used to configure the application's bottom tab bar, with a minimum of 2 and maximum of 5 tabs.

json
"tabBar": {
  "color": "#7A7E83",            // Default text color on tabs
  "selectedColor": "#007AFF",    // Text color when tab is selected
  "borderStyle": "black",        // Color of tabbar top border, optional values: black/white
  "backgroundColor": "#ffffff",  // Tab background color
  "list": [{                     // Tab list, minimum 2, maximum 5
    "pagePath": "pages/index/index", // Page path
    "iconPath": "static/tab-home.png", // Image path, recommended size 81px * 81px
    "selectedIconPath": "static/tab-home-active.png", // Selected image path
    "text": "Home"               // Tab button text
  }],
  "position": "bottom"           // Optional values: bottom, top
}

4. condition

condition is used to enable specific page scenario values for development and debugging convenience.

json
"condition": {
  "current": 0,                  // Currently active mode (list index)
  "list": [{
    "name": "Detail Page",       // Mode name
    "path": "pages/detail/detail", // Startup page
    "query": "id=1"              // Startup parameters
  }]
}

5. subPackages

subPackages is used for subpackage loading to optimize mini-program startup speed.

json
"subPackages": [{
  "root": "pagesA",              // Subpackage root directory
  "pages": [{                    // Subpackage page paths
    "path": "list/list",
    "style": {
      "navigationBarTitleText": "List"
    }
  }]
}]

6. preloadRule

preloadRule is used to configure subpackage preload rules.

json
"preloadRule": {
  "pages/index/index": {
    "network": "all",            // Preload under specified network, optional values: all (no network limit), wifi (only under wifi)
    "packages": ["pagesA"]       // Subpackage root or name to preload after entering page
  }
}

7. easycom

easycom is used to configure component auto-import rules, eliminating the need to manually import components in pages.

json
"easycom": {
  "autoscan": true,              // Enable automatic scanning
  "custom": {                    // Custom scanning rules
    "^u-(.*)": "@/uview-ui/components/u-$1/u-$1.vue"
  }
}

manifest.json

manifest.json is the application configuration file used to specify application name, icon, permissions, and other information.

Basic Structure

json
{
  "name": "Application Name",
  "appid": "",
  "description": "Application Description",
  "versionName": "1.0.0",
  "versionCode": "100",
  "transformPx": false,
  "app-plus": {
    "usingComponents": true,
    "nvueCompiler": "uni-app",
    "splashscreen": {
      "alwaysShowBeforeRender": true,
      "waiting": true,
      "autoclose": true,
      "delay": 0
    },
    "modules": {},
    "distribute": {
      "android": {
        "permissions": [
          "<uses-permission android:name=\"android.permission.CHANGE_NETWORK_STATE\"/>"
        ]
      },
      "ios": {},
      "sdkConfigs": {}
    }
  },
  "quickapp": {},
  "mp-weixin": {
    "appid": "WeChat mini-program appid starting with wx",
    "setting": {
      "urlCheck": false
    },
    "usingComponents": true
  },
  "mp-alipay": {
    "usingComponents": true
  },
  "mp-baidu": {
    "usingComponents": true
  },
  "mp-toutiao": {
    "usingComponents": true
  },
  "h5": {
    "router": {
      "base": "/"
    }
  }
}

Main Configuration Items

1. Basic Information

json
{
  "name": "Application Name",
  "appid": "",
  "description": "Application Description",
  "versionName": "1.0.0",
  "versionCode": "100"
}

2. app-plus (App-specific Configuration)

json
"app-plus": {
  "usingComponents": true,
  "nvueCompiler": "uni-app",
  "splashscreen": {
    "alwaysShowBeforeRender": true,
    "waiting": true,
    "autoclose": true,
    "delay": 0
  },
  "modules": {
    "Payment": {},
    "Push": {},
    "Share": {},
    "OAuth": {}
  },
  "distribute": {
    "android": {
      "permissions": [
        "<uses-permission android:name=\"android.permission.CHANGE_NETWORK_STATE\"/>"
      ],
      "minSdkVersion": 21,
      "targetSdkVersion": 28,
      "abiFilters": ["armeabi-v7a", "arm64-v8a"]
    },
    "ios": {
      "dSYMs": false,
      "idfa": false
    },
    "sdkConfigs": {
      "ad": {},
      "maps": {},
      "oauth": {},
      "payment": {},
      "push": {},
      "share": {}
    },
    "icons": {
      "android": {
        "hdpi": "unpackage/res/icons/72x72.png",
        "xhdpi": "unpackage/res/icons/96x96.png",
        "xxhdpi": "unpackage/res/icons/144x144.png",
        "xxxhdpi": "unpackage/res/icons/192x192.png"
      },
      "ios": {
        "appstore": "unpackage/res/icons/1024x1024.png",
        "ipad": {
          "app": "unpackage/res/icons/76x76.png",
          "app@2x": "unpackage/res/icons/152x152.png",
          "notification": "unpackage/res/icons/20x20.png",
          "notification@2x": "unpackage/res/icons/40x40.png",
          "proapp@2x": "unpackage/res/icons/167x167.png",
          "settings": "unpackage/res/icons/29x29.png",
          "settings@2x": "unpackage/res/icons/58x58.png",
          "spotlight": "unpackage/res/icons/40x40.png",
          "spotlight@2x": "unpackage/res/icons/80x80.png"
        },
        "iphone": {
          "app@2x": "unpackage/res/icons/120x120.png",
          "app@3x": "unpackage/res/icons/180x180.png",
          "notification@2x": "unpackage/res/icons/40x40.png",
          "notification@3x": "unpackage/res/icons/60x60.png",
          "settings@2x": "unpackage/res/icons/58x58.png",
          "settings@3x": "unpackage/res/icons/87x87.png",
          "spotlight@2x": "unpackage/res/icons/80x80.png",
          "spotlight@3x": "unpackage/res/icons/120x120.png"
        }
      }
    }
  }
}

3. Mini-program Platform Configuration

json
"mp-weixin": {
  "appid": "WeChat mini-program appid starting with wx",
  "setting": {
    "urlCheck": false,
    "es6": true,
    "postcss": true,
    "minified": true
  },
  "usingComponents": true,
  "permission": {
    "scope.userLocation": {
      "desc": "Your location information will be used for location interface effects in the mini-program"
    }
  }
}

4. H5 Configuration

json
"h5": {
  "title": "Application Name",
  "router": {
    "mode": "history",
    "base": "/"
  },
  "devServer": {
    "https": false,
    "port": 8080,
    "disableHostCheck": true,
    "proxy": {
      "/api": {
        "target": "http://localhost:3000",
        "changeOrigin": true,
        "secure": false,
        "pathRewrite": {
          "^/api": ""
        }
      }
    }
  },
  "optimization": {
    "treeShaking": {
      "enable": true
    }
  },
  "template": "index.html"
}

uni.setStorage and getStorage

In addition to configuration files, uni-app provides runtime global data storage methods that can share data between different pages of the application.

Store Data

javascript
// Synchronous storage
try {
  uni.setStorageSync('key', 'value')
} catch (e) {
  console.error(e)
}

// Asynchronous storage
uni.setStorage({
  key: 'key',
  data: 'value',
  success: function() {
    console.log('Storage successful')
  },
  fail: function(err) {
    console.error('Storage failed', err)
  }
})

Get Data

javascript
// Synchronous get
try {
  const value = uni.getStorageSync('key')
  if (value) {
    console.log(value)
  }
} catch (e) {
  console.error(e)
}

// Asynchronous get
uni.getStorage({
  key: 'key',
  success: function(res) {
    console.log(res.data)
  },
  fail: function(err) {
    console.error('Get failed', err)
  }
})

Remove Data

javascript
// Synchronous remove
try {
  uni.removeStorageSync('key')
} catch (e) {
  console.error(e)
}

// Asynchronous remove
uni.removeStorage({
  key: 'key',
  success: function() {
    console.log('Remove successful')
  }
})

Clear All Data

javascript
// Synchronous clear
try {
  uni.clearStorageSync()
} catch (e) {
  console.error(e)
}

// Asynchronous clear
uni.clearStorage({
  success: function() {
    console.log('Clear successful')
  }
})

getApp() and getCurrentPages()

uni-app provides global application instance and page instance retrieval methods.

getApp()

getApp() is used to get the current application instance and can be used to get and set global data.

javascript
const app = getApp()

// Set global data
app.globalData = {
  userInfo: null
}

// Get global data
console.log(app.globalData.userInfo)

getCurrentPages()

getCurrentPages() is used to get the current page stack instance, where the first element in the array is the home page and the last element is the current page.

javascript
const pages = getCurrentPages()
const currentPage = pages[pages.length - 1]
const prevPage = pages[pages.length - 2]

// Get current page path
console.log(currentPage.route)

// Get current page parameters
console.log(currentPage.options)

// Call previous page method
if (prevPage) {
  prevPage.refreshData()
}

Vuex State Management

For complex applications, Vuex is recommended for state management.

Install Vuex

bash
npm install vuex --save

Create Store

javascript
// store/index.js
import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex)

export default new Vuex.Store({
  state: {
    count: 0,
    userInfo: null
  },
  mutations: {
    increment(state) {
      state.count++
    },
    setUserInfo(state, userInfo) {
      state.userInfo = userInfo
    }
  },
  actions: {
    login({ commit }, userInfo) {
      return new Promise((resolve, reject) => {
        // Simulate login request
        setTimeout(() => {
          commit('setUserInfo', userInfo)
          resolve()
        }, 1000)
      })
    }
  },
  getters: {
    isLoggedIn: state => !!state.userInfo
  }
})

Register in main.js

javascript
// main.js
import Vue from 'vue'
import App from './App'
import store from './store'

Vue.config.productionTip = false

const app = new Vue({
  store,
  ...App
})
app.$mount()

Use in Components

html
<template>
  <view class="container">
    <text>Count: {{ count }}</text>
    <button @tap="increment">+1</button>
    
    <view v-if="isLoggedIn">
      <text>Welcome, {{ userInfo.name }}</text>
      <button @tap="logout">Logout</button>
    </view>
    <view v-else>
      <button @tap="login">Login</button>
    </view>
  </view>
</template>

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

export default {
  computed: {
    ...mapState(['count', 'userInfo']),
    ...mapGetters(['isLoggedIn'])
  },
  methods: {
    ...mapMutations(['increment']),
    ...mapActions(['login']),
    logout() {
      this.$store.commit('setUserInfo', null)
    },
    handleLogin() {
      const userInfo = {
        id: 1,
        name: 'John',
        avatar: '/static/avatar.png'
      }
      this.login(userInfo)
    }
  }
}
</script>

uni.getSystemInfo Get System Information

During development, it's often necessary to get device system information such as screen size, device model, etc.

javascript
// Synchronous get
try {
  const systemInfo = uni.getSystemInfoSync()
  console.log(systemInfo)
} catch (e) {
  console.error(e)
}

// Asynchronous get
uni.getSystemInfo({
  success: function(res) {
    console.log(res)
  },
  fail: function(err) {
    console.error(err)
  }
})

System information includes the following properties:

javascript
{
  brand: 'iPhone',              // Phone brand
  model: 'iPhone X',            // Phone model
  pixelRatio: 3,                // Device pixel ratio
  screenWidth: 375,             // Screen width
  screenHeight: 812,            // Screen height
  windowWidth: 375,             // Available window width
  windowHeight: 724,            // Available window height
  statusBarHeight: 44,          // Status bar height
  language: 'en-US',            // Application language setting
  system: 'iOS 11.0',           // Operating system version
  version: '1.0.0',             // Application version
  platform: 'ios',              // Client platform
  fontSizeSetting: 16,          // User font size setting
  SDKVersion: '2.0.4',          // Client base library version
  safeArea: {                   // Safe area
    left: 0,
    right: 375,
    top: 44,
    bottom: 778,
    width: 375,
    height: 734
  }
}

Global Styles and Themes

Global Style Files

In uni-app, you can define global styles through the <style> tag in App.vue.

html
<!-- App.vue -->
<style>
/* Global styles */
page {
  background-color: #f8f8f8;
  font-size: 16px;
  font-family: -apple-system, BlinkMacSystemFont, 'Helvetica Neue', Helvetica, Segoe UI, Arial, Roboto, 'PingFang SC', 'miui', 'Hiragino Sans GB', 'Microsoft Yahei', sans-serif;
}

.container {
  padding: 20rpx;
}

.btn {
  padding: 20rpx 30rpx;
  background-color: #007AFF;
  color: #ffffff;
  border-radius: 8rpx;
  font-size: 28rpx;
  text-align: center;
}

.btn-danger {
  background-color: #dd524d;
}

.text-primary {
  color: #007AFF;
}

.text-danger {
  color: #dd524d;
}
</style>

Theme Switching

You can implement theme switching by dynamically switching CSS variables.

html
<!-- App.vue -->
<style>
/* Define CSS variables */
page {
  /* Light theme */
  --bg-color: #f8f8f8;
  --text-color: #333333;
  --border-color: #e5e5e5;
  --primary-color: #007AFF;
  --secondary-color: #6c757d;
  --success-color: #28a745;
  --danger-color: #dc3545;
  --warning-color: #ffc107;
  --info-color: #17a2b8;
}

/* Dark theme */
page.dark {
  --bg-color: #121212;
  --text-color: #e5e5e5;
  --border-color: #333333;
  --primary-color: #409eff;
  --secondary-color: #909399;
  --success-color: #67c23a;
  --danger-color: #f56c6c;
  --warning-color: #e6a23c;
  --info-color: #909399;
}

/* Use CSS variables */
.container {
  background-color: var(--bg-color);
  color: var(--text-color);
}

.btn-primary {
  background-color: var(--primary-color);
  color: #ffffff;
}

.border {
  border: 1px solid var(--border-color);
}
</style>

<script>
export default {
  onLaunch: function() {
    // Get theme setting from local storage
    try {
      const theme = uni.getStorageSync('theme')
      if (theme === 'dark') {
        this.setDarkTheme()
      } else {
        this.setLightTheme()
      }
    } catch (e) {
      console.error(e)
    }
  },
  methods: {
    setDarkTheme() {
      // Add dark theme class
      document.documentElement.classList.add('dark')
      // Store theme setting
      uni.setStorageSync('theme', 'dark')
    },
    setLightTheme() {
      // Remove dark theme class
      document.documentElement.classList.remove('dark')
      // Store theme setting
      uni.setStorageSync('theme', 'light')
    },
    toggleTheme() {
      // Toggle theme
      if (document.documentElement.classList.contains('dark')) {
        this.setLightTheme()
      } else {
        this.setDarkTheme()
      }
    }
  }
}
</script>

Global Mixins

For logic that needs to be reused across multiple components, you can use global mixins.

javascript
// mixins/global.js
export default {
  data() {
    return {
      globalData: 'This is global data'
    }
  },
  onLoad() {
    console.log('Global mixin onLoad')
  },
  methods: {
    globalMethod() {
      console.log('This is a global method')
    },
    showToast(title, icon = 'none') {
      uni.showToast({
        title,
        icon
      })
    }
  }
}

Register global mixin in main.js:

javascript
// main.js
import Vue from 'vue'
import App from './App'
import globalMixin from './mixins/global'

Vue.mixin(globalMixin)

const app = new Vue({
  ...App
})
app.$mount()

Global Filters

For data formatting logic that needs to be reused across multiple components, you can use global filters.

javascript
// filters/index.js
export function formatDate(date, fmt = 'yyyy-MM-dd') {
  if (!date) return ''
  if (typeof date === 'string') {
    date = new Date(date.replace(/-/g, '/'))
  }
  if (typeof date === 'number') {
    date = new Date(date)
  }
  
  const o = {
    'M+': date.getMonth() + 1,
    'd+': date.getDate(),
    'h+': date.getHours(),
    'm+': date.getMinutes(),
    's+': date.getSeconds(),
    'q+': Math.floor((date.getMonth() + 3) / 3),
    'S': date.getMilliseconds()
  }
  
  if (/(y+)/.test(fmt)) {
    fmt = fmt.replace(RegExp.$1, (date.getFullYear() + '').substr(4 - RegExp.$1.length))
  }
  
  for (let k in o) {
    if (new RegExp('(' + k + ')').test(fmt)) {
      fmt = fmt.replace(RegExp.$1, (RegExp.$1.length === 1) ? (o[k]) : (('00' + o[k]).substr(('' + o[k]).length)))
    }
  }
  
  return fmt
}

export function formatPrice(price) {
  if (!price && price !== 0) return ''
  return '$' + parseFloat(price).toFixed(2)
}

export function formatFileSize(size) {
  if (!size) return '0 B'
  const units = ['B', 'KB', 'MB', 'GB', 'TB', 'PB']
  let index = 0
  while (size >= 1024 && index < units.length - 1) {
    size /= 1024
    index++
  }
  return size.toFixed(2) + ' ' + units[index]
}

Register global filters in main.js:

javascript
// main.js
import Vue from 'vue'
import App from './App'
import * as filters from './filters'

// Register global filters
Object.keys(filters).forEach(key => {
  Vue.filter(key, filters[key])
})

const app = new Vue({
  ...App
})
app.$mount()

Global Error Handling

To catch global errors in the application, you can add a global error handler in main.js.

javascript
// main.js
import Vue from 'vue'
import App from './App'

// Global error handling
Vue.config.errorHandler = function(err, vm, info) {
  console.error('Vue error:', err)
  console.error('Error info:', info)
  
  // Can report error to server
  // reportErrorToServer(err, info)
}

// Catch Promise errors
window.addEventListener('unhandledrejection', event => {
  console.error('Unhandled Promise error:', event.reason)
  
  // Can report error to server
  // reportErrorToServer(event.reason)
  
  // Prevent default handling
  event.preventDefault()
})

const app = new Vue({
  ...App
})
app.$mount()

Global Event Bus

For cross-component communication, you can use a global event bus.

javascript
// main.js
import Vue from 'vue'
import App from './App'

// Create global event bus
Vue.prototype.$bus = new Vue()

const app = new Vue({
  ...App
})
app.$mount()

Global API Interceptors

For scenarios requiring unified API request handling, you can use interceptors.

javascript
// utils/request.js
import { baseURL } from '@/config'

// Request interceptor
uni.addInterceptor('request', {
  invoke(args) {
    // Pre-request processing
    console.log('Request interceptor:', args)
    
    // Add baseURL
    if (!args.url.startsWith('http')) {
      args.url = baseURL + args.url
    }
    
    // Add token
    const token = uni.getStorageSync('token')
    if (token) {
      args.header = {
        ...args.header,
        'Authorization': `Bearer ${token}`
      }
    }
    
    // Add timestamp to prevent caching
    if (args.method === 'GET') {
      args.url += (args.url.includes('?') ? '&' : '?') + `_t=${Date.now()}`
    }
  },
  success(args) {
    // Post-request success processing
    console.log('Request success:', args)
    
    // Handle business status codes
    if (args.data.code !== 0) {
      uni.showToast({
        title: args.data.message || 'Request failed',
        icon: 'none'
      })
      
      // Handle specific error codes
      if (args.data.code === 401) {
        // Token expired, redirect to login
        uni.navigateTo({
          url: '/pages/login/login'
        })
      }
      
      // Throw business error
      const error = new Error(args.data.message)
      error.code = args.data.code
      throw error
    }
    
    // Return business data
    return args.data.data
  },
  fail(err) {
    // Request failure handling
    console.error('Request failed:', err)
    
    uni.showToast({
      title: 'Network error, please try again later',
      icon: 'none'
    })
    
    return Promise.reject(err)
  },
  complete(res) {
    // Request completion handling
    console.log('Request complete:', res)
  }
})

Global Configuration Best Practices

  1. Modular Configuration: Split configuration by functionality into multiple modules for easier maintenance.
javascript
// config/index.js
import development from './env.development'
import production from './env.production'

// Choose configuration based on environment
const env = process.env.NODE_ENV
const config = env === 'development' ? development : production

export default {
  // Basic configuration
  appName: 'uni-app Example',
  appVersion: '1.0.0',
  
  // Environment configuration
  ...config,
  
  // Common configuration
  navBar: {
    backgroundColor: '#007AFF',
    titleColor: '#ffffff',
    backIconColor: '#ffffff'
  },
  tabBar: {
    color: '#7A7E83',
    selectedColor: '#007AFF',
    backgroundColor: '#ffffff'
  },
  
  // Cache keys
  storageKeys: {
    token: 'APP_TOKEN',
    userInfo: 'USER_INFO',
    theme: 'APP_THEME',
    language: 'APP_LANGUAGE'
  }
}
  1. Environment Configuration: Provide different configurations for different environments.
javascript
// config/env.development.js
export default {
  baseURL: 'http://localhost:3000/api',
  debug: true,
  mockData: true
}

// config/env.production.js
export default {
  baseURL: 'https://api.example.com',
  debug: false,
  mockData: false
}
  1. Unified API Management: Centrally manage API interfaces.
javascript
// api/user.js
import { get, post } from '@/utils/request'

export function login(data) {
  return post('/user/login', data)
}

export function getUserInfo() {
  return get('/user/info')
}

export function updateUserInfo(data) {
  return post('/user/update', data)
}

Summary

This guide detailed global configuration methods and common configuration items in uni-app, including:

  1. Configuration Files: Configuration items and usage of pages.json and manifest.json
  2. Data Storage: Usage methods of uni.setStorage and uni.getStorage
  3. Application Instance: Usage methods of getApp() and getCurrentPages()
  4. State Management: Vuex configuration and usage
  5. System Information: Usage methods of uni.getSystemInfo
  6. Global Styles and Themes: Global style definition and theme switching
  7. Global Mixins: Reusing component logic
  8. Global Filters: Data formatting
  9. Global Error Handling: Catching application errors
  10. Global Event Bus: Cross-component communication
  11. Global API Interceptors: Unified API request handling
  12. Global Configuration Best Practices: Modular configuration, environment configuration, API management, etc.

By properly using these global configuration methods, you can make uni-app applications more structured, easier to maintain, and improve development efficiency.

一次开发,多端部署 - 让跨平台开发更简单