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:
{
"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.
"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.
"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.
"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.
"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.
"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.
"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.
"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
{
"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
{
"name": "Application Name",
"appid": "",
"description": "Application Description",
"versionName": "1.0.0",
"versionCode": "100"
}
2. app-plus (App-specific Configuration)
"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
"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
"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
// 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
// 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
// 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
// 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.
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.
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
npm install vuex --save
Create Store
// 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
// 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
<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.
// 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:
{
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
.
<!-- 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.
<!-- 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.
// 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
:
// 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.
// 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
:
// 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
.
// 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.
// 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.
// 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
- Modular Configuration: Split configuration by functionality into multiple modules for easier maintenance.
// 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'
}
}
- Environment Configuration: Provide different configurations for different environments.
// 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
}
- Unified API Management: Centrally manage API interfaces.
// 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:
- Configuration Files: Configuration items and usage of
pages.json
andmanifest.json
- Data Storage: Usage methods of
uni.setStorage
anduni.getStorage
- Application Instance: Usage methods of
getApp()
andgetCurrentPages()
- State Management: Vuex configuration and usage
- System Information: Usage methods of
uni.getSystemInfo
- Global Styles and Themes: Global style definition and theme switching
- Global Mixins: Reusing component logic
- Global Filters: Data formatting
- Global Error Handling: Catching application errors
- Global Event Bus: Cross-component communication
- Global API Interceptors: Unified API request handling
- 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.