如何更方便的在鸿蒙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

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

最后

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

相关推荐
用户09340777351424 分钟前
HarmonyOS WPS Open SDK 实践:OpenFileRequest 打开链路与沙箱拷贝
android·typescript·harmonyos
木子雨廷1 小时前
第 01 天|心智模型:iOS/Flutter 开发者学鸿蒙,第一步该换什么思路?
harmonyos
lilian2332 小时前
HarmonyOS 7 新特性(二十一)|FAST Kit:自然排序与向量计算
华为·harmonyos
tsqtsqtsq03092 小时前
鸿蒙系统 Call Service Kit 功能详解与开发适配指南
华为·harmonyos
贾伟康3 小时前
【时光清单|17】HarmonyOS ArkTS 亮暗色与视觉令牌实战:集中颜色、间距和交互状态避免页面割裂
harmonyos·arkts·arkui·深色模式·设计系统
贾伟康3 小时前
【时光清单|15】HarmonyOS ArkTS 本地状态持久化实战:让保存、删除和页面返回后的数据即时一致
harmonyos·arkts·状态管理·preferences·arkdata
HarmonyOS_SDK11 小时前
焕新鸿蒙应用权限管理方案,应用授权体验再升级
harmonyos
贾伟康2 天前
【天体运行模拟|11】HarmonyOS ArkTS 收藏与笔记实战:同步知识页和个人学习记录
harmonyos·arkts·preferences·多设备适配·arkdata
2501_919749032 天前
华为鸿蒙录音可视化APP—小羊声觉
华为·harmonyos·鸿蒙
大雷神2 天前
HarmonyOS AR Engine深度估计实战——把毫米距离画成实时热力图
华为·ar·harmonyos