uinapp项目组成

1,224 阅读18分钟

生成uni-app模版

  • 点击HBuilder左上角图标选择项目 image.png
  • 填写项目信息,选择项目模版

image.png

uni-app项目构成

uni-app目录构成

  1. .hbuilderx文件中的launch.json文件配置了启动调试时相关设置
  2. pages 文件用来存放页面。
  3. static是一个存放静态资源的文件夹,例如图片等。
  4. App.vue是uni-app的主组件,所有页面都是在App.vue下进行切换的,是页面入口文件。但App.vue本身不是页面,这里不能编写视图元素。
  5. index.html是一个渲染页面。
  6. main.js是uni-app的入口文件,主要作用是初始化vue实例、定义全局组件、使用需要的插件如vuex。
  7. manifest.json 文件是应用的配置文件,用于指定应用的名称、图标、权限等。HBuilderX 创建的工程此文件在根目录,CLI 创建的工程此文件在 src 目录。
  8. pages.json 文件用来对uni-app进行全局配置的,决定页面的路径、窗口样式,原生导航栏、底部tab栏等。
  9. uni.scss 文件的用途是为了方便整体控制应用的风格。 image.png

uni-app页面生命周期

函数名说明平台差异说明最低版本
onInit监听页面初始化,其参数同 onLoad 参数,为上个页面传递的数据,参数类型为 Object(用于页面传参),触发时机早于 onLoad百度小程序3.1.0+
onLoad监听页面加载,其参数为上个页面传递的数据,参数类型为 Object(用于页面传参),参考示例
onShow监听页面显示。页面每次出现在屏幕上都触发,包括从下级页面点返回露出当前页面
onReady监听页面初次渲染完成。注意如果渲染速度快,会在页面进入动画完成前触发
onHide监听页面隐藏
onUnload监听页面卸载
onResize监听窗口尺寸变化App、微信小程序
onPullDownRefresh监听用户下拉动作,一般用于下拉刷新,参考示例
onReachBottom页面滚动到底部的事件(不是scroll-view滚到底),常用于下拉下一页数据。具体见下方注意事项
onTabItemTap点击 tab 时触发,参数为Object,具体见下方注意事项微信小程序、QQ小程序、支付宝小程序、百度小程序、H5、App
onShareAppMessage用户点击右上角分享微信小程序、QQ小程序、支付宝小程序、字节小程序、飞书小程序、快手小程序
onPageScroll监听页面滚动,参数为Objectnvue暂不支持
onNavigationBarButtonTap监听原生标题栏按钮点击事件,参数为ObjectApp、H5
onBackPress监听页面返回,返回 event = {from:backbutton、 navigateBack} ,backbutton 表示来源是左上角返回按钮或 android 返回键;navigateBack表示来源是 uni.navigateBack ;详细说明及使用:onBackPress 详解。支付宝小程序只有真机能触发,只能监听非navigateBack引起的返回,不可阻止默认行为。app、H5、支付宝小程序
onNavigationBarSearchInputChanged监听原生标题栏搜索输入框输入内容变化事件App、H51.6.0
onNavigationBarSearchInputConfirmed监听原生标题栏搜索输入框搜索事件,用户点击软键盘上的“搜索”按钮时触发。App、H51.6.0
onNavigationBarSearchInputClicked监听原生标题栏搜索输入框点击事件(pages.json 中的 searchInput 配置 disabled 为 true 时才会触发)App、H51.6.0
onShareTimeline监听用户点击右上角转发到朋友圈微信小程序2.8.1+
onAddToFavorites监听用户点击右上角收藏微信小程序2.8.1+

onInit使用注意

  • 仅百度小程序基础库 3.260 以上支持 onInit 生命周期
  • 其他版本或平台可以同时使用 onLoad 生命周期进行兼容,注意避免重复执行相同逻辑
  • 不依赖页面传参的逻辑可以直接使用 created 生命周期替代

onReachBottom使用注意 可在pages.json里定义具体页面底部的触发距离onReachBottomDistance,比如设为50,那么滚动页面到距离底部50px时,就会触发onReachBottom事件。

如使用scroll-view导致页面没有滚动,则触底事件不会被触发。scroll-view滚动到底部的事件请参考scroll-view的文档

onPageScroll (监听滚动、滚动监听、滚动事件)参数说明:

属性类型说明
scrollTopNumber页面在垂直方向已滚动的距离(单位px)

注意

  • onPageScroll里不要写交互复杂的js,比如频繁修改页面。因为这个生命周期是在渲染层触发的,在非h5端,js是在逻辑层执行的,两层之间通信是有损耗的。如果在滚动过程中,频发触发两层之间的数据交换,可能会造成卡顿。
  • 如果想实现滚动时标题栏透明渐变,在App和H5下,可在pages.json中配置titleNView下的type为transparent,参考
  • 如果需要滚动吸顶固定某些元素,推荐使用css的粘性布局,参考插件市场。插件市场也有其他js实现的吸顶插件,但性能不佳,需要时可自行搜索。
  • 在App、微信小程序、H5中,也可以使用wxs监听滚动,参考;在app-nvue中,可以使用bindingx监听滚动,参考
  • onBackPress上不可使用async,会导致无法阻止默认返回
onPageScroll : function(e) { //nvue暂不支持滚动监听,可用bindingx代替
    console.log("滚动距离为:" + e.scrollTop);
},

onTabItemTap 返回的json对象说明:

属性类型说明
indexString被点击tabItem的序号,从0开始
pagePathString被点击tabItem的页面路径
textString被点击tabItem的按钮文字

注意

  • onTabItemTap常用于点击当前tabitem,滚动或刷新当前页面。如果是点击不同的tabitem,一定会触发页面切换。
  • 如果想在App端实现点击某个tabitem不跳转页面,不能使用onTabItemTap,可以使用plus.nativeObj.view放一个区块盖住原先的tabitem,并拦截点击事件。
  • 支付宝小程序平台onTabItemTap表现为点击非当前tabitem后触发,因此不能用于实现点击返回顶部这种操作
onTabItemTap : function(e) {
    console.log(e);
    // e的返回格式为json对象: {"index":0,"text":"首页","pagePath":"pages/index/index"}
},

onNavigationBarButtonTap 参数说明:

属性类型说明
indexNumber原生标题栏按钮数组的下标
onNavigationBarButtonTap : function (e) {
    console.log(e);
    // e的返回格式为json对象:{"text":"测试","index":0}
}

onBackPress 回调参数对象说明:

属性类型说明
fromString触发返回行为的来源:'backbutton'——左上角导航栏按钮及安卓返回键;'navigateBack'——uni.navigateBack() 方法。支付宝小程序端不支持返回此字段
export default {
    data() {
        return {};
    },
    onBackPress(options) {
        console.log('from:' + options.from)
    }
}

注意

  • nvue 页面weex编译模式支持的生命周期同weex,具体参考:weex生命周期介绍
  • 支付宝小程序真机可以监听到非navigateBack引发的返回事件(使用小程序开发工具时不会触发onBackPress),不可以阻止默认返回行为

组件生命周期

标题说明平台差异说明最低版本
beforeCreate在实例初始化之后被调用。详见
created在实例创建完成后被立即调用。详见
beforeMount在挂载开始之前被调用。详见
mounted挂载到实例上去之后调用。详见 注意:此处并不能确定子组件被全部挂载,如果需要子组件完全挂载之后在执行操作可以使用$nextTickVue官方文档
beforeUpdate数据更新时调用,发生在虚拟 DOM 打补丁之前。详见仅H5平台支持
updated由于数据更改导致的虚拟 DOM 重新渲染和打补丁,在这之后会调用该钩子。详见仅H5平台支持
beforeDestroy实例销毁之前调用。在这一步,实例仍然完全可用。详见
destroyedVue 实例销毁后调用。调用后,Vue 实例指示的所有东西都会解绑定,所有的事件监听器会被移除,所有的子实例也会被销毁。详见

uni-app的配置文件

pages.json

pages.json 文件用来对 uni-app 进行全局配置,决定页面文件的路径、窗口样式、原生的导航栏、底部的原生tabbar 等。

它类似微信小程序中app.json页面管理部分。注意定位权限申请等原属于app.json的内容,在uni-app中是在manifest中配置。

配置项列表
属性类型必填描述平台兼容
globalStyleObject设置默认页面的窗口表现
pagesObject Array设置页面路径及窗口表现
easycomObject组件自动引入规则2.5.5+
tabBarObject设置底部 tab 的表现
conditionObject启动模式配置
subPackagesObject Array分包加载配置
preloadRuleObject分包预下载规则微信小程序
workersStringWorker 代码放置的目录微信小程序
leftWindowObject大屏左侧窗口H5
topWindowObject大屏顶部窗口H5
rightWindowObject大屏右侧窗口H5

以下是一个包含了所有配置选项的 pages.json :

    "pages": [{
        "path": "pages/component/index",
        "style": {
            "navigationBarTitleText": "组件"
        }
    }, {
        "path": "pages/API/index",
        "style": {
            "navigationBarTitleText": "接口"
        }
    }, {
        "path": "pages/component/view/index",
        "style": {
            "navigationBarTitleText": "view"
        }
    }],
    "condition": { //模式配置,仅开发期间生效
        "current": 0, //当前激活的模式(list 的索引项)
        "list": [{
            "name": "test", //模式名称
            "path": "pages/component/view/index" //启动页面,必选
        }]
    },
    "globalStyle": {
        "navigationBarTextStyle": "black",
        "navigationBarTitleText": "演示",
        "navigationBarBackgroundColor": "#F8F8F8",
        "backgroundColor": "#F8F8F8",
        "usingComponents":{
            "collapse-tree-item":"/components/collapse-tree-item"
        },
        "renderingMode": "seperated", // 仅微信小程序,webrtc 无法正常时尝试强制关闭同层渲染
        "pageOrientation": "portrait", //横屏配置,全局屏幕旋转设置(仅 APP/微信/QQ小程序),支持 auto / portrait / landscape
        "rpxCalcMaxDeviceWidth": 960,
        "rpxCalcBaseDeviceWidth": 375,
        "rpxCalcIncludeWidth": 750
    },
    "tabBar": {
        "color": "#7A7E83",
        "selectedColor": "#3cc51f",
        "borderStyle": "black",
        "backgroundColor": "#ffffff",
        "height": "50px",
        "fontSize": "10px",
        "iconWidth": "24px",
        "spacing": "3px",
        "list": [{
            "pagePath": "pages/component/index",
            "iconPath": "static/image/icon_component.png",
            "selectedIconPath": "static/image/icon_component_HL.png",
            "text": "组件"
        }, {
            "pagePath": "pages/API/index",
            "iconPath": "static/image/icon_API.png",
            "selectedIconPath": "static/image/icon_API_HL.png",
            "text": "接口"
        }],
        "midButton": {
            "width": "80px",
            "height": "50px",
            "text": "文字",
            "iconPath": "static/image/midButton_iconPath.png",
            "iconWidth": "24px",
            "backgroundImage": "static/image/midButton_backgroundImage.png"
        }
    },
  "easycom": {
    "autoscan": true, //是否自动扫描组件
    "custom": {//自定义扫描规则
      "^uni-(.*)": "@/components/uni-$1.vue"
    }
  },
  "topWindow": {
    "path": "responsive/top-window.vue",
    "style": {
      "height": "44px"
    }
  },
  "leftWindow": {
    "path": "responsive/left-window.vue",
    "style": {
      "width": "300px"
    }
  },
  "rightWindow": {
    "path": "responsive/right-window.vue",
    "style": {
      "width": "300px"
    },
    "matchMedia": {
      "minWidth": 768
    }
  }
}
关于分包优化的说明
  • 在对应平台的配置下添加"optimization":{"subPackages":true}开启分包优化

  • 目前只支持mp-weixinmp-qqmp-baidump-toutiao的分包优化

  • 分包优化具体逻辑:

    • 静态文件:分包下支持 static 等静态资源拷贝,即分包目录内放置的静态资源不会被打包到主包中,也不可在主包中使用
    • js文件:当某个 js 仅被一个分包引用时,该 js 会被打包到该分包内,否则仍打到主包(即被主包引用,或被超过 1 个分包引用)
    • 自定义组件:若某个自定义组件仅被一个分包引用时,且未放入到分包内,编译时会输出提示信息
"subPackages": [{ "root": "pages/sub", "pages": [{ "path": "index/index" }] }]

manifest.json

manifest.json 文件是应用的配置文件,用于指定应用的名称、图标、权限等。HBuilderX 创建的工程此文件在根目录,CLI 创建的工程此文件在 src 目录。

配置项列表
属性类型默认值描述最低版本
nameString应用名称
appidString新建 uni-app 项目时,DCloud 云端分配。用途详见应用标识
descriptionString应用描述
localeStringauto设置当前默认语言,具体参考 locale
versionNameString版本名称,例如:1.0.0。详见下方Tips说明
versionCodeString版本号,例如:36
transformPxBooleantrue是否转换项目的px,为true时将px转换为rpx,为false时,px为传统的实际像素
networkTimeoutObject网络超时时间,详见
debugBooleanfalse是否开启 debug 模式,开启后调试信息以 info 的形式给出,其信息有页面的注册,页面路由,数据更新,事件触发等
uniStatisticsObject是否开启 uni 统计,全局配置2.2.3+
app-plusObjectApp 特有配置
h5ObjectH5 特有配置
quickappObject快应用特有配置,即将支持
mp-weixinObject微信小程序特有配置
mp-alipayObject支付宝小程序特有配置
mp-baiduObject百度小程序特有配置
mp-toutiaoObject字节跳动小程序特有配置1.6.0
mp-larkObject飞书小程序特有配置3.2.12
mp-qqObjectqq 小程序特有配置2.1.0
完整 manifest.json
{
    "appid": "__UNI__XXXXXX,创建应用时云端分配的,不要修改。",
    "name": "应用名称,如uni-app",
    "description": "应用描述",
    "versionName": "1.0.0",
    "versionCode": "100",
    "uniStatistics": {
        "enable": false
    },
    "app-plus": {
        "screenOrientation": [
            "portrait-primary",
            "landscape-primary",
            "portrait-secondary",
            "landscape-secondary"
        ],
        "optimization": {
            "subPackages": true
        },
        "modules": {
            "Contacts": {},
            "Fingerprint": {},
            "Maps": {},
            "Messaging": {},
            "OAuth": {},
            "Payment": {},
            "Push": {},
            "Share": {},
            "Speech": {},
            "Statistic": {},
            "VideoPlayer": {},
            "LivePusher": {}
        },
        "distribute": {
            "android": {
                "packagename": "Android应用包名,如io.dcloud.uniapp",
                "keystore": "Android应用打包使用的密钥库文件",
                "password": "Android应用打包使用密钥库中证书的密码",
                "aliasname": "Android应用打包使用密钥库中证书的别名",
                "schemes": [
                    "应用支持的scheme,大小写相关,推荐使用小写"
                ],
                "theme": "程序使用的主题",
                "android:name": "自定义程序入口类名",
                "custompermissions": "Boolean类型,是否自定义android权限,true表示自定义权限,只使用permissions下指定的android权限,不根据用户使用的5+模块自动添加android权限,false表示自动根据用户使用的5+模块自动添加android权限",
                "permissions": [
                    "要添加的额外的android权限,如<uses-permission android:name=\"com.android.launcher.permission.INSTALL_SHORTCUT\" />",
                    "<uses-permission android:name=\"com.android.launcher.permission.UNINSTALL_SHORTCUT\" />"
                ],
                "minSdkVersion": "apk支持的最低版本,默认值为14",
                "targetSdkVersion": "apk的目标版本,默认值为21"
            },
            "ios": {
                "appid": "iOS应用标识,苹果开发网站申请的appid,如io.dcloud.uniapp",
                "mobileprovision": "iOS应用打包配置文件",
                "password": "iOS应用打包个人证书导入密码",
                "p12": "iOS应用打包个人证书,打包配置文件关联的个人证书",
                "devices": "iOS应用支持的设备类型,可取值iphone/ipad/universal",
                "urltypes": [
                    {
                        "urlidentifier": "com.xxx.test",
                        "urlschemes": [
                            "hbuilder"
                        ]
                    }
                ],
                "frameworks": [
                    "使用native.js调用API要引用的库文件名称,如CoreLocation.framework",
                    "QuartzCore.framework"
                ],
                "idfa": "true|false,是否使用广告标识符,默认值为false",
                "plistcmds": [
                    "Set :权限 使用权限的原因",
                    "Set :NSCameraUsageDescription 说明使用用户相机的原因"
                ]
            },
            "sdkConfigs": {
                "maps": {
                    "baidu": {
                        "appkey_ios": "",
                        "appkey_android": ""
                    }
                },
                "oauth": {
                    "weixin": {
                        "appid": "",
                        "appsecret": ""
                    },
                    "qq": {
                        "appid": ""
                    },
                    "sina": {
                        "appkey": "",
                        "appsecret": "",
                        "redirect_uri": ""
                    },
                    "xiaomi": {
                        "appid_ios": "",
                        "appsecret_ios": "",
                        "redirect_uri_ios": "",
                        "appid_android": "",
                        "appsecret_android": "",
                        "redirect_uri_android": ""
                    }
                },
                "payment": {
                    "appleiap": {},
                    "alipay": {
                        "scheme": ""
                    },
                    "weixin": {
                        "appid": ""
                    }
                },
                "push": {
                    "igexin": {
                        "appid": "",
                        "appkey": "",
                        "appsecret": ""
                    }
                },
                "share": {
                    "weixin": {
                        "appid": ""
                    },
                    "sina": {
                        "appkey": "",
                        "appsecret": "",
                        "redirect_uri": ""
                    },
                    "qq": {
                        "appid": ""
                    }
                },
                "statics": {
                    "umeng": {
                        "appkey_ios": "",
                        "channelid_ios": "",
                        "appkey_android": "",
                        "channelid_android": ""
                    }
                }
            },
            "icons": {
                "ios": {
                    "appstore": "必选, 1024x1024, 提交app sotre使用的图标",
                    "iphone": {
                        "app@2x": "可选,120x120,iOS7-11程序图标(iPhone4S/5/6/7/8)",
                        "app@3x": "可选,180x180,iOS7-11程序图标(iPhone6plus/7plus/8plus/X)",
                        "spotlight@2x": "可选,80x80,iOS7-11 Spotlight搜索图标(iPhone5/6/7/8)",
                        "spotlight@3x": "可选,120x120,iOS7-11 Spotlight搜索图标(iPhone6plus/7plus/8plus/X)",
                        "settings@2x": "可选,58x58,iOS5-11 Settings设置图标(iPhone5/6/7/8)",
                        "settings@3x": "可选,87x87,iOS5-11 Settings设置图标(iPhone6plus/7plus/8plus/X)",
                        "notification@2x": "可选,40x40,iOS7-11 通知栏图标(iPhone5/6/7/8)",
                        "notification@3x": "可选,60x60,iOS7-11 通知栏图标(iPhone6plus/7plus/8plus/X)"
                    },
                    "ipad": {
                        "app": "可选,76x76,iOS7-11程序图标",
                        "app@2x": "可选,152x152,iOS7-11程序图标(高分屏)",
                        "proapp@2x": "可选,167x167,iOS9-11程序图标(iPad Pro)",
                        "spotlight": "可选,40x40,iOS7-11 Spotlight搜索图标",
                        "spotlight@2x": "可选,80x80,iOS7-11 Spotlight搜索图标(高分屏)",
                        "settings": "可选,29x29,iOS5-11 设置图标",
                        "settings@2x": "可选,58x58,iOS5-11 设置图标(高分屏)",
                        "notification": "可选,20x20,iOS7-11 通知栏图标",
                        "notification@2x": "可选,40x40,iOS7-11 通知栏图标(高分屏)"
                    }
                },
                "android": {
                    "mdpi": "必选,48x48,普通屏程序图标",
                    "ldpi": "必选,48x48,大屏程序图标",
                    "hdpi": "必选,72x72,高分屏程序图标",
                    "xhdpi": "必选,96x96,720P高分屏程序图标",
                    "xxhdpi": "必选,144x144,1080P高分屏程序图标",
                    "xxxhdpi": "可选,192x192"
                }
            },
            "splashscreen": {
                "ios": {
                    "iphone": {
                        "retina35": "可选,640x960,3.5英寸设备(iPhone4)启动图片",
                        "retina40": "可选,640x1136,4.0英寸设备(iPhone5)启动图片",
                        "retina40l": "可选,1136x640,4.0英寸设备(iPhone5)横屏启动图片",
                        "retina47": "可选,750x1334,4.7英寸设备(iPhone6)启动图片",
                        "retina47l": "可选,1334x750,4.7英寸设备(iPhone6)横屏启动图片",
                        "retina55": "可选,1242x2208,5.5英寸设备(iPhone6Plus)启动图片",
                        "retina55l": "可选,2208x1242,5.5英寸设备(iPhone6Plus)横屏启动图片",
                        "iphonex": "可选,1125x2436,iPhoneX启动图片",
                        "iphonexl": "可选,2436x1125,iPhoneX横屏启动图片"
                    },
                    "ipad": {
                        "portrait": "可选,768x1004,需支持iPad时必选,iPad竖屏启动图片",
                        "portrait-retina": "可选,1536x2008,需支持iPad时必选,iPad高分屏竖屏图片",
                        "landscape": "可选,1024x748,需支持iPad时必选,iPad横屏启动图片",
                        "landscape-retina": "可选,2048x1496,需支持iPad时必选,iPad高分屏横屏启动图片",
                        "portrait7": "可选,768x1024,需支持iPad iOS7时必选,iPad竖屏启动图片",
                        "portrait-retina7": "可选,1536x2048,需支持iPad iOS7时必选,iPad高分屏竖屏图片",
                        "landscape7": "可选,1024x768,需支持iPad iOS7时必选,iPad横屏启动图片",
                        "landscape-retina7": "可选,2048x1536,需支持iPad iOS7时必选,iPad高分屏横屏启动图片"
                    }
                },
                "android": {
                    "mdpi": "必选,240x282,普通屏启动图片",
                    "ldpi": "必选,320x442,大屏启动图片",
                    "hdpi": "必选,480x762,高分屏启动图片",
                    "xhdpi": "必选,720x1242,720P高分屏启动图片",
                    "xxhdpi": "必选,1080x1882,1080P高分屏启动图片"
                }
            }
        },
        "splashscreen": {
            "waiting": true,
            "autoclose": true
        },
        "error": {
            "url": "页面加载错误时打开的页面地址,可以是网络地址,也可以是本地地址"
        },
        "useragent": {
            "value": "自定义ua字符串",
            "concatenate": "是否为追加模式"
        },
        "useragent_ios": {
            "value": "与useragent的value一致,仅在iOS平台生效,当useragent和useragent_ios同时存在时优先级useragent_ios>useragent",
            "concatenate": "与useragent的concatenate一致,仅iOS平台生效"
        },
        "useragent_android": {
            "value": "与useragent的value一致,仅在Android平台生效,当useragent和useragent_android同时存在时优先级useragent_android>useragent",
            "concatenate": "与useragent的concatenate一致,仅Android平台生效"
        },
        "ssl": "accept|refuse|warning,访问https网络时对非受信证书的处理逻辑",
        "runmode": "normal",
        "appWhitelist": [
            "Android平台下载apk地址白名单列表",
            "iOS平台跳转appstore地址白名单列表"
        ],
        "schemeWhitelist": [
            "URL Scheme白名单列表,如:mqq"
        ],
        "channel": "渠道标记,可在DCloud开发者中心查看各渠道应用的统计数据",
        "adid": "广告联盟会员id,在DCloud开发者中心申请后填写",
        "safearea": {
            "background": "#CCCCCC",
            "bottom": {
                "offset": "none|auto"
            },
            "left": {
                "offset": "none|auto"
            },
            "right": {
                "offset": "none|auto"
            }
        },
        "softinput": {
            "navBar": "auto",
            "mode": "adjustResize|adjustPan"
        },
        "popGesture": "none"
    },
    "quickapp": {},
    "mp-weixin": {
        "appid": "wx开头的微信小程序appid",
        "uniStatistics": {
            "enable": false
        }
    },
    "mp-baidu": {
        "appid": "百度小程序appid"
    },
    "mp-toutiao": {
        "appid": "字节跳动小程序appid"
    },
    "mp-lark": {
        "appid": "飞书小程序appid"
    },
    "h5": {
        "title": "演示",
        "template": "index.html",
        "router": {
            "mode": "history",
            "base": "/hello/"
        },
        "async": {
            "loading": "AsyncLoading",
            "error": "AsyncError",
            "delay": 200,
            "timeout": 3000
        }
    }
}

package.json

  • 在开发web时,有时需要一套代码编译发布到不同的站点,比如主站和微信h5站。(注意不是一套代码内部自适应不同浏览器,是真的分离部署了不同的网站)
  • 在开发小程序时,经常有扩展小程序平台,比如基于阿里小程序的钉钉小程序、淘宝小程序。

uni-app 通过在package.json文件中增加uni-app扩展节点,可实现自定义条件编译平台。

扩展新的平台后,有3点影响:

  1. 可以在代码里编写自定义的条件编译,为这个新平台编写专用代码
  2. 运行时可以执行面向新平台的编译运行
  3. 发行时可以执行面向新平台的编译发行

注意只能扩展web和小程序平台,不能扩展app打包。并且扩展小程序平台时只能基于指定的基准平台扩展子平台,不能扩展基准平台。基准平台详见下文。

package.json扩展配置用法:

    /**
     * package.json其它原有配置 
     * 拷贝代码后请去掉注释!
     */
    "uni-app": {// 扩展配置
        "scripts": {
            "custom-platform": { //自定义编译平台配置,可通过cli方式调用
                "title":"自定义扩展名称", // 在HBuilderX中会显示在 运行/发行 菜单中
                "browser":"",  //运行到的目标浏览器,仅当UNI_PLATFORM为h5时有效
                "env": {//环境变量
                    "UNI_PLATFORM": "",  //基准平台
                    "MY_TEST": "", // ... 其他自定义环境变量
                 },
                "define": { //自定义条件编译
                    "CUSTOM-CONST": true //自定义条件编译常量,建议为大写
                }
            }
        }    
    }
}

Tips:

  • UNI_PLATFORM仅支持填写uni-app默认支持的基准平台,目前仅限如下枚举值:h5mp-weixinmp-alipaymp-baidump-toutiaomp-qq
  • browser 仅在UNI_PLATFORMh5时有效,目前仅限如下枚举值:chromefirefoxidedgesafarihbuilderx
  • package.json文件中不允许出现注释,否则扩展配置无效
  • vue-cli需更新到最新版,HBuilderX需升级到 2.1.6+ 版本

vue.config.js

uni.scss文件的用途是为了方便整体控制应用的风格。比如按钮颜色、边框风格,uni.scss文件里预置了一批scss变量预置。 支持情况

  • CLI 工程
  • HBuilderX 2.1.5 及以上版本

注意事项

  • 仅vue页面生效

部分配置项会被编译配置覆盖,例如:

  • publicPath 不支持,如果需要配置,请在 manifest.json->h5->router->base 中配置,参考文档:h5-router
  • outputDir 不支持
  • assetsDir 固定 static
  • pages 不支持
  • runtimeCompiler 固定 false
  • productionSourceMap 固定 false
  • css.extract H5 平台固定 false,其他平台固定 true
  • parallel 固定 false
  • 使用cli项目时,默认情况下 babel-loader 会忽略所有 node_modules 中的文件。如果你想要通过 Babel 显式转译一个依赖,可以在transpileDependencies中列出来。详情参考 使用示例

自定义静态资源目录

const CopyWebpackPlugin = require('copy-webpack-plugin') //最新版本copy-webpack-plugin插件暂不兼容,推荐v5.0.0

module.exports = {
    configureWebpack: {
        plugins: [
            new CopyWebpackPlugin([
                {
                    from: path.join(__dirname, 'src/images'),
                    to: path.join(__dirname, 'dist', process.env.NODE_ENV === 'production' ? 'build' : 'dev', process.env.UNI_PLATFORM, 'images')
                }
            ])
        ]
    }
}

注入全局依赖


module.exports = {
    configureWebpack: {
        plugins: [
            new webpack.ProvidePlugin({
                'localStorage': ['mp-storage', 'localStorage'],
                'window.localStorage': ['mp-storage', 'localStorage']
            })
        ]
    }
}

配置环境变量


module.exports = {
  chainWebpack: config => {
    config
      .plugin('define')
      .tap(args => {
        args[0]['process.env'].VUE_APP_TEST = '"test"'
        return args
      })
  }
}

启用压缩的方法:

  • HBuilderX创建的项目勾选运行-->运行到小程序模拟器-->运行时是否压缩代码
  • cli创建的项目可以在package.json中添加参数--minimize,示例:"dev:mp-weixin": "cross-env NODE_ENV=development UNI_PLATFORM=mp-weixin vue-cli-service uni-build --watch --minimize"

uni.scss

uni-app 官方扩展插件(uni ui)及 插件市场 上很多三方插件均使用了这些样式变量,如果你是插件开发者,建议你使用 scss 预处理,并在插件代码中直接使用这些变量(无需 import 这个文件),方便用户通过搭积木的方式开发整体风格一致的App。

uni.scss是一个特殊文件,在代码中无需 import 这个文件即可在scss代码中使用这里的样式变量。uni-app的编译器在webpack配置中特殊处理了这个uni.scss,使得每个scss文件都被注入这个uni.scss,达到全局可用的效果。如果开发者想要less、stylus的全局使用,需要在vue.config.js中自行配置webpack策略。

注意:

  1. 如要使用这些常用变量,需要在 HBuilderX 里面安装 scss 插件;

  2. 使用时需要在 style 节点上加上 lang="scss"

    <style lang="scss">
    </style>
    
  3. pages.json不支持scss,原生导航栏和tabbar的动态修改只能使用js api 以下是 uni.scss 的相关变量:

/* 颜色变量 */

/* 行为相关颜色 */
$uni-color-primary: #007aff;
$uni-color-success: #4cd964;
$uni-color-warning: #f0ad4e;
$uni-color-error: #dd524d;

/* 文字基本颜色 */
$uni-text-color:#333;//基本色
$uni-text-color-inverse:#fff;//反色
$uni-text-color-grey:#999;//辅助灰色,如加载更多的提示信息
$uni-text-color-placeholder: #808080;
$uni-text-color-disable:#c0c0c0;

/* 背景颜色 */
$uni-bg-color:#ffffff;
$uni-bg-color-grey:#f8f8f8;
$uni-bg-color-hover:#f1f1f1;//点击状态颜色
$uni-bg-color-mask:rgba(0, 0, 0, 0.4);//遮罩颜色

/* 边框颜色 */
$uni-border-color:#c8c7cc;

/* 尺寸变量 */

/* 文字尺寸 */
$uni-font-size-sm:24rpx;
$uni-font-size-base:28rpx;
$uni-font-size-lg:32rpx;

/* 图片尺寸 */
$uni-img-size-sm:40rpx;
$uni-img-size-base:52rpx;
$uni-img-size-lg:80rpx;

/* Border Radius */
$uni-border-radius-sm: 4rpx;
$uni-border-radius-base: 6rpx;
$uni-border-radius-lg: 12rpx;
$uni-border-radius-circle: 50%;

/* 水平间距 */
$uni-spacing-row-sm: 10px;
$uni-spacing-row-base: 20rpx;
$uni-spacing-row-lg: 30rpx;

/* 垂直间距 */
$uni-spacing-col-sm: 8rpx;
$uni-spacing-col-base: 16rpx;
$uni-spacing-col-lg: 24rpx;

/* 透明度 */
$uni-opacity-disabled: 0.3; // 组件禁用态的透明度

/* 文章场景相关 */
$uni-color-title: #2C405A; // 文章标题颜色
$uni-font-size-title:40rpx;
$uni-color-subtitle: #555555; // 二级标题颜色
$uni-font-size-subtitle:36rpx;
$uni-color-paragraph: #3F536E; // 文章段落颜色
$uni-font-size-paragraph:30rpx;

App.vue

应用生命周期
函数名说明
onLaunchuni-app 初始化完成时触发(全局只触发一次)
onShow当 uni-app 启动,或从后台进入前台显示
onHide当 uni-app 从前台进入后台
onError当 uni-app 报错时触发
onUniNViewMessage对 nvue 页面发送的数据进行监听,可参考 nvue 向 vue 通讯
onUnhandledRejection对未处理的 Promise 拒绝事件监听函数(2.8.1+)
onPageNotFound页面不存在监听函数
onThemeChange监听系统主题变化
注意
  • 应用生命周期仅可在App.vue中监听,在其它页面监听无效。
  • onlaunch里进行页面跳转,如遇白屏报错,请参考ask.dcloud.net.cn/article/359…
  • onPageNotFound 页面实际上已经打开了(比如通过分享卡片、小程序码)且发现页面不存在,才会触发,api 跳转不存在的页面不会触发(如 uni.navigateTo)
    // 只能在App.vue里监听应用的生命周期
    export default {
        onLaunch: function() {
            console.log('App Launch')
        },
        onShow: function() {
            console.log('App Show')
        },
        onHide: function() {
            console.log('App Hide')
        }
    }
</script>
globalData

小程序有globalData,这是一种简单的全局变量机制。这套机制在uni-app里也可以使用,并且全端通用。

以下是 App.vue 中定义globalData的相关配置:

    export default {  
        globalData: {  
            text: 'text'  
        }
    }  
</script>
全局样式

App.vue中,可以定义一些全局通用样式,例如需要加一个通用的背景色,首屏页面渲染的动画等都可以写在App.vue中。

注意如果工程下同时有vue和nvue文件,全局样式的所有css会应用于所有文件,而nvue支持的css有限,编译器会在控制台报警,提示某些css无法在nvue中支持。此时需要把nvue不支持的css写在单独的条件编译里。如:

    /* #ifndef APP-PLUS-NVUE */
    @import './common/uni.css';
    /* #endif*/
</style>

main.js

main.js是uni-app的入口文件,主要作用是初始化vue实例、定义全局组件、使用需要的插件如vuex。

首先引入了Vue库和App.vue,创建了一个vue实例,并且挂载vue实例。

import App from './App'
import pageHead from './components/page-head.vue' //全局引用page-head组件

Vue.config.productionTip = false
Vue.component('page-head', pageHead) //全局注册page-head组件,每个页面将可以直接使用该组件
App.mpType = 'app'

const app = new Vue({
    ...App
})
app.$mount() //挂载Vue实例

使用Vue.use引用插件,使用Vue.prototype添加全局变量,使用Vue.component注册全局组件。

可以引用vuex,因涉及多个文件,此处没有提供示例,详见hello uni-app示例工程。

无法使用vue-router,路由须在pages.json中进行配置。如果开发者坚持使用vue-router,可以在插件市场找到转换插件。

注意

  • nvue 暂不支持在 main.js 注册全局组件

Uni-app开发与小程序开发有什么区别

在建设。。。

宿主环境

在建设。。。

Uni-app的组件

在建设。。。

Uni-app的api

在建设。。。