如何更方便的在鸿蒙Next中进行页面跳转

背景

了解过鸿蒙开发的应该都清楚,在单模块应用和多模块应用,应该如何进行页面的跳转

js 复制代码
// url:页面在模块内的相对路径,在模块内的main_pages.json中声明
router.pushUrl({ url: 'pages/LaunchPage' })
  • 单模块应用,可以直接传入模块内的main_pages.json中页面的路径即可跳转
  • 多模块应用,方法不变,页面的路径修改为:
js 复制代码
// 固定的前缀:@bundle:
// 固定的应用包名:bundleName
// 页面所在的模块名:moduleName
// 默认的模块内的源文件目录:ets
// 固定的页面在main_pages.json中的相对路径:例如:'pages/LaunchPage'
router.pushUrl({ url: '@bundle:${bundleName}/${moduleName}/ets/pages/LaunchPage' })

因为大部分的应用都会是多模块应用,所以这次主要想解决的,也是多模块应用下的页面跳转。

遇到的问题

  1. 页面跳转时,需要拼接的字符串比较长,不易于开发
  2. 页面的文件名一般不会修改,但是文件路径可能会有修改,如果文件路径有修改,所有跳转该页面的代码,都需要做调整,工作量较大

解决思路

a. 目的是通过封装统一的路由方法,调用方只需要传入页面的文件名即可完成跳转,不需要额外的拼接

b.后续也可以结合自己的业务,可以手动给每个Page绑定自己的路由别名,在跳转时,通过别名跳转,这个别名会确保不会修改,并且可以关联新的页面文件。类似安卓的ARouter,鸿蒙Next目前还没有发现好用的三方库

  1. 新建一个WLRouterKit的模块,并且新建一个RouterSourceData.ts文件,目的是想通过编译期间的脚本代码,自动读取每个模块的main_pages.json文件,获取所有页面的模块内的相对路径
  2. 在读取每个模块的文件路径时,直接生成好包含模块名的页面路径部分:/${moduleName}/ets/pages/LaunchPage'
  3. 创建一个Map属性,key是页面的文件名,value是上面第二步生成的路径。如此就可以通过文件名匹配到对应的路径,最后在跳转时,拼接上固定的前缀部分即可。

实现代码

脚本代码

编译期间会执行hvigorfile.ts,他里面默认是可以注册插件的,这个我还没有了解怎么使用,目前就是直接在这个文件中定义方法,并且执行即可

hvigorfile.ts 复制代码
let fs = require('fs')
let path = require('path')
function generateRouter() {
    // 读取文件信息
    // WLRouterKit的路径:/Users/xxx/WLRouterKit
    let routerKitDirname = path.join(__dirname)
    // 获取项目的根目录:/Users/xxxx/xxx,因为我的WLRouterKit是在根目录的common目录下
    const rootPath = path.dirname(path.dirname(routerKitDirname))
    let totalRouters = {}
    // 读取features和common目录下的所有模块
    const dirs = ['features', 'common']
    // main_pages.json在模块内的相对路径,固定的路径
    const mainPagesModulePath = 'src/main/resources/base/profile/main_pages.json'
    dirs.forEach(dir => {
        // 读取所有features和common目录下的模块
        const dirPath = path.join(rootPath, dir)
        const moduleDirs = fs.readdirSync(dirPath)
        moduleDirs.forEach(file => {
            // 拼接文件路径
            const mainPagesFilePath = path.join(dirPath, file, mainPagesModulePath)
            // 判断文件是否存在
            if (fs.existsSync(mainPagesFilePath)) {
                console.log(`模块内的main_pages.json读取成功,${mainPagesFilePath}`)
                // 读取文件内容
                const jsonData = fs.readFileSync(mainPagesFilePath, 'utf-8')
                const data = JSON.parse(jsonData)
                const src = data.src
                for (const path of src) {
                    const values = path.split('/')
                    const fileName = values[values.length - 1]
                    const pageUrl = `${file}/ets/${path}`
                    totalRouters[fileName] = pageUrl
                }
            }
        })
    })

    // 1. 生成类名等信息
    var content = '/*自动生成的路由数据*/'
    content = content + '\nabstract class RouterSourceData { \n'
    // 2. 根据本地配置的路由routers,生成targetDatas属性
    content = content + "\tstatic targetDatas: { [key: string]: string } = { "
    const keys = Object.keys(totalRouters)
    keys.forEach(key => {
        const value = totalRouters[key]
        const line = `\r\t '${key}': '${value}',`
        content = content + line
    })
    content = content + '\r\t}'

    /// 类结束定义
    content = content + '\n}'
    content = content + '\nexport default RouterSourceData'

    // 写入文件
    const writePath = path.join(__dirname, 'src/main/ets/RouterSourceData.ts')
    fs.writeFile(writePath, content, function (err) {
        if (err) {
            console.log('文件写入失败')
            return
        }
        console.log('文件写入成功')
    })
}

生成的目标类结构:

RouterSourceData.ts 复制代码
/*自动生成的路由数据*/
abstract class RouterSourceData { 
	static targetDatas: { [key: string]: string } = { 
	 'Index': 'xxKit/ets/pages/Index',
	 'LaunchPage': 'XXModule/ets/pages/LaunchPage',
	 'LoginRegisterPage': 'XXModule/ets/pages/LoginRegisterPage',
	 'TestPage': 'xxKit/ets/CommonWeb/Test/TestPage',
	}
}
export default RouterSourceData

生成出这样的数据结构,就可以很方便的进行页面跳转的封装,通过页面的文件名,找到对应的文件路径。并且每次新增文件或者修改文件路径,在编译之后,就自动有正确的文件路径覆盖这个文件。

最后

提供这样一个解决的思路,提供了最基本的获取多模块应用下的文件路径的思路,后续可以自行进行其他的扩展。

相关推荐
Android技术栈10 小时前
鸿蒙开发(NEXT/API 12)【管理应用与Wear Engine服务的连接状态】手机侧应用开发
服务器·harmonyos·鸿蒙·鸿蒙系统·openharmony
baobao熊1 天前
【HarmonyOS】时间处理Dayjs
华为·harmonyos
zhongcx1 天前
鸿蒙应用示例:DevEco Testing 工具的常用功能及使用场景
harmonyos
@海~涛1 天前
鸿蒙OpenHarmony
华为·harmonyos
zhongcx1 天前
鸿蒙应用示例:镂空效果实现教程
harmonyos
训山1 天前
【11】纯血鸿蒙HarmonyOS NEXT星河版开发0基础学习笔记-模块化语法与自定义组件
笔记·学习·华为·harmonyos·鸿蒙系统
helloxmg2 天前
鸿蒙harmonyos next flutter混合开发之开发package
flutter·华为·harmonyos
zhongcx2 天前
鸿蒙应用示例:ArkTS UI框架中的文本缩进技巧
harmonyos
东林知识库2 天前
鸿蒙NEXT开发-自定义构建函数(基于最新api12稳定版)
华为·harmonyos