HarmonyOS NEXT 应用开发实战(六、组件导航Navigation使用详解)

在鸿蒙应用开发中,Navigation 组件是实现界面间导航的重要工具。本文将介绍如何使用 Navigation 组件实现页面跳转及参数传递,确保你能轻松构建具有良好用户体验的应用。

当前HarmonyOS支持两套路由机制(Navigation和Router),Navigation作为后续长期演进及推荐的路由选择方案,其与Router比较有不少优势。建议后续直接使用Navigation作为内部的路由方案。

Navigation介绍

Navigation组件通常作为页面的根容器,支持单页面、分栏和自适应三种显示模式。开发者可以使用Navigation组件提供的属性来设置页面的标题栏、工具栏、导航栏等。

Navigation和Router能力对标

Router路由的页面是一个@Entry修饰的Component,每一个页面都需要在main_page.json中声明。而基于Navigation的路由页面分为导航页和子页,导航页又叫Navbar,是Navigation包含的子组件,子页是NavDestination包含的子组件。

业务场景NavigationRouter
一多能力支持,Auto模式自适应单栏跟双栏显示不支持
跳转指定页面pushPath & pushDestinationpushUrl & pushNameRoute
跳转HSP中页面支持支持
跳转HAR中页面支持支持
跳转传参支持支持
获取指定页面参数支持不支持
传参类型传参为对象形式传参为对象形式,对象中暂不支持方法变量
跳转结果回调支持支持
跳转单例页面不支持支持
页面返回支持支持
页面返回传参支持支持
返回指定路由支持支持
页面返回弹窗支持,通过路由拦截实现showAlertBeforeBackPage
路由替换replacePath & replacePathByNamereplaceUrl & replaceNameRoute
路由栈清理clearclear
清理指定路由removeByIndexes & removeByName不支持
转场动画支持支持
自定义转场动画支持支持,动画类型受限
屏蔽转场动画支持全局和单次支持 设置pageTransition方法duration为0
geometryTransition共享元素动画支持(NavDestination之间共享)不支持
页面生命周期监听UIObserver.on('navDestinationUpdate')UIObserver.on('routerPageUpdate')
获取页面栈对象支持不支持
路由拦截支持通过setInercption做路由拦截不支持
路由栈信息查询支持getState() & getLength()
路由栈move操作moveToTop & moveIndexToTop不支持
沉浸式页面支持不支持,需通过window配置
设置页面标题栏(titlebar)和工具栏(toolbar)支持不支持
模态嵌套路由支持不支持

Navigation简单示例

主页面(首页面)示例:

 
@Entry
@Component
struct NavigationExample {
  build() {
    Column() {
      Navigation() {
        // 中间主区域
      }
      .title("主标题") // 页面标题
      .mode(NavigationMode.Auto) // 显示模式:Auto(自适应)、Stack(单页显示)、Split(分栏显示)、Full(强调型标题栏)、Mini(普通型标题栏)
      .menus([
        // 顶部菜单栏
      ])
      .toolBar({items: [
        // 底部工具栏
      ]})
    }
    .height('100%')
    .width('100%')
    .backgroundColor('#F1F3F5')
  }
}
// index.ets
@Entry
@Component
struct Index {
  pathStack: NavPathStack = new NavPathStack()

  build() {
    Navigation(this.pathStack) {
      Column() {
        Button('Push PageOne', { stateEffect: true, type: ButtonType.Capsule })
          .width('80%')
          .height(40)
          .margin(20)
          .onClick(() => {
            this.pathStack.pushPathByName('pageOne', null)
          })
      }.width('100%').height('100%')
    }
    .title("Navigation")
  }
}

 子页示例:

// PageOne.ets

@Builder
export function PageOneBuilder() {
  PageOne()
}

@Component
export struct PageOne {
  pathStack: NavPathStack = new NavPathStack()

  build() {
    NavDestination() {
      Column() {
        Button('回到首页', { stateEffect: true, type: ButtonType.Capsule })
          .width('80%')
          .height(40)
          .margin(20)
          .onClick(() => {
            this.pathStack.clear()
          })
      }.width('100%').height('100%')
    }.title('PageOne')
    .onReady((context: NavDestinationContext) => {
      this.pathStack = context.pathStack
    })
  }
}

注意:每个子页也需要配置到系统配置文件route_map.json中(参考 系统路由配置 ):

// 工程配置文件module.json5中配置 {"routerMap": "$profile:route_map"}
// route_map.json
{
  "routerMap": [
    {
      "name": "pageOne",
      "pageSourceFile": "src/main/ets/pages/PageOne.ets",
      "buildFunction": "PageOneBuilder",
      "data": {
        "description": "this is pageOne"
      }
    }
  ]
}

NavRouter介绍

NavRouter是Navigation组件中的特殊子组件,通常用于与Navigation组件配合使用,它默认提供了点击响应处理,不需要开发者自定义点击事件逻辑。NavRouter组件只有两个子组件,其中第二个子组件必须是NavDestination。而NavDestination则是Navigation组件中的特殊子组件,用于显示内容页的内容。当开发者点击NavRouter组件时,会跳转到对应的NavDestination内容区。

  Navigation() {
    TextInput({ placeholder: '请输入...' })
      .width('90%')
      .height(40)
      .backgroundColor('#ffffff')

    List({ space: 12 }) {
      ForEach(this.arr, item => {
        ListItem() {
          NavRouter() {
            Text("NavRouter" + item)
              .width('100%')
              .height(72)
              .backgroundColor(Color.White)
              .borderRadius(36)
              .fontSize(16)
              .fontWeight(500)
              .textAlign(TextAlign.Center)
            NavDestination() {
              Text(`NavDestinationContent${item}`)
            }
            .title(`NavDestinationTitle${item}`)
          }
        }
      })
    }
  }
  .title('主标题')
  .mode(NavigationMode.Stack)//导航模式
  .titleMode(NavigationTitleMode.Mini)//标题模式
  .menus([  //设置菜单
    { value: "", icon: './../../../resources/base/media/icon.png', action: () => {
    } },
    { value: "", icon: './../../../resources/base/media/icon.png', action: () => {
    } }
  ])
  .toolBar({ items: [  //设置工具栏
    { value: 'func', icon: './../../../resources/base/media/icon.png', action: () => {
    } },
    { value: 'func', icon: './../../../resources/base/media/icon.png', action: () => {
    } }
  ] })

在鸿蒙开发中,NavRouter 和直接使用 this.pageStack.pushDestinationByName 来实现页面跳转的确可以达到相似的效果,但它们在设计理念和使用场景上有一些区别。以下是这两者之间的一些关键点和它们各自的用途:

1. NavRouter 的用途

  • 封装与简化NavRouter 是一个封装了导航逻辑的组件,专注于处理页面间的跳转和路由管理。它提供了一个更简洁的接口以实现页面跳转,可以让开发者更容易进行组件化开发,从而提高代码的可读性和可维护性。

  • 动态路由:在 NavRouter 中,可以方便地将导航逻辑和目标页面的内容结合在一起。通过 NavRouter,不必手动管理目标页面的具体情况,可以直接利用组件的声明式来定义导航内容。

2. this.pageStack.pushDestinationByName

  • 底层控制:使用 this.pageStack.pushDestinationByName 更接近底层的 API,适合需要更细粒度控制的情况。它通常适用于需要直接处理路由堆栈的场合。

  • 灵活性:虽然提供了更多的灵活性,但相应的也要求开发者自行管理跳转的状态、参数传递等,代码可能相对繁琐,尤其是在处理复杂的导航场景时。

3. 何时使用 NavRouter

  • 如果你的应用需要在多个组件之间频繁进行导航,并且希望维护清晰的结构和可读性,使用 NavRouter 是一个不错的选择。

  • 对于简单的情况,如果你的跳转逻辑不复杂,且需要直接控制页面堆栈的行为,使用 this.pageStack.pushDestinationByName 也完全可以。

总结而言,虽然两者都可以实现页面跳转,但 NavRouter 提供了更高层次的抽象,更适合构建组件化的、可维护的导航结构,而 this.pageStack.pushDestinationByName 更适合需要底层控制的场景。选择使用哪一种方式,主要依赖于具体的开发需求和代码结构设计。简言之,NavRouter 有点儿类似于折叠效果,所有内容已经拿到了,不需要再跳转到其他页面去请求,只需展开显示即可。则使用NavRouter 可以完成在一个页面里实现想要的效果。

Navigation使用步骤

一、基本使用

将Navigation 组件作为基础页面的根容器,它能够管理整个页面的布局和导航。定义NavPathStack 实例,后面需要用它实现路由跳转和传参。Navigation通过页面栈对象 NavPathStack 提供的方法来操作页面,需要创建一个栈对象并传入Navigation中。

以下是一个基本的 Navigation 组件结构示例:

import { getZhiHuNews } from '../../common/api/zhihu';
import { BaseResponse,ErrorResp } from '../../common/bean/ApiTypes';
import { Log } from '../../utils/logutil'


@Component
export default struct ZhiHu{
  @State message: string = 'Hello World';
  private arr: number[] = [1, 2, 3];

  //重要,定义NavPathStack 实例,后面需要用它实现路由跳转和传参
  pageStack: NavPathStack = new NavPathStack()

  // 组件生命周期
  aboutToAppear() {
    Log.info('ZhiHu aboutToAppear');

    getZhiHuNews("20241017").then((res) => {
      Log.debug(res.data.message)
      Log.debug("request","res.data.code:%{public}d",res.data.code)
    }).catch((err:BaseResponse<ErrorResp>) => {
      Log.debug("request","err.data.code:%d",err.data.code)
      Log.debug("request",err.data.message)
    });
    let list: number[] = []
    for (let i = 1; i <= 10; i++) {
      list.push(i);
    }
  }

  // 组件生命周期
  aboutToDisappear() {
    Log.info('ZhiHu aboutToDisappear');
  }

  build() {
    Navigation(this.pageStack){
      Row() {
        Column({ space: 0 }) {
          // 标题栏
          Text("日报")
            .size({ width: '100%', height: 50 })
            .backgroundColor("#28bff1")
            .fontColor("#ffffff")
            .textAlign(TextAlign.Center)
            .fontSize("18fp")

          // 内容项
            Swiper(this.swiperController) {
              LazyForEach(this.data, (item: string) => {
                Stack({ alignContent: Alignment.Center }) {
                  Text(item.toString())
                    .width('100%')
                    .height(160)
                    .backgroundColor(0xAFEEEE)
                    .textAlign(TextAlign.Center)
                    .fontSize(30)
                    .zIndex(1)
                    .onClick(() => {
                      //this.pageStack.pushPathByName("PageOne", item)
                      this.pageStack.pushDestinationByName("PageOne", { id:"9773231" }).catch((e:Error)=>{
                        // 跳转失败,会返回错误码及错误信息
                        console.log(`catch exception: ${JSON.stringify(e)}`)
                      }).then(()=>{
                        // 跳转成功
                      });
                    })

                  // 显示轮播图标题
                  Text("特立独行的猫哥")
                    .padding(5)
                    .margin({ top:60 })
                    .width('100%').height(50)
                    .textAlign(TextAlign.Center)
                    .maxLines(2)
                    .textOverflow({overflow:TextOverflow.Clip})
                    .fontSize(20)
                    .fontColor(Color.White)
                    .opacity(100) // 设置标题的透明度 不透明度设为100%,表示完全不透明
                    .backgroundColor('#808080AA') // 背景颜色设为透明
                    .zIndex(2)

                }
              }, (item: string) => item)
            }
            .cachedCount(2)
            .index(1)
            .autoPlay(true)
            .interval(4000)
            .loop(true)
            .indicatorInteractive(true)
            .duration(1000)
            .itemSpace(0)
            .curve(Curve.Linear)
            .onChange((index: number) => {
              console.info(index.toString())
            })
            .onGestureSwipe((index: number, extraInfo: SwiperAnimationEvent) => {
              console.info("index: " + index)
              console.info("current offset: " + extraInfo.currentOffset)
            })
            .height(160) // 设置高度

          List({ space: 12 }) {
            ForEach(this.arr, (item:string) => {
              ListItem() {
                NavRouter() {
                  Text("NavRouter" + item)
                    .width("100%")
                    .height(72)
                    .backgroundColor('#FFFFFF')
                    .borderRadius(24)
                    .fontSize(16)
                    .fontWeight(500)
                    .textAlign(TextAlign.Center)
                  NavDestination() {
                    Text("NavDestinationContent" + item)
                  }
                  .title("NavDestinationTitle" + item)
                }
              }
            }, (item:string) => item)
          }

        }.size({ width: '100%', height: '100%' })
      }
    }
    .mode(NavigationMode.Stack)
    .width('100%').height('100%')

  }
}

注意:主页面使用  Navigation 组件作为根容器。而待跳转的子页面(目标页面),则是使用NavDestination作为根容器。

二、配置系统路由表

在进行页面跳转之前,需要在目录src/main/resources/base/profile中,创建文件route_map.json,手动注册跳转的页面。内容示例:

{
  "routerMap": [
    {
      "name": "PageOne",
      "pageSourceFile": "src/main/ets/pages/zhihu/detail/Detail.ets",
      "buildFunction": "DetailPageBuilder",
      "data": {
        "description": "this is Page Detail"
      }
    }
  ]
}

上面这个配置其实是系统路由表,从API version 12版本开始,Navigation支持系统跨模块的路由表方案,整体设计是将路由表方案下沉到系统中管理,即在需要路由的各个业务模块(HSP/HAR)中独立配置router_map.json文件,在触发路由跳转时,应用只需要通过NavPactStack进行路由跳转,此时系统会自动完成路由模块的动态加载、组件构建,并完成路由跳转功能,从而实现了开发层面的模块解耦。 

在这个示例中,name 定义了路由名称,pageSourceFile 指向页面的具体实现文件,buildFunction 则指定了构建函数。开发者需确保这些字段的正确性和一致性,以便系统能正确识别和加载目标页面。

路由表的基本概念

在新的设计中,每个业务模块(HSP / HAR)都可以独立配置 router_map.json 文件。当应用触发路由跳转时,使用 NavPathStack 内置的接口,系统将自动处理模块的动态加载和组件构建,从而实现路由跳转功能。

鸿蒙的系统路由表方案为应用开发提供了更加灵活和高效的路由管理方式。通过将路由表下沉到模块层,系统支持模块的独立配置和动态加载,不仅实现了开发层面的模块解耦,也大大简化了开发流程。对于正在进行鸿蒙应用开发来说,掌握这一机制将显著提升开发效率和应用性能。

配置路由表注意事项
  1. 注册正确:确保 name 和 buildFunction 与要跳转的页面一致。
  2. 参数获取:在目标页面中,开发者可以使用 this.pageStack.getParamByName 方法获取传递的参数。
路由模块解耦的优势
  • 独立性:每个业务模块可独立管理自己的路由信息,减少各模块间的相互依赖,提高开发效率。
  • 动态加载:通过系统自动处理模块的加载和组件构建,提升了应用的性能和响应速度。
  • 代码可维护性:在日后的维护中,开发者只需关注自身模块的路由配置和实现,对于系统的整体架构影响较小。
路由跳转的实现

使用 NavPathStack 进行路由跳转时,只需调用相应的方法并传递参数,系统会自动执行动态装载和跳转。例如:

this.pageStack.pushDestinationByName("DetailPage", { id: "9773231" })
  .catch((error) => {
    console.error(`路由跳转失败: ${JSON.stringify(error)}`);
  })
  .then(() => {
    console.log("路由跳转成功");
  });

在上述代码中,调用 pushDestinationByName 方法完成页面跳转,同时也可以传递必要的参数。其他一些操作还有:

@Entry
@Component
struct Index {
  pathStack: NavPathStack = new NavPathStack()

  build() {
    // 设置NavPathStack并传入Navigation
    Navigation(this.pathStack) {
        ...
    }.width('100%').height('100%')
  }
  .title("Navigation")
}

// push page
this.pathStack.pushPath({ name: 'pageOne' })

// pop page
this.pathStack.pop()
this.pathStack.popToIndex(1)
this.pathStack.popToName('pageOne')

// replace page
this.pathStack.replacePath({ name: 'pageOne' })

// clear all page
this.pathStack.clear()

// 获取页面栈大小
let size = this.pathStack.size()

// 删除栈中name为PageOne的所有页面
this.pathStack.removeByName("pageOne")

// 删除指定索引的页面
this.pathStack.removeByIndexes([1,3,5])

// 获取栈中所有页面name集合
this.pathStack.getAllPathName()

// 获取索引为1的页面参数
this.pathStack.getParamByIndex(1)

// 获取PageOne页面的参数
this.pathStack.getParamByName("pageOne")

// 获取PageOne页面的索引集合
this.pathStack.getIndexByName("pageOne")
...

目标页面的实现

下面是目标页面 DetailPage 的一个简单示例:

import { Log } from '../../../utils/logutil';

@Builder
export function DetailPageBuilder() {
  DetailPage()
}

@Component
export default struct DetailPage {
  @State message: string = 'Hello World';
  pageStack: NavPathStack = new NavPathStack();
  private pathInfo: NavPathInfo | null = null;

  // 组件生命周期
  aboutToAppear() {
    Log.info('Detail aboutToAppear');
  }

  // 组件生命周期
  aboutToDisappear() {
    Log.info('Detail aboutToDisappear');
  }

  build() {
    NavDestination() {
      Column({ space: 0 }) {
        Text("内容").width('100%').height('100%').textAlign(TextAlign.Center).fontSize("25fp")
      }
    }
    .title("日报详情")
    .width('100%')
    .height('100%')
    .onReady(ctx => {
      this.pageStack = ctx.pathStack;
      const params = this.pageStack.getParamByName("PageOne");
      Log.info('接收到的参数:', params);
    });
  }
}

组件生命周期与传递参数获取

在 DetailPage 的 onReady 方法中,开发者可以获取到传递的参数。这里使用 this.pageStack.getParamByName("PageOne") 获取指定页面的参数。这样可以灵活应对数据的传递和使用。

在导航页面中传递参数

使用 this.pageStack.pushDestinationByName 方法跳转到目标页面,并传递参数。例如:

this.pageStack.pushDestinationByName("TargetPage", { id: "12345", name: "示例数据" })
  .catch((error) => {
    console.error(`路由跳转失败: ${JSON.stringify(error)}`);
  });
import { Log } from '../../../utils/logutil';

@Builder
export function TargetPageBuilder() {
  TargetPage();
}

@Component
export default struct TargetPage {
  @State message: string = 'Hello from Target Page';
  pageStack: NavPathStack = new NavPathStack();
  private pathInfo: NavPathInfo | null = null;

  // 组件生命周期方法,页面即将出现
  aboutToAppear() {
    Log.info('TargetPage aboutToAppear');
  }

  // 组件生命周期方法,页面即将消失
  aboutToDisappear() {
    Log.info('TargetPage aboutToDisappear');
  }

  build() {
    NavDestination() {
      Column({ space: 0 }) {
        Text("内容").width('100%').height('100%').textAlign(TextAlign.Center).fontSize("25fp");
      }
    }
    .title("目标页面")
    .width('100%')
    .height('100%')
    .onReady(ctx => {
      this.pageStack = ctx.pathStack; // 获取当前的路径栈
      const params = this.pageStack.getParamByName("TargetPage"); // 获取传递的参数
      Log.info('接收到的参数:', params);

      // 例如,如果传递的数据为 { id: "12345", name: "示例数据" }
      if (params) {
        const id = params.id; // 获取具体的参数值
        const name = params.name;
        Log.info(`获取到的 ID: ${id}, 名称: ${name}`);
      }
    });
  }
}

总结

通过使用 Navigation 组件及其相关接口,开发者可以方便地实现页面间的跳转和数据传递,从而构建丰富且流畅的用户界面。将页面逻辑与导航结构紧密结合,可以极大提升应用的可维护性和用户体验。希望本篇文章能帮助到您在鸿蒙应用开发中的导航实现。

写在最后

最后,推荐下笔者的业余开源app影视项目“爱影家”,推荐分享给与我一样喜欢免费观影的朋友。【注:该项目仅限于学习研究使用!请勿用于其他用途!】

开源地址:爱影家app开源项目介绍及源码

https://gitee.com/yyz116/imovie

💖技术交流

 ​​​​​​​

其他资源

文档中心--组件导航 (Navigation)(推荐)

HarmonyOS:NavPathStack的详细使用说明以及示例-CSDN博客

HarmonyOS Next开发学习手册——组件导航 (Navigation) (推荐)_鸿蒙 navigation-CSDN博客

「HarmonyNextOS」页面路由跳转Router更换为Navigation_鸿蒙 routermap-CSDN博客

CommonAppDevelopment/common/routermodule/README_AUTO_GENERATE.md · HarmonyOS-Cases/Cases - Gitee.com

SystemRouterMap: 本项目提供系统路由的验证,运用系统路由表的方式,跳转到模块(HSP/HAR)的页面,可以不用配置不同跳转模块间的依赖。

HarmonyOS ArkUI实战开发-页面导航(Navigation)_arkui navigation-CSDN博客

【鸿蒙实战开发】基于Navigation的路由管理_navigation组件关联的路由栈提供了入栈方法-CSDN博客 OpenHarmony三方库中心仓--HMRouter

https://juejin.cn/post/7372488623944630281

如何开发一个OpenHarmony购物app导航页面-鸿蒙开发者社区-51CTO.COM

鸿蒙HarmonyOS实战-ArkUI组件(Navigation)_harmonyos navigation-CSDN博客

【HarmonyOS NEXT 】应用开发:ArkTS导航组件一(Navigation)_arkts navigation-CSDN博客

https://zhuanlan.zhihu.com/p/1076639693

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/896652.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Dongle Sentinal在Jenkins下访问不了的问题

背景&#xff1a; 工作站部署的jenkins的脚本无法正常打包&#xff0c;定位后发现是本地获取不了license&#xff0c;但是使用usb over network的远程license都能获取并正常打包 分析&#xff1a; 获取不了license的原因是本地无法识别dongle。根据提供信息&#xff0c;之前…

力扣76~80题

题76&#xff08;困难&#xff09;&#xff1a; 分析&#xff1a; 这道题其实不难&#xff0c;但是是我做最久的了&#xff0c;我居然去用res去接所有可能得值&#xff0c;然后再求长度导致空间暴力&#xff0c;我还以为是我queue的问题。。。 最后用暴力求解解的&#xff0c…

Apache Seata Raft模式配置中心

本文来自 Apache Seata官方文档&#xff0c;欢迎访问官网&#xff0c;查看更多深度文章。 本文来自 Apache Seata官方文档&#xff0c;欢迎访问官网&#xff0c;查看更多深度文章。 Apache Seata Raft模式配置中心 title: Seata Raft模式配置中心 author: 蒋奕晨-清华大学&…

Vue是一套构建用户界面的渐进式框架,常用于构建单页面应用

学习总结 1、掌握 JAVA入门到进阶知识(持续写作中……&#xff09; 2、学会Oracle数据库入门到入土用法(创作中……&#xff09; 3、手把手教你开发炫酷的vbs脚本制作(完善中……&#xff09; 4、牛逼哄哄的 IDEA编程利器技巧(编写中……&#xff09; 5、面经吐血整理的 面试技…

HCIE-Datacom题库_11_IPsecVPN【17道题】

一、单选题 1.IPsecSA(SecurityAssociation&#xff0c;安全联盟)有两种生成方式&#xff0c;分别是手工方式和IKE自动协商方式&#xff0c;以下关于这两种方式的描述中&#xff0c;错误的是哪一项? 手工方式和IKE方式建立的SA都支持动态刷新 IKE方式建立的SA,其生存周期由…

传奇架设GEE引擎数据库服务器提示:拒绝未授权ip连接服务器的解决办法

今天一个新手GM遇到一个问题&#xff0c;他有一个GEE引擎的传奇版本&#xff0c;数据库服务器提示&#xff1a;拒绝未授权ip连接服务器&#xff1a;222.186.50.212、111.162.159.87 1.189.121.156、14.204.122.13、1.189.141.27等等&#xff0c;出于担心服务器是否有异常&#…

【VUE安装本地自定义capacitor插件以及打包成安卓APK过程】

capacitor插件创建使用过程 1. 初始化一个vue项目2.安装capacitor依赖3.自动化创建插件4. 实现功能后构建插件,插件目录下生成dist文件夹5. vue项目中安装插件6. vue项目中使用接口7. 构建vue项目8.构建为安卓项目9.打包APK1. 初始化一个vue项目 过程省略,本案例用的vue3+ty…

AI编译器与TVM

由于AI芯片的特殊性和高度定制化&#xff0c;为了兼容硬件的多样性&#xff0c;AI模型必须能被高效地映射到各种AI芯片上。AI编译器将深度学习框架描述的AI模型作为输入&#xff0c;将为各种AI芯片生成的优化代码作为输出。AI编译器的目标是通过编译优化的方法将深度学习框架产…

onlyoffice docker启用jwt并生成jwt

一、说明 本文是docker教程&#xff0c;linux/win的安装版本也类似&#xff0c;只需要修改配置文件中的secrt就可以了【Configuring JWT for ONLYOFFICE Docs - ONLYOFFICE】 二、正文开始 docker启动时候如果不想使用jwt&#xff0c;加上参数-e JWT_ENABLEDfalse就可以了&…

AI驱动的支持截图或线框图快速生成网页应用的开源项目

Napkins.dev是什么 Napkins.dev是一个创新的开源项目&#xff0c;基于AI技术将用户的截图或线框图快速转换成可运行的网页应用程序。项目背后依托于Meta的Llama 3.1 405B大型语言模型和Llama 3.2 Vision视觉模型&#xff0c;结合Together.ai的推理服务&#xff0c;实现从视觉设…

Centos7安装ZLMediaKit

https://github.com/ZLMediaKit/ZLMediaKit 一 获取代码 git clone https://gitee.com/xia-chu/ZLMediaKit cd ZLMediaKit git submodule update --init git submodule update --init 命令用于初始化和更新 Git 仓库中的子模块&#xff08;submodules&#xff09;。这个命令…

AI劳动力崛起:人将面临失业危机?

场景 第一眼看到这个网站的时候&#xff0c;AI员工官网&#xff08;好像是部署在美国&#xff09;&#xff0c;我觉得很好奇&#xff0c;真的可以让AI替代人类完成工作吗&#xff1f;替代到什么程度呢&#xff1f;能以自然语言直接驱动吗&#xff1f; 正好手上在做爬虫项目&am…

X射线衍射(X-ray Diffraction,XRD)小白版

文章目录 实验过程原理晶体构成X射线波长diffraction 干涉效应 Braggs Law晶体间距d散射角度θ半波长λ/2公式 公式名称由来应用设备 实验过程 In the X-ray experiment , a sample is placed into the center of an instrument and illuminated with a beam of X-rays. 在X射…

Debug-029-el-table实现自动滚动分批请求数据

前情提要 最近做了一个小优化&#xff0c;还是关于展示大屏方面的。大屏中使用el-table展示列表数据&#xff0c;最初的方案是将数据全部返回&#xff0c;确实随着数据变多有性能问题&#xff0c;有时请求时间比较长。这里做的优化就是实现列表的滚动到距离底部一定高度时再次请…

Python语法结构(二)(Python Syntax Structure II)

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:Linux运维老纪的首页…

Shell编程-函数

作者介绍&#xff1a;简历上没有一个精通的运维工程师。希望大家多多关注作者&#xff0c;下面的思维导图也是预计更新的内容和当前进度(不定时更新)。 我们前面学习了那么多命令&#xff0c;以及涉及到部分逻辑判断的问题。从简单来说&#xff0c;他就是Shell编程&#xff0c;…

在Xshell中查看日志文件详情

学习总结 1、掌握 JAVA入门到进阶知识(持续写作中……&#xff09; 2、学会Oracle数据库入门到入土用法(创作中……&#xff09; 3、手把手教你开发炫酷的vbs脚本制作(完善中……&#xff09; 4、牛逼哄哄的 IDEA编程利器技巧(编写中……&#xff09; 5、面经吐血整理的 面试技…

排序06 粗排模型

前面讲的多目标模型主要是用于精排。 粗排&#xff1a;尽量减少推理的计算量&#xff0c;牺牲准确性确保线上推理的速度足够快。 精排模型和双塔模型 中间的神经网络被多个任务共享 因此&#xff0c;前期融合模型用于召回&#xff0c;后期融合可以作为精排。 小红书粗排的三…

Shell案例之一键部署mysql

1.问题 我认为啊学习就是一个思考的过程&#xff0c;思考问题的一个流程应该是&#xff1a;提出问题&#xff0c;分析问题&#xff0c;解决问题 在shell里部署mysql服务时&#xff0c;我出现一些问题&#xff1a; 1.安装mysql-server时&#xff0c;没有密钥&#xff0c;安装…

PCL 基于中值距离的点云对应关系

目录 一、概述 1.1原理 1.2实现步骤 1.3应用场景 二、代码实现 2.1关键函数 2.1.1 获取中值距离筛选后的对应点对 2.1.2获取初始点对 2.1.3可视化 2.2完整代码 三、实现效果 PCL点云算法汇总及实战案例汇总的目录地址链接&#xff1a; PCL点云算法与项目实战案例汇…