鸿蒙Router与Navigation组件导航示例详解

 更新时间:2026年06月26日 09:29:07   作者:kiros_wang  
鸿蒙提供了​​Router与Navigation两套核心组件,分别针对​​页面级跳转​​和层级化导航​​场景,帮助开发者以声明式或编程式的方式灵活控制页面流转,这篇文章主要介绍了鸿蒙Router与Navigation组件导航的相关资料,需要的朋友可以参考下

适用版本:HarmonyOS NEXT / API 12+
语言:ArkTS

一、两种导航方案概览

鸿蒙提供了两套页面导航方案,适用于不同场景:

对比维度Router(路由)Navigation(组件导航)
出现版本早期版本API 9+,API 12 成熟
导航粒度页面级(整页跳转)组件级(灵活嵌套)
栈管理系统统一管理开发者手动管理 NavPathStack
传参方式路由参数 paramsNavPathStack 携带强类型参数
适配多端手机较好,平板一般原生支持响应式(手机/平板/折叠屏)
生命周期onPageShow / onPageHideonReady / onShown / onHidden
动画系统默认动画完全自定义转场动画
推荐程度旧项目维护新项目首选

二、Router:传统页面路由

2.1 基本配置

Router 基于 文件路径 做路由,页面必须在 main_pages.json 中注册。

main_pages.json

{
  "src": [
    "pages/Index",
    "pages/DetailPage",
    "pages/ProfilePage",
    "pages/LoginPage"
  ]
}

每个页面的 .ets 文件必须加 @Entry 装饰器:

// pages/DetailPage.ets
@Entry
@Component
struct DetailPage {
  build() {
    Column() {
      Text('详情页')
    }
  }
}

2.2 页面跳转

import { router } from '@ohos.router';

// ① 普通跳转(可返回)
router.pushUrl({
  url: 'pages/DetailPage',
  params: {
    id: '123',
    title: '商品详情',
  }
});

// ② 替换当前页(不可返回)
router.replaceUrl({
  url: 'pages/LoginPage',
});

// ③ 跳转并清空历史栈
router.pushUrl(
  { url: 'pages/Index' },
  router.RouterMode.Single // 单实例模式:若栈中已有该页则移到顶部
);

2.3 接收参数

// pages/DetailPage.ets
import { router } from '@ohos.router';

interface DetailParams {
  id: string;
  title: string;
}

@Entry
@Component
struct DetailPage {
  private params: DetailParams = router.getParams() as DetailParams;

  build() {
    Column() {
      Text(`ID: ${this.params.id}`)
      Text(`标题: ${this.params.title}`)
    }
  }
}

2.4 返回与返回传值

// 简单返回
router.back();

// 返回到指定页面
router.back({ url: 'pages/Index' });

// 返回并带数据(通过 params,接收方在 onPageShow 中获取)
router.back({
  url: 'pages/OrderPage',
  params: { refreshList: true }
});
// OrderPage.ets 在 onPageShow 中接收返回数据
@Entry
@Component
struct OrderPage {
  onPageShow() {
    const params = router.getParams() as Record<string, boolean>;
    if (params?.refreshList) {
      this.loadOrders();
    }
  }

  loadOrders() { /* ... */ }

  build() { /* ... */ }
}

2.5 Router 完整案例:商品列表 → 详情

列表页 ProductListPage.ets

import { router } from '@ohos.router';

interface Product {
  id: string;
  name: string;
  price: number;
}

@Entry
@Component
struct ProductListPage {
  private products: Product[] = [
    { id: '1', name: '苹果', price: 5 },
    { id: '2', name: '橙子', price: 8 },
    { id: '3', name: '葡萄', price: 15 },
  ];

  build() {
    Column() {
      Text('商品列表').fontSize(20).fontWeight(FontWeight.Bold).margin(16)

      List({ space: 12 }) {
        ForEach(this.products, (item: Product) => {
          ListItem() {
            Row() {
              Text(item.name).fontSize(16).layoutWeight(1)
              Text(`¥${item.price}`).fontSize(16).fontColor('#FF5722')
            }
            .width('100%')
            .padding(16)
            .backgroundColor(Color.White)
            .borderRadius(8)
          }
          .onClick(() => {
            router.pushUrl({
              url: 'pages/ProductDetailPage',
              params: { id: item.id, name: item.name, price: item.price }
            });
          })
        })
      }
      .width('100%')
      .padding({ left: 16, right: 16 })
    }
    .width('100%')
    .height('100%')
    .backgroundColor('#F5F5F5')
  }
}

详情页 ProductDetailPage.ets

import { router } from '@ohos.router';

interface ProductParams {
  id: string;
  name: string;
  price: number;
}

@Entry
@Component
struct ProductDetailPage {
  private product: ProductParams = router.getParams() as ProductParams;
  @State inCart: boolean = false;

  build() {
    Column() {
      // 顶部导航栏
      Row() {
        Image($r('app.media.ic_back'))
          .width(24).height(24)
          .onClick(() => router.back())
        Text('商品详情').fontSize(18).fontWeight(FontWeight.Medium).margin({ left: 16 })
      }
      .width('100%').height(56).padding({ left: 16 })

      // 内容
      Column({ space: 12 }) {
        Text(this.product.name).fontSize(24).fontWeight(FontWeight.Bold)
        Text(`¥${this.product.price}`).fontSize(20).fontColor('#FF5722')
        Text('商品描述:这是一款优质的新鲜水果,产地直供。').fontSize(14).fontColor('#666')
      }
      .width('100%').padding(16).alignItems(HorizontalAlign.Start)

      // 加入购物车
      Button(this.inCart ? '已加入购物车' : '加入购物车')
        .width('90%')
        .backgroundColor(this.inCart ? '#999' : '#FF5722')
        .onClick(() => {
          this.inCart = true;
          // 返回时通知列表页刷新购物车数量
          router.back({
            url: 'pages/ProductListPage',
            params: { cartUpdated: true }
          });
        })
    }
    .width('100%').height('100%')
  }
}

2.6 Router 的局限性

  1. 必须注册页面路径,动态路由不方便
  2. 参数是 Object 类型,没有 TypeScript 类型推断
  3. 平板适配差,无法天然实现左右分栏
  4. 无法细粒度控制转场动画
  5. 返回传值麻烦,需要在 onPageShow 中手动获取

三、Navigation:组件化导航(推荐)

3.1 核心概念

Navigation 由三个核心部分组成:

Navigation(导航容器)
    │
    ├── NavPathStack(路由栈,由开发者创建和管理)
    │
    └── NavDestination(导航目标页,替代 @Entry 页面)
            └── 通过 navDestination Builder 动态创建

关键特点:

  • NavPathStack 是强类型的路由栈,可携带任意类型参数
  • NavDestination 是组件,不需要在 main_pages.json 注册
  • 支持响应式布局(NavigationMode.Auto 自动切换单/双栏)

3.2 最简单的 Navigation 示例

// Index.ets(入口页)
@Entry
@ComponentV2
struct Index {
  // ① 创建并管理路由栈
  private stack: NavPathStack = new NavPathStack();

  build() {
    // ② Navigation 作为根容器,绑定路由栈
    Navigation(this.stack) {
      // 主页内容
      Column() {
        Text('首页').fontSize(24)
        Button('跳转详情页')
          .onClick(() => {
            // ③ 通过路由栈跳转
            this.stack.pushPathByName('DetailPage', { id: '123' });
          })
      }
      .width('100%').height('100%').justifyContent(FlexAlign.Center)
    }
    // ④ 注册所有目标页面
    .navDestination(pageMap)
    .mode(NavigationMode.Stack)
    .hideTitleBar(true)
  }
}

// ⑤ 路由映射表(Builder 函数)
@Builder
function pageMap(name: string, param: object) {
  if (name === 'DetailPage') {
    DetailPage({ param: param as DetailParam })
  }
}
// DetailPage.ets(目标页)
interface DetailParam {
  id: string;
}

@ComponentV2
struct DetailPage {
  @Param param: DetailParam = { id: '' };
  // 通过 @Consumer 获取路由栈(可选,也可通过 NavDestinationContext)
  @Consumer() stack: NavPathStack = new NavPathStack();

  build() {
    NavDestination() {
      Column() {
        Text(`详情 ID: ${this.param.id}`)
        Button('返回')
          .onClick(() => this.stack.pop())
      }
      .width('100%').height('100%').justifyContent(FlexAlign.Center)
    }
    .title('详情页')
  }
}

3.3 NavPathStack 常用 API

const stack = new NavPathStack();

// === 跳转 ===
stack.pushPathByName('PageName', params);       // 压栈跳转
stack.pushPathByName('PageName', params, false); // 跳转但不加动画
stack.replacePath({ name: 'LoginPage' });        // 替换当前页(不可返回)
stack.pushPath({ name: 'PageName', param: {} }); // 使用 NavPathInfo 跳转

// === 返回 ===
stack.pop();                    // 返回上一页
stack.pop({ result: 'ok' });    // 返回并携带结果
stack.popToName('HomePage');    // 返回到指定页面
stack.popToIndex(0);            // 返回到栈底
stack.clear();                  // 清空路由栈

// === 查询 ===
stack.size();                   // 栈的深度
stack.getAllPathName();          // 获取所有页面名称列表
stack.getParamByName('PageName'); // 获取某页面的参数

3.4 接收返回值

Navigation 支持优雅的返回值回调,不需要像 Router 那样在 onPageShow 中判断:

// 跳转时注册回调
stack.pushPathByName('EditPage', { userId: '123' }, (popInfo) => {
  // 当 EditPage 调用 stack.pop(result) 时,这里收到返回值
  const result = popInfo.result as EditResult;
  if (result.saved) {
    this.loadUserInfo(); // 刷新数据
  }
});
// EditPage 返回时携带结果
@ComponentV2
struct EditPage {
  @Consumer() stack: NavPathStack = new NavPathStack();

  build() {
    NavDestination() {
      Button('保存并返回')
        .onClick(() => {
          // pop 时传入结果
          this.stack.pop({ saved: true, nickname: '新昵称' });
        })
    }
  }
}

3.5 完整案例:电商 App 导航架构

这是一个完整的三层导航案例:首页 → 商品列表 → 商品详情。

第一步:定义路由常量和参数类型

// constants/RouteNames.ets
export const RouteNames = {
  PRODUCT_LIST: 'ProductListPage',
  PRODUCT_DETAIL: 'ProductDetailPage',
  ORDER_CONFIRM: 'OrderConfirmPage',
  LOGIN: 'LoginPage',
};

// 各页面参数类型
export interface ProductListParam {
  categoryId: string;
  categoryName: string;
}

export interface ProductDetailParam {
  productId: string;
  productName: string;
  price: number;
}

export interface OrderConfirmParam {
  productId: string;
  quantity: number;
}

第二步:创建路由映射(集中管理)

// router/PageMap.ets
import { RouteNames, ProductListParam, ProductDetailParam, OrderConfirmParam } from '../constants/RouteNames';
import { ProductListPage } from '../pages/ProductListPage';
import { ProductDetailPage } from '../pages/ProductDetailPage';
import { OrderConfirmPage } from '../pages/OrderConfirmPage';
import { LoginPage } from '../pages/LoginPage';

@Builder
export function AppPageMap(name: string, param: object) {
  if (name === RouteNames.PRODUCT_LIST) {
    ProductListPage({ param: param as ProductListParam })
  } else if (name === RouteNames.PRODUCT_DETAIL) {
    ProductDetailPage({ param: param as ProductDetailParam })
  } else if (name === RouteNames.ORDER_CONFIRM) {
    OrderConfirmPage({ param: param as OrderConfirmParam })
  } else if (name === RouteNames.LOGIN) {
    LoginPage()
  }
}

第三步:入口页(首页)

// pages/Index.ets
import { AppPageMap } from '../router/PageMap';
import { RouteNames, ProductListParam } from '../constants/RouteNames';

@Entry
@ComponentV2
struct Index {
  @Provider() stack: NavPathStack = new NavPathStack();

  private categories = [
    { id: 'fruit', name: '水果生鲜' },
    { id: 'snack', name: '零食饮料' },
    { id: 'daily', name: '日用百货' },
  ];

  build() {
    Navigation(this.stack) {
      Scroll() {
        Column({ space: 16 }) {
          Text('首页').fontSize(24).fontWeight(FontWeight.Bold)

          // 分类入口
          ForEach(this.categories, (cat: { id: string; name: string }) => {
            Row() {
              Text(cat.name).fontSize(16).layoutWeight(1)
              Image($r('app.media.ic_arrow_right')).width(16).height(16)
            }
            .width('100%').padding(16)
            .backgroundColor(Color.White).borderRadius(8)
            .onClick(() => {
              const param: ProductListParam = {
                categoryId: cat.id,
                categoryName: cat.name,
              };
              this.stack.pushPathByName(RouteNames.PRODUCT_LIST, param);
            })
          })
        }
        .padding(16)
      }
    }
    .navDestination(AppPageMap)
    .mode(NavigationMode.Stack)
    .hideTitleBar(true)
    .width('100%').height('100%')
  }
}

第四步:商品列表页

// pages/ProductListPage.ets
import { RouteNames, ProductListParam, ProductDetailParam } from '../constants/RouteNames';

interface Product {
  id: string;
  name: string;
  price: number;
}

@ComponentV2
export struct ProductListPage {
  @Param param: ProductListParam = { categoryId: '', categoryName: '' };
  @Consumer() stack: NavPathStack = new NavPathStack();

  // 模拟数据
  private getProducts(): Product[] {
    return [
      { id: 'p1', name: `${this.param.categoryName}-商品A`, price: 19.9 },
      { id: 'p2', name: `${this.param.categoryName}-商品B`, price: 35.5 },
      { id: 'p3', name: `${this.param.categoryName}-商品C`, price: 8.8 },
    ];
  }

  build() {
    NavDestination() {
      List({ space: 12 }) {
        ForEach(this.getProducts(), (product: Product) => {
          ListItem() {
            Row() {
              Column({ space: 4 }) {
                Text(product.name).fontSize(16)
                Text(`¥${product.price.toFixed(2)}`).fontSize(14).fontColor('#FF5722')
              }
              .alignItems(HorizontalAlign.Start).layoutWeight(1)

              Button('查看详情').fontSize(12)
                .onClick(() => {
                  const param: ProductDetailParam = {
                    productId: product.id,
                    productName: product.name,
                    price: product.price,
                  };
                  // 跳转详情并接收返回值
                  this.stack.pushPathByName(RouteNames.PRODUCT_DETAIL, param, (popInfo) => {
                    const result = popInfo.result as { addedToCart: boolean };
                    if (result?.addedToCart) {
                      console.info('用户已加入购物车,刷新角标');
                    }
                  });
                })
            }
            .width('100%').padding(16)
            .backgroundColor(Color.White).borderRadius(8)
          }
        })
      }
      .padding(16)
    }
    .title(this.param.categoryName)
    .backgroundColor('#F5F5F5')
  }
}

第五步:商品详情页

// pages/ProductDetailPage.ets
import { RouteNames, ProductDetailParam, OrderConfirmParam } from '../constants/RouteNames';

@ComponentV2
export struct ProductDetailPage {
  @Param param: ProductDetailParam = { productId: '', productName: '', price: 0 };
  @Consumer() stack: NavPathStack = new NavPathStack();
  @Local quantity: number = 1;

  build() {
    NavDestination() {
      Column({ space: 0 }) {

        // 商品信息区
        Column({ space: 12 }) {
          Text(this.param.productName)
            .fontSize(22).fontWeight(FontWeight.Bold)
          Text(`¥${this.param.price.toFixed(2)}`)
            .fontSize(20).fontColor('#FF5722')
          Text('产地直供,新鲜直达,品质保证。')
            .fontSize(14).fontColor('#888').lineHeight(22)
        }
        .width('100%').padding(16).alignItems(HorizontalAlign.Start)
        .backgroundColor(Color.White)

        // 数量选择
        Row({ space: 16 }) {
          Text('数量').fontSize(15)
          Row({ space: 12 }) {
            Button('-').width(32).height(32)
              .onClick(() => { if (this.quantity > 1) this.quantity--; })
            Text(`${this.quantity}`).fontSize(16).width(40).textAlign(TextAlign.Center)
            Button('+').width(32).height(32)
              .onClick(() => { this.quantity++; })
          }
        }
        .width('100%').padding(16).justifyContent(FlexAlign.SpaceBetween)
        .backgroundColor(Color.White).margin({ top: 8 })

        Blank()

        // 底部按钮区
        Row({ space: 12 }) {
          Button('加入购物车')
            .layoutWeight(1).backgroundColor('#FF9800')
            .onClick(() => {
              // 返回并携带结果给列表页
              this.stack.pop({ addedToCart: true });
            })

          Button('立即购买')
            .layoutWeight(1).backgroundColor('#FF5722')
            .onClick(() => {
              const param: OrderConfirmParam = {
                productId: this.param.productId,
                quantity: this.quantity,
              };
              this.stack.pushPathByName(RouteNames.ORDER_CONFIRM, param);
            })
        }
        .width('100%').padding(16)
        .backgroundColor(Color.White)
        .border({ width: { top: 1 }, color: '#F0F0F0' })
      }
      .width('100%').height('100%').backgroundColor('#F5F5F5')
    }
    .title(this.param.productName)
  }
}

3.6 NavigationMode 响应式布局(平板适配)

Navigation 最大的优势之一是原生支持响应式双栏布局,一套代码适配手机和平板。

@Entry
@ComponentV2
struct Index {
  @Provider() stack: NavPathStack = new NavPathStack();

  build() {
    Navigation(this.stack) {
      // 左栏:分类列表(平板模式下常驻)
      CategoryList()
    }
    .navDestination(AppPageMap)
    // Auto 模式:屏幕宽 < 520vp 单栏,>= 520vp 自动双栏
    .mode(NavigationMode.Auto)
    // 双栏时左栏宽度
    .navBarWidth(300)
    .navBarWidthRange([240, 400])
    .hideTitleBar(true)
  }
}
模式说明
NavigationMode.Stack始终单栏(手机常用)
NavigationMode.Split始终双栏(横屏平板)
NavigationMode.Auto自动根据屏幕宽度切换

3.7 自定义转场动画

Navigation 支持完全自定义的转场效果:

// 入场动画(从右侧滑入)
stack.pushPathByName('DetailPage', param);

// 在 NavDestination 中配置动画
NavDestination() {
  // ...
}
.customNavContentTransition((from, to, operation) => {
  // operation: NavigationOperation.PUSH / POP / REPLACE
  const isForward = operation === NavigationOperation.PUSH;
  return {
    onTransitionEnd: (isSuccess: boolean) => {},
    timeout: 1000,
    transition: (proxy: NavigationTransitionProxy) => {
      // 自定义动画逻辑
      animateTo({ duration: 300, curve: Curve.EaseOut }, () => {
        proxy.finishTransition();
      });
    }
  };
})

3.8 NavDestination 生命周期

NavDestination 有独立的生命周期,比 Router 页面更精细:

NavDestination() {
  // ...
}
.onReady((ctx: NavDestinationContext) => {
  // 页面创建完成,可获取参数和路由栈
  const param = ctx.pathInfo.param;
  const stack = ctx.pathStack;
})
.onShown(() => {
  // 页面出现在前台(包括从下级页面返回)
  console.info('页面可见,刷新数据');
})
.onHidden(() => {
  // 页面被遮挡(跳转到下级页面时)
  console.info('页面不可见,暂停动画');
})
.onBackPressed(() => {
  // 拦截返回键,返回 true 表示自行处理(不执行默认返回)
  if (this.hasUnsavedChanges) {
    this.showSaveDialog();
    return true;
  }
  return false; // false = 执行默认返回行为
})

四、Router vs Navigation 对比总结

4.1 参数传递对比

Router(类型不安全)

// 发送方
router.pushUrl({
  url: 'pages/Detail',
  params: { id: '123' } // Object 类型,无类型约束
});

// 接收方(需要手动断言,容易出错)
const params = router.getParams() as { id: string };

Navigation(强类型)

// 发送方
interface DetailParam { id: string; }
stack.pushPathByName('DetailPage', { id: '123' } as DetailParam);

// 接收方(通过 @Param 直接接收,完全类型安全)
@ComponentV2
struct DetailPage {
  @Param param: DetailParam = { id: '' };
}

4.2 返回值对比

Router(繁琐)

// 返回方(只能夹带在 params 里)
router.back({ url: 'pages/List', params: { refreshed: true } });

// 接收方(需要在 onPageShow 里判断)
onPageShow() {
  const p = router.getParams() as { refreshed?: boolean };
  if (p?.refreshed) this.refresh();
}

Navigation(优雅)

// 跳转时直接注册回调
stack.pushPathByName('EditPage', param, (popInfo) => {
  const result = popInfo.result as { refreshed: boolean };
  if (result.refreshed) this.refresh();
});

// 返回方
stack.pop({ refreshed: true });

4.3 适用场景选择

新项目?
    └── 是 → 直接用 Navigation ✅

旧项目?
    ├── 页面不多,维护即可 → 继续用 Router
    └── 需要平板适配 / 复杂动画 → 逐步迁移到 Navigation

需要平板双栏布局?
    └── 必须用 Navigation(NavigationMode.Auto)

需要拦截返回键?
    ├── Router → onBackPress() 只能全局处理
    └── Navigation → NavDestination.onBackPressed() 精细控制

页面层级深(3层以上)?
    └── 推荐 Navigation(NavPathStack 管理更清晰)

五、混用方案(过渡期)

如果项目中已有大量 Router 代码,短期内可以混用,但需注意:

// 在 Navigation 体系中调用 Router 跳转到旧页面
import { router } from '@ohos.router';

@ComponentV2
struct SomePage {
  @Consumer() stack: NavPathStack = new NavPathStack();

  build() {
    NavDestination() {
      Button('跳转旧页面(Router)')
        .onClick(() => {
          // 新旧混用,谨慎使用
          router.pushUrl({ url: 'pages/OldPage' });
        })
    }
  }
}

⚠️ 混用注意事项:

  1. Router 和 Navigation 各自维护独立的路由栈,router.back() 不会影响 NavPathStack
  2. 混用期间动画可能不一致
  3. 建议新功能全部用 Navigation,旧页面逐步迁移

六、常见坑点

坑 1:NavDestination 不写 @Param 导致参数丢失

// ❌ 错误:用普通属性接收,首次渲染时参数可能未初始化
@ComponentV2
struct DetailPage {
  param: DetailParam = { id: '' }; // 没有 @Param
}

// ✅ 正确:必须用 @Param 装饰器
@ComponentV2
struct DetailPage {
  @Param param: DetailParam = { id: '' };
}

坑 2:路由栈没有用 @Provider 导致子组件拿不到

// ❌ 错误:普通属性不会被 @Consumer 接收
struct Index {
  private stack: NavPathStack = new NavPathStack(); // 普通属性
}

// ✅ 正确:用 @Provider 使子组件可以 @Consumer 接收
struct Index {
  @Provider() stack: NavPathStack = new NavPathStack();
}

坑 3:多个 Navigation 嵌套导致路由混乱

// ❌ 错误:Index 和 DetailPage 各自有 Navigation,会产生两个路由栈
struct Index {
  build() {
    Navigation(this.stack) {
      // ...
    }
  }
}
struct DetailPage {
  build() {
    NavDestination() {
      Navigation(anotherStack) { // ❌ 多余的嵌套 Navigation
        // ...
      }
    }
  }
}

// ✅ 正确:全局只有一个根 Navigation,子页面用 NavDestination

坑 4:忘记在 navDestination 中注册页面

// ❌ 错误:跳转后白屏
Navigation(this.stack) { /* ... */ }
// 没有 .navDestination(pageMap)

// ✅ 正确:必须绑定 pageMap
Navigation(this.stack) { /* ... */ }
.navDestination(pageMap)

七、总结

场景推荐方案
新项目Navigation(全面使用)
旧项目维护Router(不动现有代码)
需要平板/折叠屏适配Navigation(Auto 模式)
需要强类型参数Navigation(@Param)
需要优雅的返回值Navigation(pop 回调)
需要精细控制生命周期Navigation(onShown/onHidden)
简单的几个页面跳转Router 或 Navigation 均可

一句话总结: Router 是「跳页面」,Navigation 是「管状态」——Navigation 把整个应用的页面流转统一纳入 NavPathStack 管理,是鸿蒙官方力推的现代导航方案,新项目直接用就对了。

到此这篇关于鸿蒙Router与Navigation组件导航的文章就介绍到这了,更多相关鸿蒙Router与Navigation组件导航内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Xmind8 Pro 最新激活序列号

    Xmind8 Pro 最新激活序列号

    最近需要打开文件后缀名为.xmind的文件,所以下载了Xmind8 。打开以后想要导出,奈何普通版本只能导出.txt文本文档,所以就总结出了这篇文章,对Xmind8 Pro破解方法感兴趣的朋友跟随小编一起看看吧
    2021-05-05
  • 浅析mmdetection在windows10系统环境中搭建过程

    浅析mmdetection在windows10系统环境中搭建过程

    这篇文章主要介绍了mmdetection在windows10系统环境中搭建过程,本文图文并茂通过实例代码给大家介绍的非常详细,具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-01-01
  • JetBrains发布java代码质量检测工具Qodana早期预览版

    JetBrains发布java代码质量检测工具Qodana早期预览版

    这篇文章主要介绍了JetBrains发布java代码质量检测工具Qodana早期预览版,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2021-01-01
  • 详解HBase表的数据模型

    详解HBase表的数据模型

    HBase 是一种列存储模式与键值对存储模式结合的 NoSQL 数据库,它具有灵活的数据模型,不仅可以基于键进行快速查询,还可以实现基于值、列名等的全文遍历和检索,下面给大家介绍HBase表的数据模型,感兴趣的朋友一起看看吧
    2022-05-05
  • 软件测试面试如何测试一个杯子

    软件测试面试如何测试一个杯子

    本文主要介绍软件测试面试如何测试一个杯子,这里帮大家整理了详细的面试资料,和面试需要准备的知识点,有兴趣的小伙伴可以参考下
    2016-08-08
  • MobaXterm详细使用图文教程(MobaXterm连接Linux服务器)

    MobaXterm详细使用图文教程(MobaXterm连接Linux服务器)

    这篇文章主要介绍了MobaXterm详细使用教程,介绍一下如何设置并用MobaXterm来连接Linux服务器,本文介绍了三种连接方式:SSH,FTP,serial,以及几个有用的设置和命令,需要的朋友可以参考下
    2023-05-05
  • Emscripten在Windows10下的安装和配置

    Emscripten在Windows10下的安装和配置

    这篇文章主要介绍了Emscripten在Windows10下的安装和配置,Emscripten 是一个完整的 WebAssembly开源编译器工具链,使用Emscripten可以参考平台说明,感兴趣的朋友一起看看吧
    2022-05-05
  • MobaXterm入门使用教程

    MobaXterm入门使用教程

    MobaXterm就是一款SSH客户端,它帮助我们在Windows操作系统下去连接并操作Linux服务器,本文主要介绍了MobaXterm入门使用教程,感兴趣的可以了解一下
    2023-05-05
  • 网站搜索框使用微信扫码功能

    网站搜索框使用微信扫码功能

    客户要求可以直接识别标签二维码对某些仪器设备进行管理,类似于淘宝搜索框可以直接拍照搜索商品一样。接下来通过本文给大家分享网站搜索框使用微信扫码功能,需要的朋友可以参考下
    2019-08-08
  • win10安装Anaconda+tensorflow2.0-CPU+Pycharm的图文教程

    win10安装Anaconda+tensorflow2.0-CPU+Pycharm的图文教程

    本文通过图文并茂的形式给大家介绍了win10安装Anaconda+tensorflow2.0-CPU+Pycharm的教程,非常不错,具有一定的参考借鉴价值,需要的朋友可以参考下
    2019-12-12

最新评论