Skip to content

pages.json 页面路由 ​

pages.json 文件用来对 qinjs 进行全局配置,决定页面文件的路径、窗口样式、原生的导航栏、底部的原生 tabbar 等。在 qinjs 中也支持 pages.json 本地调试。

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

配置项列表 ​

属性类型必填描述平台兼容
extendsObject否集成 pages.json 所有属性
compilePagesObject否单独编译 pages 文件夹中的某一个文件
compileSubPackagesObject否单独编译 subPackages 文件夹中的某一个文件
globalStyleObject否设置默认页面的窗口表现
pagesObject Array是设置页面路径及窗口表现
easycomObject否组件自动引入规则
tabBarObject否设置底部 tab 的表现
conditionObject否启动模式配置
subPackagesObject Array否分包加载配置H5 不支持
preloadRuleObject否分包预下载规则微信小程序
workersString否Worker 代码放置的目录微信小程序
leftWindowObject否大屏左侧窗口H5
topWindowObject否大屏顶部窗口H5
rightWindowObject否大屏右侧窗口H5
entryPagePathString否默认启动首页微信小程序

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

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",
      "iconfontSrc":"static/iconfont.ttf", // app tabbar 字体.ttf文件路径 app 3.4.4+
    "list": [{
      "pagePath": "pages/component/index",
      "iconPath": "static/image/icon_component.png",
      "selectedIconPath": "static/image/icon_component_HL.png",
      "text": "组件",
          "iconfont": { // 优先级高于 iconPath,该属性依赖 tabbar 根节点的 iconfontSrc
             "text": "\ue102",
            "selectedText": "\ue103",
            "fontSize": "17px",
            "color": "#000000",
            "selectedColor": "#0000ff"
          }
    }, {
      "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
    }
  }
}
{
  "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",
      "iconfontSrc":"static/iconfont.ttf", // app tabbar 字体.ttf文件路径 app 3.4.4+
    "list": [{
      "pagePath": "pages/component/index",
      "iconPath": "static/image/icon_component.png",
      "selectedIconPath": "static/image/icon_component_HL.png",
      "text": "组件",
          "iconfont": { // 优先级高于 iconPath,该属性依赖 tabbar 根节点的 iconfontSrc
             "text": "\ue102",
            "selectedText": "\ue103",
            "fontSize": "17px",
            "color": "#000000",
            "selectedColor": "#0000ff"
          }
    }, {
      "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
    }
  }
}

globalStyle ​

用于设置应用的状态栏、导航条、标题、窗口背景色等。

属性类型默认值描述平台差异说明
navigationBarBackgroundColorHexColor#F8F8F8导航栏背景颜色(同状态栏背景色)APP与H5为#F8F8F8,小程序平台请参考相应小程序文档
navigationBarTextStyleStringblack导航栏标题颜色及状态栏前景颜色,仅支持 black/white
navigationBarTitleTextString导航栏标题文字内容
navigationStyleStringdefault导航栏样式,仅支持 default/custom。custom即取消默认的原生导航栏,需看使用注意微信小程序 7.0+、H5
backgroundColorHexColor#ffffff下拉显示出来的窗口的背景色微信小程序
backgroundTextStyleStringdark下拉 loading 的样式,仅支持 dark / light微信小程序
enablePullDownRefreshBooleanfalse是否开启下拉刷新,详见页面生命周期。
onReachBottomDistanceNumber50页面上拉触底事件触发时距页面底部距离,单位只支持px,详见页面生命周期uni-app x 不支持
backgroundColorTopHexColor#ffffff顶部窗口的背景色(bounce回弹区域)仅 iOS 平台
backgroundColorBottomHexColor#ffffff底部窗口的背景色(bounce回弹区域)仅 iOS 平台
titleImageString导航栏图片地址(替换当前文字标题),支付宝小程序内必须使用https的图片链接地址H5
transparentTitleStringnone导航栏整体(前景、背景)透明设置。支持 always 一直透明 / auto 滑动自适应 / none 不透明H5
titlePenetrateStringNO导航栏点击穿透H5
pageOrientationStringportrait横屏配置,屏幕旋转设置,仅支持 auto / portrait / landscape 详见 响应显示区域变化微信小程序、QQ小程序
animationDurationNumber300窗口显示动画的持续时间,单位为 ms
h5Object设置编译到 H5 平台的特定样式,配置项参考下方 H5H5
wxObject设置编译到 wx 平台的特定样式,配置项参考下方 MP-WEIXIN微信小程序
ttObject设置编译到 tt 平台的特定样式抖音小程序
ksObject设置编译到 ks 平台的特定样式快手小程序
usingComponentsObject引用小程序组件,参考 小程序组件uni-app x 不支持
renderingModeString同层渲染,webrtc(实时音视频) 无法正常时尝试配置 seperated 强制关掉同层微信小程序
leftWindowBooleantrue当存在 leftWindow 时,默认是否显示 leftWindowH5
topWindowBooleantrue当存在 topWindow 时,默认是否显示 topWindowH5
rightWindowBooleantrue当存在 rightWindow 时,默认是否显示 rightWindowH5
rpxCalcMaxDeviceWidthNumber960rpx 计算所支持的最大设备宽度,单位 pxH5
rpxCalcBaseDeviceWidthNumber375rpx 计算使用的基准设备宽度,设备实际宽度超出 rpx 计算所支持的最大设备宽度时将按基准宽度计算,单位 pxH5
rpxCalcIncludeWidthNumber750rpx 计算特殊处理的值,始终按实际的设备宽度计算,单位 rpxH5
maxWidthNumber单位px,当浏览器可见区域宽度大于maxWidth时,两侧留白,当小于等于maxWidth时,页面铺满;不同页面支持配置不同的maxWidth;maxWidth = leftWindow(可选)+page(页面主体)+rightWindow(可选)H5

注意

  • 支付宝小程序使用titleImage时必须使用https的图片链接地址,需要真机调试才能看到效果,支付宝开发者工具内无效果
  • globalStyle中设置的titleImage也会覆盖掉pages->style内的设置文字标题
  • 使用 maxWidth 时,页面内fixed元素需要使用--window-left,--window-right来保证布局位置正确

topWindow ​

以现有的手机应用为mainWindow,在左、上、右,可以追加新的页面显示窗体。

整体的宽屏适配思路,参考单独的宽屏适配指南

属性类型默认值描述
pathString配置页面路径
styleObject配置页面窗口表现,配置项参考下方 pageStyle
matchMediaObject配置显示该窗口的规则,配置项参考下方 matchMedia

注意

  • 目前 style 节点仅支持配置 width,height 等 css 样式相关属性
  • 如果需求当存在 topwindow 时,自动隐藏页面的 navigationBar,根据需求不同在App.vue中配置如下 css:
    • 只需要隐藏某个的页面 navigationBar
    css
    /* 隐藏路径为 pages/component/view/view 页面的 navigationBar */
    .qin-app--showtopwindow [data-page="pages/component/view/view"] qin-page-head {
      display: none;
    }
    /* 隐藏路径为 pages/component/view/view 页面的 navigationBar */
    .qin-app--showtopwindow [data-page="pages/component/view/view"] qin-page-head {
      display: none;
    }
    • 需要隐藏大部分页面的 navigationBar,显示某个页面的 navigationBar
    css
    /* 隐藏所有页面的 navigationBar */
    .qin-app--showtopwindow qin-page-head {
      display: none;
    }
    
    /* 显示路径为 pages/component/view/view 页面的 navigationBar */
    .qin-app--showtopwindow [data-page="pages/component/view/view"] qin-page-head {
      display: block;
    }
    /* 隐藏所有页面的 navigationBar */
    .qin-app--showtopwindow qin-page-head {
      display: none;
    }
    
    /* 显示路径为 pages/component/view/view 页面的 navigationBar */
    .qin-app--showtopwindow [data-page="pages/component/view/view"] qin-page-head {
      display: block;
    }

matchMedia ​

属性类型默认值描述
minWidthNumber768当设备可见区域宽度 >= minWidth 时,显示该 window

通过matchMedia的调节,可以自适应在不同屏幕上显示指定的window。

json
{
  "pages": [
    {
      "path": "pages/login/login",
      "style": {
        "topWindow": false, // 当前页面不显示 topWindow
        "leftWindow": false, // 当前页面不显示 leftWindow
        "rightWindow": false // 当前页面不显示 rightWindow
      }
    }
  ],
  "topWindow": {
    "path": "responsive/top-window.vue", // 指定 topWindow 页面文件
    "style": {
      "height": "44px"
    }
  },
  "leftWindow": {
    "path": "responsive/left-window.vue", // 指定 leftWindow 页面文件
    "style": {
      "width": "300px"
    }
  },
  "rightWindow": {
    "path": "responsive/right-window.vue", // 指定 rightWindow 页面文件
    "style": {
      "width": "300px" // 页面宽度
    },
    "matchMedia": {
      "minWidth": 768 //生效条件,当窗口宽度大于768px时显示
    }
  }
}
{
  "pages": [
    {
      "path": "pages/login/login",
      "style": {
        "topWindow": false, // 当前页面不显示 topWindow
        "leftWindow": false, // 当前页面不显示 leftWindow
        "rightWindow": false // 当前页面不显示 rightWindow
      }
    }
  ],
  "topWindow": {
    "path": "responsive/top-window.vue", // 指定 topWindow 页面文件
    "style": {
      "height": "44px"
    }
  },
  "leftWindow": {
    "path": "responsive/left-window.vue", // 指定 leftWindow 页面文件
    "style": {
      "width": "300px"
    }
  },
  "rightWindow": {
    "path": "responsive/right-window.vue", // 指定 rightWindow 页面文件
    "style": {
      "width": "300px" // 页面宽度
    },
    "matchMedia": {
      "minWidth": 768 //生效条件,当窗口宽度大于768px时显示
    }
  }
}

leftWindow ​

与topWindow相同

rightWindow ​

与topWindow相同

窗口通信参考:https://uniapp.dcloud.net.cn/api/window/communication

pages ​

qinjs 通过 pages 节点配置应用由哪些页面组成,pages 节点接收一个数组,数组每个项都是一个对象,其属性值如下:

属性类型默认值描述
pathString配置页面路径
styleObject配置页面窗口表现,配置项参考下方 pageStyle
routersObject页面定制,配置项参考下方 pageRouters

Tips:

  • pages节点的第一项为应用入口页(即首页)
  • 应用中新增/减少页面,都需要对 pages 数组进行修改
  • 文件名不需要写后缀,框架会自动寻找路径下的页面资源

代码示例:

开发目录为:

shell
┌─pages
│  ├─index
│  │  └─index.vue
│  └─login
│     └─login.vue
├─static
├─main.js
├─App.vue
├─manifest.json
└─pages.json
┌─pages
│  ├─index
│  │  └─index.vue
│  └─login
│     └─login.vue
├─static
├─main.js
├─App.vue
├─manifest.json
└─pages.json

则需要在 pages.json 中填写

js
{
    "pages": [
        {
            "path": "pages/index/index",
            "routers": { ... },
            "style": { ... }
        }, {
            "path": "pages/login/login",
            "routers": { ... },
            "style": { ... }
        }
    ]
}
{
    "pages": [
        {
            "path": "pages/index/index",
            "routers": { ... },
            "style": { ... }
        }, {
            "path": "pages/login/login",
            "routers": { ... },
            "style": { ... }
        }
    ]
}

routers ​

qinjs 通过 pages 节点配置应用由哪些页面组成,pages 节点接收一个数组,数组每个项都是一个对象,其属性值如下:

属性类型默认值描述
pathStringH5 真实的路径,支持路径参数。如: /home/:id
nameStringqin.navigateTo 、 qin.redirectTo 、 qin.switchTab 、 qin.reLaunch 可使用 name 参数进行跳转

style ​

用于设置每个页面的状态栏、导航条、标题、窗口背景色等。

页面中配置项会覆盖 globalStyle 中相同的配置项

属性类型默认值描述平台差异说明
navigationBarBackgroundColorHexColor#F8F8F8导航栏背景颜色(同状态栏背景色)APP与H5为#F8F8F8,小程序平台请参考相应小程序文档
navigationBarTextStyleStringblack导航栏标题颜色及状态栏前景颜色,仅支持 black/white
navigationBarTitleTextString导航栏标题文字内容
navigationBarShadowObject导航栏阴影,配置参考下方 导航栏阴影
navigationStyleStringdefault导航栏样式,仅支持 default/custom。custom即取消默认的原生导航栏,需看使用注意微信小程序 7.0+、H5
disableScrollBooleanfalse设置为 true 则页面整体不能上下滚动(bounce效果),只在页面配置中有效,在globalStyle中设置无效微信小程序(iOS)
backgroundColorHexColor#ffffff窗口的背景色微信小程序、抖音小程序
backgroundTextStyleStringdark下拉 loading 的样式,仅支持 dark/light
enablePullDownRefreshBooleanfalse是否开启下拉刷新,详见页面生命周期。
onReachBottomDistanceNumber50页面上拉触底事件触发时距页面底部距离,单位只支持px,详见页面生命周期
titleImageString导航栏图片地址(替换当前文字标题),支付宝小程序内必须使用https的图片链接地址H5
transparentTitleStringnone导航栏透明设置。支持 always 一直透明 / auto 滑动自适应 / none 不透明H5
titlePenetrateStringNO导航栏点击穿透H5
h5Object设置编译到 H5 平台的特定样式,配置项参考下方 H5H5
wxObject设置编译到 wx 平台的特定样式微信小程序
ttObject设置编译到 tt 平台的特定样式抖音小程序
usingComponentsObject引用小程序组件,参考 小程序组件、微信小程序、京东小程序
leftWindowBooleantrue当存在 leftWindow时,当前页面是否显示 leftWindowH5
topWindowBooleantrue当存在 topWindow 时,当前页面是否显示 topWindowH5
rightWindowBooleantrue当存在 rightWindow时,当前页面是否显示 rightWindowH5
maxWidthNumber单位px,当浏览器可见区域宽度大于maxWidth时,两侧留白,当小于等于maxWidth时,页面铺满;不同页面支持配置不同的maxWidth;maxWidth = leftWindow(可选)+page(页面主体)+rightWindow(可选)H5(2.9.9+)

注意

  • 使用 maxWidth 时,页面内fixed元素需要使用--window-left,--window-right来保证布局位置正确

代码示例:

js
{
  "pages": [{
      "path": "pages/index/index",
      "style": {
        "navigationBarTitleText": "首页",//设置页面标题文字
        "enablePullDownRefresh":true//开启下拉刷新
      }
    },
    ...
  ]
}
{
  "pages": [{
      "path": "pages/index/index",
      "style": {
        "navigationBarTitleText": "首页",//设置页面标题文字
        "enablePullDownRefresh":true//开启下拉刷新
      }
    },
    ...
  ]
}

自定义导航栏使用注意 ​

当 navigationStyle 设为 custom 或 titleNView 设为 false 时,原生导航栏不显示,此时要注意几个问题:

  • 非 H5 端,手机顶部状态栏区域会被页面内容覆盖。这是因为窗体是沉浸式的原因,即全屏可写内容。 qinjs 提供了状态栏高度的css变量--status-bar-height,如果需要把状态栏的位置从前景部分让出来,可写一个占位 div ,高度设为 css 变量。
html
<template>
    <view>
        <view class="status_bar">
            <!-- 这里是状态栏 -->
        </view>
        <view> 状态栏下的文字 </view>
    </view>
</template>
<style>
    .status_bar {
        height: var(--status-bar-height);
        width: 100%;
    }
</style>
<template>
    <view>
        <view class="status_bar">
            <!-- 这里是状态栏 -->
        </view>
        <view> 状态栏下的文字 </view>
    </view>
</template>
<style>
    .status_bar {
        height: var(--status-bar-height);
        width: 100%;
    }
</style>
  • 如果原生导航栏不能满足需求,推荐使用 qin ui 的自定义导航栏NavBar。这个前端导航栏自动处理了状态栏高度占位问题。
  • 前端导航栏搭配原生下拉刷新时,会有问题,包括
    • 微信小程序下iOS需要拉更长才能看到下拉刷新的三个点,而Android是从屏幕顶部下拉,无法从导航栏下方下拉。如果一定要从前端导航栏下拉,小程序下只能放弃原生下拉刷新,纯前端模拟,参考mescroll插件,但这样很容易产生性能问题。目前小程序平台自身没有提供更好的方案
    • H5下,原生下拉刷新提供了circle样式,可以指定offset偏移量(pages.json的app-plus下配置),自定义下拉圈出现的位置。在hello uni-app的扩展组件中有示例。
  • 非H5端,前端导航盖不住原生组件。如果页面有video、map、textarea(仅小程序)等原生组件,滚动时会覆盖住导航栏
    • 如果是小程序下,可以使用cover-view来做导航栏,避免覆盖问题
  • 前端组件在渲染速度上不如原生导航栏,原生导航可以在动画期间渲染,保证动画期间不白屏,但使用前端导航栏,在新窗体进入的动画期间可能会整页白屏,越低端的手机越明显。
  • 页面禁用原生导航栏后,想要改变状态栏的前景字体样式,仍可设置页面的 navigationBarTextStyle 属性(只能设置为 black或white)。

h5 ​

配置编译到 H5 平台时的特定样式

属性类型描述
titleNViewObject导航栏
pullToRefreshObject下拉刷新

导航栏 ​

属性类型默认值描述最低版本
backgroundColorString#F7F7F7背景颜色,颜色值格式为"#RRGGBB"。
buttonsArray自定义按钮,参考 buttons
titleColorString#000000标题文字颜色
titleTextString标题文字内容
titleSizeString标题文字字体大小
typeStringdefault导航栏样式。"default"-默认样式;"transparent"-透明渐变。
searchInputObject导航栏上的搜索框样式,详见:searchInput1.6.5
自定义按钮 ​
属性类型默认值描述
typeStringnone按钮样式
colorString默认与标题文字颜色一致按钮上文字颜色
backgroundString默认值为灰色半透明按钮的背景颜色,仅在标题栏type=transparent时生效
badgeTextString按钮上显示的角标文本,最多显示3个字符,超过则显示为...
colorPressed(暂不支持)String默认值为 color 属性值自动调整透明度为 0.3按下状态按钮文字颜色
floatStringright按钮在标题栏上的显示位置,可取值"left"、"right"
fontWeightStringnormal按钮上文字的粗细。可取值"normal"-标准字体、"bold"-加粗字体。
fontSizeString按钮上文字大小
fontSrcString按钮上文字使用的字体文件路径。
selectStringfalse是否显示选择指示图标(向下箭头)
textString按钮上显示的文字。使用字体图标时 unicode 字符表示必须 '\u' 开头,如 "\ue123"(注意不能写成"\e123")。
widthString44px按钮的宽度,可取值: "*px" - 逻辑像素值,如"10px"表示10逻辑像素值,不支持rpx,按钮的内容居中显示; "auto" - 自定计算宽度,根据内容自动调整按钮宽度
按钮样式 ​

使用 type 值设置按钮的样式时,会忽略 fontSrc 和 text 属性。

值说明
forward前进按钮
back后退按钮
share分享按钮
favorite收藏按钮
home主页按钮
menu菜单按钮
close关闭按钮
none无样式,需通过 text 属性设置按钮上显示的内容、通过 fontSrc 属性设置使用的字体库。

下拉刷新 ​

h5 平台下拉刷新动画,只有 circle 类型。

属性类型默认值描述
colorString#2BD009颜色值格式为"#RRGGBB"
offsetString0px下拉刷新控件的起始位置。支持百分比,如"10%";像素值,如"50px",不支持rpx。
搜索框样式 ​
属性类型默认值描述
autoFocusBooleanfalse是否自动获取焦点
alignStringcenter非输入状态下文本的对齐方式。可取值: "left" - 居左对齐; "right" - 居右对齐; "center" - 居中对齐。
backgroundColorStringrgba(255,255,255,0.5)背景颜色
borderRadiusString0px输入框的圆角半径,取值格式为"XXpx",其中XX为像素值(逻辑像素),不支持rpx。
placeholderString提示文本
placeholderColorString#CCCCCC提示文本颜色
disabledBooleanfalse是否可输入

注意事项:

  • 如果 h5 节点没有配置,默认会使用 app-plus 下的配置。
  • 配置了 h5 节点,则会覆盖 app-plus 下的配置。
属性类型描述
colorTypeString阴影的颜色,支持:grey、blue、green、orange、red、yellow

注意事项:

  • 微信 需要配置: "disableScroll": true
  • 支付宝 "mp-alipay":

wx ​

配置编译到 MP-WEIXIN 平台时的特定样式

属性类型默认值描述
homeButtonBooleanfalse在非首页、非页面栈最底层页面或非tabbar内页面中的导航栏展示home键
backgroundColorTopHexColor#ffffff顶部窗口的背景色,仅 iOS 支持
backgroundColorBottomHexColor#ffffff底部窗口的背景色,仅 iOS 支持
restartStrategyStringhomePage重新启动策略配置。支持 homePage / homePageAndLatestPage
initialRenderingCacheString页面初始渲染缓存配置。支持 static / dynamic
visualEffectInBackgroundStringnone切入系统后台时,隐藏页面内容,保护用户隐私。支持 hidden / none
handleWebviewPreloadStringstatic控制预加载下个页面的时机。支持 static / manual / auto

FAQ ​

easycom ​

传统vue组件,需要安装、引用、注册,三个步骤后才能使用组件。easycom将其精简为一步。

只要组件路径符合规范(具体见下),就可以不用引用、注册,直接在页面中使用。如下:

html
<template>
  <view class="container">
    <comp-a></comp-a>
    <uni-list>
    </uni-list>
  </view>
</template>
<script>
  // 这里不用import引入,也不需要在components内注册uni-list组件。template里就可以直接用
  export default {
    data() {
      return {}
    }
  }
</script>
<template>
  <view class="container">
    <comp-a></comp-a>
    <uni-list>
    </uni-list>
  </view>
</template>
<script>
  // 这里不用import引入,也不需要在components内注册uni-list组件。template里就可以直接用
  export default {
    data() {
      return {}
    }
  }
</script>

路径规范指:

  1. 安装在项目根目录的components目录下,并符合components/组件名称/组件名称.vue
  2. 安装在 qin_modules 下,路径为qin_modules/插件ID/components/组件名称/组件名称.vue

工程目录:

shell
┌─components            
│  └─comp-a
│    └─comp-a.vue      符合easycom规范的组件
└─qin_modules          [qin_module](/qin_modules)中符合easycom规范的组件
   └─qin_modules
     └─qinui-list
       └─components
         └─qinui-list
           └─ qinui-list.vue
┌─components            
│  └─comp-a
│    └─comp-a.vue      符合easycom规范的组件
└─qin_modules          [qin_module](/qin_modules)中符合easycom规范的组件
   └─qin_modules
     └─qinui-list
       └─components
         └─qinui-list
           └─ qinui-list.vue

不管components目录下安装了多少组件,easycom打包会自动剔除没有使用的组件,对组件库的使用尤为友好。

组件库批量安装,随意使用,自动按需打包。以官方的qin-ui为例,在HBuilderX新建项目界面选择qin-ui项目模板,只需在页面中敲u,拉出大量组件代码块,直接选择,即可使用。大幅提升开发效率,降低使用门槛。

在uni-app插件市场下载符合components/组件名称/组件名称.vue目录结构的组件,均可直接使用。

自定义easycom配置的示例

easycom是自动开启的,不需要手动开启,有需求时可以在pages.json的easycom节点进行个性化设置,如关闭自动扫描,或自定义扫描匹配组件的策略。设置参数如下:

属性类型默认值描述
autoscanBooleantrue是否开启自动扫描,开启后将会自动扫描符合components/组件名称/组件名称.vue目录结构的组件
customObject-以正则方式自定义组件匹配规则。如果autoscan不能满足需求,可以使用custom自定义匹配规则

如果你的组件,不符合easycom前述的路径规范。可以在pages.json的easycom节点中自行定义路径规范。

如果需要匹配node_modules内的vue文件,需要使用packageName/path/to/vue-file-$1.vue形式的匹配规则,其中packageName为安装的包名,/path/to/vue-file-$1.vue为vue文件在包内的路径。

json
"easycom": {
  "autoscan": true,
  "custom": {
    "^uni-(.*)": "@/components/uni-$1.vue", // 匹配components目录内的vue文件
    "^vue-file-(.*)": "packageName/path/to/vue-file-$1.vue" // 匹配node_modules内的vue文件
  }
}
"easycom": {
  "autoscan": true,
  "custom": {
    "^uni-(.*)": "@/components/uni-$1.vue", // 匹配components目录内的vue文件
    "^vue-file-(.*)": "packageName/path/to/vue-file-$1.vue" // 匹配node_modules内的vue文件
  }
}

说明

  • easycom方式引入的组件无需在页面内import,也不需要在components内声明,即可在任意页面使用。
  • easycom方式引入组件不是全局引入,而是局部引入。例如在H5端只有加载相应页面才会加载使用的组件。
  • 在组件名完全一致的情况下,easycom引入的优先级低于手动引入(区分连字符形式与驼峰形式)。
  • 考虑到编译速度,直接在pages.json内修改easycom不会触发重新编译,需要改动页面内容触发。
  • easycom只处理vue组件,不处理小程序专用组件(如微信的wxml格式组件)。不处理后缀为.nvue的组件。因为nvue页面引入的组件也是.vue组件。可以参考uni ui,使用vue后缀,同时兼容nvue页面。

tabBar ​

如果应用是一个多 tab 应用,可以通过 tabBar 配置项指定一级导航栏,以及 tab 切换时显示的对应页。

在 pages.json 中提供 tabBar 配置,不仅仅是为了方便快速开发导航,更重要的是在App和小程序端提升性能。在这两个平台,底层原生引擎在启动时无需等待js引擎初始化,即可直接读取 pages.json 中配置的 tabBar 信息,渲染原生tab。

Tips

  • 当设置 position 为 top 时,将不会显示 icon
  • tabBar 中的 list 是一个数组,只能配置最少2个、最多5个 tab,tab 按数组的顺序排序。
  • tabbar 切换第一次加载时可能渲染不及时,可以在每个tabbar页面的onLoad生命周期里先弹出一个等待雪花(hello uni-app使用了此方式)
  • tabbar 的页面展现过一次后就保留在内存中,再次切换 tabbar 页面,只会触发每个页面的onShow,不会再触发onLoad。
  • 顶部的 tabbar 目前仅微信小程序上支持。需要用到顶部选项卡的话,建议不使用 tabbar 的顶部设置,而是自己做顶部选项卡,可参考 hello uni-app->模板->顶部选项卡。

属性说明:

属性类型必填默认值描述平台差异说明
colorHexColor是tab 上的文字默认颜色
selectedColorHexColor是tab 上的文字选中时的颜色
backgroundColorHexColor是tab 的背景色
borderStyleString否blacktabbar 上边框的颜色,可选值 black/white,也支持其他颜色值H5
blurEffectString否noneiOS 高斯模糊效果,可选值 dark/extralight/light/none(参考:使用说明)H5(只有最新版浏览器才支持)
listArray是tab 的列表,详见 list 属性说明,最少2个、最多5个 tab
positionString否bottom可选值 bottom、toptop 值仅微信小程序支持
fontSizeString否10px文字默认大小H5
iconWidthString否24px图标默认宽度(高度等比例缩放)H5
spacingString否3px图标和文字的间距H5
heightString否50pxtabBar 默认高度H5
midButtonObject否中间按钮 仅在 list 项为偶数时有效H5
iconfontSrcString否list设置 iconfont 属性时,需要指定字体文件路径H5
backgroundImageString否设置背景图片,优先级高于 backgroundColor
backgroundRepeatString否设置标题栏的背景图平铺方式,可取值:"repeat" - 背景图片在垂直方向和水平方向平铺;"repeat-x" - 背景图片在水平方向平铺,垂直方向拉伸;"repeat-y" - 背景图片在垂直方向平铺,水平方向拉伸;"no-repeat" - 背景图片在垂直方向和水平方向都拉伸。 默认使用 "no-repeat"
redDotColorString否tabbar上红点颜色

其中 list 接收一个数组,数组中的每个项都是一个对象,其属性值如下:

属性类型必填说明平台差异
pagePathString是页面路径,必须在 pages 中先定义
textString是tab 上按钮文字,在 H5 平台为非必填。例如中间可放一个没有文字的+号图标
iconPathString否图片路径,icon 大小限制为40kb,建议尺寸为 81px * 81px,当 position 为 top 时,此参数无效,不支持网络图片,不支持字体图标
selectedIconPathString否选中时的图片路径,icon 大小限制为40kb,建议尺寸为 81px * 81px ,当 position 为 top 时,此参数无效
visibleBoolean否该项是否显示,默认显示H5
iconfontObject否字体图标,优先级高于 iconPathH5

midButton 属性说明

属性类型必填默认值描述
widthString否80px中间按钮的宽度,tabBar 其它项为减去此宽度后平分,默认值为与其它项平分宽度
heightString否50px中间按钮的高度,可以大于 tabBar 高度,达到中间凸起的效果
textString否中间按钮的文字
iconPathString否中间按钮的图片路径
iconWidthString否24px图片宽度(高度等比例缩放)
backgroundImageString否中间按钮的背景图片路径
iconfontObject否字体图标,优先级高于 iconPath

midButton没有pagePath,需监听点击事件,自行处理点击后的行为逻辑。监听点击事件为调用API:uni.onTabBarMidButtonTap,详见https://uniapp.dcloud.io/api/ui/tabbar?id=ontabbarmidbuttontap

iconfont参数说明:

属性类型说明
textString字库 Unicode 码
selectedTextString选中后字库 Unicode 码
fontSizeString字体图标字号(px)
colorString字体图标颜色
selectedColorString字体图标选中颜色

tabbar常见问题 ​

  • tabbar 的 js api 见接口-界面-tabbar,可实现动态显示隐藏(如弹出层无法覆盖tabbar)、内容修改(、item加角标等功能。hello uni-app中也有示例。
  • tabbar 的 item 点击事件见页面生命周期的onTabItemTap。
  • 代码跳转到 tabbar 页面,api只能使用qin.replace,不能使用 qin.navigateTo、qin.redirectTo;
  • tabbar 的默认高度,在不同平台不一样。开发者也可以自行设定高度,调回56px。详见
  • tabbar 在H5端是div模拟的,属于前端屏幕窗口的一部分,如果要使用bottom居底定位方式,应该使用css变量--window-bottom,比如悬浮在tabbar上方10px的按钮,样式如下bottom: calc(var(--window-bottom) + 10px)
  • 中间带+号的tabbar模板例子,参考。可跨端,但+号不凸起。如需中间凸起,配置tabbar的midButton。
  • 前端弹出遮罩层挡不住tabbar的问题,跨端处理方式时动态隐藏tabbar。
  • 微信小程序模拟器1.02.1904090版有bug,在缩放模拟器页面百分比后,tabbar点击多次后就会卡死。真机无碍,使用时注意。详见

代码示例

json
"tabBar": {
  "color": "#7A7E83",
  "selectedColor": "#3cc51f",
  "borderStyle": "black",
  "backgroundColor": "#ffffff",
  "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": "接口"
  }]
}
"tabBar": {
  "color": "#7A7E83",
  "selectedColor": "#3cc51f",
  "borderStyle": "black",
  "backgroundColor": "#ffffff",
  "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": "接口"
  }]
}

自定义tabbar ​

TODO

condition ​

启动模式配置,仅开发期间生效,用于模拟直达页面的场景,如:小程序转发后,用户点击所打开的页面。

属性说明:

属性类型是否必填描述
currentNumber是当前激活的模式,list节点的索引值
listArray是启动模式列表

list说明:

属性类型是否必填描述
nameString是启动模式名称
pathString是启动页面路径
queryString否启动参数,可在页面的 onLoad 函数里获得

注意: 在微信开发者工具里需要手动改变编译模式,如下图:

代码示例:

js
"condition": { //模式配置,仅开发期间生效
  "current": 0, //当前激活的模式(list 的索引项)
  "list": [{
      "name": "swiper", //模式名称
      "path": "pages/component/swiper/swiper", //启动页面,必选
      "query": "interval=4000&autoplay=false" //启动参数,在页面的onLoad函数里面得到。
    },
    {
      "name": "test",
      "path": "pages/component/switch/switch"
    }
  ]
}
"condition": { //模式配置,仅开发期间生效
  "current": 0, //当前激活的模式(list 的索引项)
  "list": [{
      "name": "swiper", //模式名称
      "path": "pages/component/swiper/swiper", //启动页面,必选
      "query": "interval=4000&autoplay=false" //启动参数,在页面的onLoad函数里面得到。
    },
    {
      "name": "test",
      "path": "pages/component/switch/switch"
    }
  ]
}

subPackages ​

分包加载配置,此配置为小程序的分包加载机制。

因小程序有体积和资源加载限制,各家小程序平台提供了分包方式,优化小程序的下载和启动速度。

所谓的主包,即放置默认启动页面/TabBar 页面,以及一些所有分包都需用到公共资源/JS 脚本;而分包则是根据pages.json的配置进行划分。

在小程序启动时,默认会下载主包并启动主包内页面,当用户进入分包内某个页面时,会把对应分包自动下载下来,下载完成后再进行展示。此时终端界面会有等待提示。

其目的不用于下载提速,而用于首页是 vue 时的启动提速。

subPackages 节点接收一个数组,数组每一项都是应用的子包,其属性值如下:

属性类型是否必填描述
rootString是子包的根目录
pagesArray是子包由哪些页面组成,参数同 pages

注意:

  • subPackages 里的pages的路径是 root 下的相对路径,不是全路径。
  • 微信小程序每个分包的大小是2M,总体积一共不能超过20M。
  • 抖音小程序每个分包的大小是2M,总体积一共不能超过16M(抖音小程序基础库 1.88.0 及以上版本开始支持,抖音小程序开发者工具请使用大于等于 2.0.6 且小于 3.0.0 的版本)。
  • 快手小程序每个分包的大小是2M,总体积一共不能超过24M。
  • 分包下支持独立的 static 目录,用来对静态资源进行分包。
  • qinjs内支持对微信小程序``抖音小程序、快手小程序分包优化,即将静态资源或者js文件放入分包内不占用主包大小。详情请参考:关于分包优化的说明
  • 针对vendor.js过大的情况可以使用运行时压缩代码
    • cli创建的项目可以在package.json中添加参数--minimize,示例:"dev:wx": "cross-env NODE_ENV=development UNI_PLATFORM=wx vue-cli-service uni-build --watch --minimize"

使用方法:

假设支持分包的 qinjs 目录结构如下:

shell
┌─pages
│  ├─index
│  │  └─index.vue
│  └─login
│     └─login.vue
├─pagesA
│  ├─static
│  └─list
│     └─list.vue
├─pagesB
│  ├─static
│  └─detail
│     └─detail.vue
├─static
├─main.js
├─App.vue
├─manifest.json
└─pages.json
┌─pages
│  ├─index
│  │  └─index.vue
│  └─login
│     └─login.vue
├─pagesA
│  ├─static
│  └─list
│     └─list.vue
├─pagesB
│  ├─static
│  └─detail
│     └─detail.vue
├─static
├─main.js
├─App.vue
├─manifest.json
└─pages.json

则需要在 pages.json 中填写

js
{
  "pages": [{
    "path": "pages/index/index",
    "style": { ...}
  }, {
    "path": "pages/login/login",
    "style": { ...}
  }],
  "subPackages": [{
    "root": "pagesA",
    "pages": [{
      "path": "list/list",
      "style": { ...}
    }]
  }, {
    "root": "pagesB",
    "pages": [{
      "path": "detail/detail",
      "style": { ...}
    }]
  }],
  "preloadRule": {
    "pagesA/list/list": {
      "network": "all",
      "packages": ["__APP__"]
    },
    "pagesB/detail/detail": {
      "network": "all",
      "packages": ["pagesA"]
    }
  }
}
{
  "pages": [{
    "path": "pages/index/index",
    "style": { ...}
  }, {
    "path": "pages/login/login",
    "style": { ...}
  }],
  "subPackages": [{
    "root": "pagesA",
    "pages": [{
      "path": "list/list",
      "style": { ...}
    }]
  }, {
    "root": "pagesB",
    "pages": [{
      "path": "detail/detail",
      "style": { ...}
    }]
  }],
  "preloadRule": {
    "pagesA/list/list": {
      "network": "all",
      "packages": ["__APP__"]
    },
    "pagesB/detail/detail": {
      "network": "all",
      "packages": ["pagesA"]
    }
  }
}

preloadRule ​

分包预载配置。

配置preloadRule后,在进入小程序某个页面时,由框架自动预下载可能需要的分包,提升进入后续分包页面时的启动速度

preloadRule 中,key 是页面路径,value 是进入此页面的预下载配置,每个配置有以下几项:

字段类型必填默认值说明
packagesStringArray是无进入页面后预下载分包的 root 或 name。__APP__ 表示主包。
networkString否wifi在指定网络下预下载,可选值为:all(不限网络)、wifi(仅wifi下预下载)

app的分包,同样支持preloadRule,但网络规则无效。

本地调试@local ​

在日常开发往往会有一些关于 pages.json 不想提交到代码仓库的配置,这时候 qinjs 支持本地配置的。在 .gitignore 中添加 *.local* 即可被 git 忽略。

sh
pages.json
pages.local.json
pages.h5.json
pages.h5.local.json
pages.wx.json
pages.wx.local.json
pages.tt.json
pages.tt.local.json
pages.json
pages.local.json
pages.h5.json
pages.h5.local.json
pages.wx.json
pages.wx.local.json
pages.tt.json
pages.tt.local.json

运行抖音小程序加载优先级

pages.tt.local.json (抖音配置本地) > pages.tt.json (抖音配置) > pages.local.json (默认本地配置) > pages.json (默认配置)

运行微信小程序加载优先级

pages.wx.local.json (微信配置本地) > pages.wx.json (微信配置) > pages.local.json (默认本地配置) > pages.json (默认配置)

运行 H5 加载优先级

pages.h5.local.json (抖音配置本地) > pages.h5.json (抖音配置) > pages.local.json (默认本地配置) > pages.json (默认配置)

单独调试某一个页面 ​

当项目比较大的时候小程序开发工具编译有时候会比较慢。特别是低端电脑打开页面和组件比较多的项目的时候,没保存一下需要等待1分钟甚至更多小程序开发工具才会有反应,甚至有时候等了10分钟依然没有反应。可设置 compilePages 和 compileSubPackages 单独编译某个文件,加速小程序开发工具的编译速度,提高开发效率。

json
"compilePages": [
  {
    "path": "pages/index/index",
    "routers": {
      "name": "Home",
      "path": "/"
    },
    "style": {
      "navigationBarTitleText": "INDEX_QIN_JS"
    }
  }
],
"compileSubPackages": [
  {
    "root": "pack1",
    "pages": [
      {
        "path": "pages/pack1-page1/index",
        "routers": {
          "name": "Pack1Page1",
          "path": "/pack1/page1"
        },
        "style": {
          "navigationBarTitleText": "PACK1_PAGE1_QIN_JS"
        }
      }
    ]
  }
]
"compilePages": [
  {
    "path": "pages/index/index",
    "routers": {
      "name": "Home",
      "path": "/"
    },
    "style": {
      "navigationBarTitleText": "INDEX_QIN_JS"
    }
  }
],
"compileSubPackages": [
  {
    "root": "pack1",
    "pages": [
      {
        "path": "pages/pack1-page1/index",
        "routers": {
          "name": "Pack1Page1",
          "path": "/pack1/page1"
        },
        "style": {
          "navigationBarTitleText": "PACK1_PAGE1_QIN_JS"
        }
      }
    ]
  }
]

extends ​

可以集成集体配置。 ./pages.base.json 中支持 pages.json 所有配置。

json
{
  "extends": "./pages.base.json"
}
{
  "extends": "./pages.base.json"
}

本地调试 ​

pages.json 也支持 pages.local.json 本地调试,我们可以把 .local.json 忽略 git 提交。

FAQ ​

  • Q:为什么在 pages.json 里配置小程序定位权限描述,无法编译到小程序端,运行后一直提示 getLocation 需要在 app.json 中声明
  • A:微信小程序的权限描述配置在 manifest 中,不在 pages.json 中,具体参考文档