uni-app之微信小程序开发(三)

1,844 阅读4分钟

路由管理

因为项目页面过多,在uni-app中管理页面路由太麻烦了,所以千辛万苦找到了这个方法。

构建文件构架

src文件夹家新建router文件夹,然后根据一下构建文件结构。

    router              # 动态路由文件夹
    ├── build.js        # 编译路由配置主文件
    ├── index.js        # 主配置文件
    ├── pagesA          # 分包pagesA模块文件
    │   └── inner.js    # 拆分出来的pagesA模块路由文件
    └── modules         # 动态路由模块文件
        └── small.js    # 拆分出来的模块路由文件

编写build.js文件

build.js文件为主文件,是用nodejs编写的用于编译pages.json。

  • 代码如下:

    const fs = require('fs')
    const path = require('path')
    const router = require('./index.js')
    
    // 将子路由模块配置文件转化为 uniapp 配置文件格式
    const buildRouter = route => {
      const res = []
      const { baseUrl, children } = route
      function builder (baseUrl, children) {
        children.forEach(i => {
          if (i.children) {
            builder(baseUrl + i.path + '/', i.children)
          } else {
            const obj = {
              path: baseUrl + i.path,
              style: {
                navigationBarTitleText: i.name
              }
            }
            Object.keys(i).forEach(ii => {
              !['path', 'name'].includes(ii) && (obj.style[ii] = i[ii])
            })
            res.push(obj)
          }
        })
      }
      builder(baseUrl, children)
      return res
    }
    
    // 自动加载 './modules' 目录子路由配置文件
    const getRouter = () => {
      const srcPath = path.resolve(__dirname, './modules')
      const result = fs.readdirSync(srcPath)
      let router = []
      result.forEach(r => {
        const route = require('./modules/' + r)
        router = [ ...router, ...buildRouter(route)]
      })
      return router
    }
    
    // 构建 pages 并写入 pages.json 文件
    router.pages = getRouter()
    fs.writeFile(
      __dirname + '/../pages.json',
      // 我这边是用两个空格来缩进 pages.json,如果喜欢制表符,第三个参数更换你为 \t 即可
      JSON.stringify(router, null, '  '),
      e => e ? console.error(e) : console.log('pages.json 配置文件更新成功')
    )
    
  • 如果更新了,可以看原作者源码。

编写index.js文件

该文件是用于编写除了pages.json这个文件中的pages字段外的其他内容,可参考官方配置。本人的内容如下:

module.exports = {
  easycom: {
    autoscan: true,
    custom: {
      // uni-ui 规则如下配置
      "^uni-(.*)": "@dcloudio/uni-ui/lib/uni-$1/uni-$1.vue",
      "^u-(.*)": "uview-ui/components/u-$1/u-$1.vue",
      "^my-(.*)": "@/components/my-$1/my-$1.vue", // 匹配components目录内的vue文件
    },
  },
  tabBar: {
    color: "#7A7E83",
    selectedColor: "#216df6",
    borderStyle: "black",
    backgroundColor: "#ffffff",
    list: [
      {
        pagePath: "pages/index/index",
        iconPath: "static/image/tabbar/home.png",
        selectedIconPath: "static/image/tabbar/home-1.png",
        text: "首页",
      },
      {
        pagePath: "pages/record/index",
        iconPath: "static/image/tabbar/record.png",
        selectedIconPath: "static/image/tabbar/record-1.png",
        text: "就诊记录",
      },
      {
        pagePath: "pages/userCenter/index",
        iconPath: "static/image/tabbar/userCenter.png",
        selectedIconPath: "static/image/tabbar/userCenter-1.png",
        text: "个人中心",
      },
    ],
  },
  globalStyle: {
    navigationBarTextStyle: "black",
    navigationBarTitleText: "患者端",
    navigationBarBackgroundColor: "#ffffff",
    backgroundColor: "#F8F8F8",
    h5: {
      titleNView: false,
    },
  }
};

编写modules下子路由文件

导出一个对象,代码如下:

module.exports = {
  baseUrl: 'pages/small/',
  children: [
    {
      path: 'register',
      name: '注册',
      'app-plus': {
        titleNView: {
          buttons: [
            {
              text: '消息',
              fontSize: '16px'
            }
          ]
        }
      }
    }, {
      path: 'login',
      name: '登录'
    }
  ]
}
  • baseUrl:这些文件存放的位置目录。拆分出来,可以不重要重复写这些路径。
  • children:该子路由中各个页面的路径和标题。
  • 其他配置项:如果需要使用到其他配置项,就直接写就行了,原来怎么写还怎么写。例如,上方代码的 app-plus
  • 说明:这里和 uniapp 默认的 pages.json 中的格式略有区别,我在 build.js 文件里面的 buildRouter() 函数就是做这个数据格式转化的。目的是为了让我们的子路由配置代码更加简洁。

子路由嵌套写法

虽然划分了各个子路由到不同的文件,但是,这些里面可能还是需要嵌套写法的。因此我更新了代码,增加了这种写法。

module.exports = {
  baseUrl: 'pages/site/',
  children: [
    {
      path: 'index',
      name: '首页',
      'app-plus': { titleNView: { buttons:[{ text:'消息', fontSize:'16px' }] } }
    },
    { path: 'tobeAcceptedTask', name: '待接受任务', },
    {
      path: 'task',
      // 嵌套写法演示
      children: [
        { path: 'index', name: '任务' },
        {
          path: 'deliveryMerchant', name: '配送商户',
         'app-plus': { titleNView: { buttons:[{ text:'地图模式', fontSize:'14px', width: '76px' }] } }
        },
        {
          path: 'map', name: '地图模式',
          'app-plus': { titleNView: false }
        },
        { path: 'goodsList', name: '商品列表' },
        { path: 'receivables', name: '收款' },
      ]
    },
  ]
}

分包配置和分包预载配置

本人的项目比较大,生成小程序的时候超过了2M,不能上传预览,所以进行了简单的分包。

  • build.js文件添加以下代码,用于修改pages配置:
// 自动加载 './pagesA' 目录分包文件
const getSubPackages = () => {
  const srcPath = path.resolve(__dirname, "./pagesA");
  const result = fs.readdirSync(srcPath);
  let router = [];
  result.forEach((r) => {
    const route = require("./pagesA/" + r);
    router = [...router, ...buildRouter(route)];
  });
  return [
    {
      root: "pagesA",
      pages: router,
    },
  ];
};

// 构建 getSubPackages 分包 并写入pages.json文件
router.subPackages = getSubPackages();
fs.writeFile(
  __dirname + "/../pages.json",
  // 我这边是用两个空格来缩进 pages.json,如果喜欢制表符,第三个参数更换你为 \t 即可
  JSON.stringify(router, null, "  "),
  (e) => (e ? console.error(e) : console.log("pages.json 分包配置文件更新成功"))
);

  • index.js中添加以下代码,用于分包预载配置,提高页面打开速度:
  preloadRule: {
    "pages/index/index": {
      network: "all",
      packages: ["pagesA"],
    },
  },

使用

构建好这些代码后,直接在命令行中运行 build.js 文件,就会在src文件夹下,生成pages.json配置文件。代码如下:

node src/router/build.js

特别说明

这里需要说明的是,本人是使用的 CLI 工具生成的项目,上文中的根目录就变成了项目的 src 目录。如果项目是使用 hbuilder GUI界面生成的项目,所以根目录就是项目根目录。。

参考文档

动态生成 uniapp 配置文件 pages.json 的解决方案