uniapp的navigator跳转功能

接下来,我将围绕一个常见的电商小程序来构建一系列连贯的使用场景。在这个过程中,我们将把 <navigator> 组件的所有关键属性和方法都串联起来,并详细解释它们在每个环节所扮演的角色和作用。

核心场景:构建一个电商小程序的用户购物流程

想象一下,我们正在开发一个名为“优品汇”的电商小程序。用户可以浏览商品、查看详情、加入购物车、下单支付、以及跳转到合作的客服小程序。这个流程几乎涵盖了 <navigator> 的所有核心功能。

准备工作:项目结构与 pages.json

请在你的 uni-app 项目中,确保有如下的目录结构,并将 pages.json 文件配置如下。这为我们所有的导航场景提供了基础。

目录结构 (部分):

├── pages
│   ├── index
│   │   └── index.vue
│   ├── product
│   │   ├── list.vue
│   │   └── detail.vue
│   ├── order
│   │   ├── list.vue
│   │   └── detail.vue
│   ├── payment
│   │   └── success.vue
│   └── tabBar
│       ├── cart
│       │   └── cart.vue
│       └── my
│           └── my.vue
├── static
│   └── ...
└── pages.json

pages.json 配置:

{"pages": [{"path": "pages/index/index","style": { "navigationBarTitleText": "优品汇首页" }},{"path": "pages/product/list","style": { "navigationBarTitleText": "商品列表" }},{"path": "pages/product/detail","style": { "navigationBarTitleText": "商品详情" }},{"path": "pages/order/list","style": { "navigationBarTitleText": "我的订单" }},{"path": "pages/order/detail","style": { "navigationBarTitleText": "订单详情" }},{"path": "pages/payment/success","style": { "navigationBarTitleText": "支付成功" }},{"path": "pages/tabBar/cart/cart","style": { "navigationBarTitleText": "购物车" }},{"path": "pages/tabBar/my/my","style": { "navigationBarTitleText": "我的" }}],"globalStyle": {"navigationBarTextStyle": "black","navigationBarTitleText": "优品汇","navigationBarBackgroundColor": "#F8F8F8","backgroundColor": "#F8F8F8"},"tabBar": {"list": [{"pagePath": "pages/index/index","text": "首页"},{"pagePath": "pages/tabBar/cart/cart","text": "购物车"},{"pagePath": "pages/tabBar/my/my","text": "我的"}]}
}

场景一:从首页进入商品列表页(基础跳转与交互定制)

用户故事: 用户点击首页“限时抢购”入口,平滑跳转到商品列表页,并能看到清晰的点击反馈。

在这里插入图片描述

1. 首页 pages/index/index.vue (源页面)
<template><view class="content"><view class="promo-section"><!-- 这是一个典型的页面跳转。我们在这里定制了用户交互的每一个细节。--><navigatorurl="/pages/product/list?activityId=promo123&from=home"open-type="navigate"hover-class="promo-hover":hover-start-time="50":hover-stay-time="200"><view class="promo-card"><text class="promo-title">限时抢购</text><text class="promo-desc">点击查看详情</text></view></navigator></view></view>
</template><script>
export default {data() {return {};}
};
</script><style>
.content {padding: 40rpx;
}
.promo-card {background-color: #e54d42;color: white;padding: 60rpx 40rpx;border-radius: 16rpx;text-align: center;box-shadow: 0 4px 10px rgba(229, 77, 66, 0.4);
}
.promo-title {font-size: 48rpx;font-weight: bold;
}
.promo-desc {font-size: 28rpx;margin-top: 10rpx;opacity: 0.9;
}
/* 自定义点击效果:轻微下沉和变暗 */
.promo-hover {opacity: 0.9;transform: scale(0.98);transition: all 0.2s;
}
</style>
2. 商品列表页 pages/product/list.vue (目标页面)

在这里插入图片描述

<template><view class="container"><view v-if="activityId" class="activity-banner"><text>当前活动ID:{{ activityId }}</text><text>来源页面:{{ fromPage }}</text></view><view class="product-list"><text>这里是商品列表...</text></view></view>
</template><script>
export default {data() {return {activityId: '',fromPage: ''};},// onLoad生命周期函数用于接收页面参数onLoad(options) {console.log('接收到的页面参数:', options);if (options.activityId) {this.activityId = options.activityId;}if (options.from) {this.fromPage = options.from;}}
};
</script><style>
.container {padding: 20rpx;
}
.activity-banner {background-color: #fffbe6;border: 1px solid #ffe58f;padding: 20rpx;border-radius: 8rpx;margin-bottom: 20rpx;display: flex;flex-direction: column;
}
</style>

关键属性解析:

  • url: "/pages/product/list?activityId=promo123"

    • 作用: 定义了导航的目标路径。这里我们使用了相对路径,并附带了一个查询参数 activityId,这样商品列表页(list.vue)就能通过 onLoad 生命周期函数获取到这个参数,从而展示特定活动下的商品。这是页面间通信最常用、最基础的方式。
  • open-type: "navigate"

    • 作用: 这是最标准的跳转方式,它会“保留”当前页面(首页),然后“推入”一个新的页面(商品列表页)到页面栈中。用户可以从商品列表页通过左上角的返回按钮回到首页。这符合用户“进入-返回”的心智模型。
  • hover-class: "promo-hover"

    • 作用: 极大地提升了用户体验。当用户的指尖按下这个区域时,会立即应用 .promo-hover 这个 CSS 类,提供一个即时的视觉反馈(在这里是透明度和缩放效果)。这告诉用户:“系统已经响应了你的操作”。
  • hover-start-time: 50

    • 作用: 定义了从用户按下到 hover-class 生效的延迟时间(50毫秒)。这个值可以防止用户在快速划过屏幕时不小心触发点击效果,让交互更精准。
  • hover-stay-time: 200

    • 作用: 定义了用户手指松开后,点击效果还会“停留”的时间(200毫秒)。这给用户一种流畅、不生硬的感觉,尤其是在性能稍差的设备上,可以确保用户能看到完整的点击动画。
      代码解析与运行指南:
  1. 运行项目,在首页点击“限时抢购”卡片。
  2. 你会观察到卡片有轻微下沉和变暗的动画效果,这是 hover-classhover-start-timehover-stay-time 共同作用的结果。
  3. 页面会跳转到“商品列表”,并且页面顶部的黄色提示框会显示出我们从 url 中传递过来的参数 activityIdfrom。这验证了 onLoad 函数成功接收了参数。
  4. 你可以点击原生导航栏的返回按钮,会返回到首页,这是 open-type="navigate" 的效果。

场景二:从商品列表跳转到 TabBar 购物车页

用户故事: 在商品列表页,用户点击悬浮的购物车图标,直接切换到底部导航的购物车页面。

在这里插入图片描述

1. 商品列表页 pages/product/list.vue (在场景一的基础上增加)
<template><view class="container"><!-- ... (场景一中的代码) ... --><view class="product-list"><text>这里是商品列表...</text><!-- 在这里添加一个跳转到商品详情的链接,为场景五做准备 --><navigatorurl="/pages/product/detail?id=P001"open-type="navigate"class="product-item-link"animation-type="fade-in":animation-duration="400"><button type="default">查看商品P001详情(App有渐变动画)</button></navigator></view><!-- 购物车悬浮按钮 --><navigatorurl="/pages/tabBar/cart/cart"open-type="switchTab"hover-class="none"><view class="fab-cart-btn"><text>🛒</text></view></navigator></view>
</template><script>
// ... (与场景一相同) ...
export default {data() {return {activityId: '',fromPage: ''};},onLoad(options) {console.log('接收到的页面参数:', options);if (options.activityId) {this.activityId = options.activityId;}if (options.from) {this.fromPage = options.from;}}
};
</script><style>
/* ... (场景一的样式) ... */
.container {padding: 20rpx;
}
.activity-banner {background-color: #fffbe6;border: 1px solid #ffe58f;padding: 20rpx;border-radius: 8rpx;margin-bottom: 20rpx;display: flex;flex-direction: column;
}
.product-item-link {margin-top: 40rpx;
}
.fab-cart-btn {position: fixed;bottom: 100rpx;right: 40rpx;width: 100rpx;height: 100rpx;background-color: #007aff;border-radius: 50%;display: flex;justify-content: center;align-items: center;font-size: 50rpx;color: white;box-shadow: 0 4px 12px rgba(0, 122, 255, 0.4);
}
</style>
2. 购物车页 pages/tabBar/cart/cart.vue (目标页面)
<template><view><view class="title">购物车</view><text>这里是您的购物车页面。</text></view>
</template>

代码解析与运行指南:

  1. 从首页进入商品列表页。
  2. 点击右下角的蓝色圆形购物车按钮。
  3. 应用会立即切换到“购物车”Tab,并且底部的 TabBar 会高亮“购物车”项。
  4. 核心观察点: 此时,你无法通过返回手势或返回按钮回到“商品列表页”。这是因为 open-type="switchTab" 清空了所有非 TabBar 的页面栈,确保了导航的扁平化。
  5. hover-class="none" 确保了点击这个图标按钮时,它本身不会有任何多余的视觉变化。

场景三:下单成功后,使用 redirectreLaunch

用户故事: 用户支付成功后,可以选择“查看订单”(不希望再返回支付页)或“返回首页”(开始一次全新的会话)。

在这里插入图片描述

1. 支付成功页 pages/payment/success.vue
<template><view class="container"><view class="icon-success"></view><text class="status-text">支付成功!</text><view class="button-area"><!-- 使用 reLaunch 返回首页。这会清空所有页面栈,只留下首页。--><navigator url="/pages/index/index" open-type="reLaunch"><button class="plain-btn">返回首页</button></navigator><!-- 使用 redirect 跳转到订单页。这会关闭当前页面,用订单列表页替换它。--><navigator url="/pages/order/list" open-type="redirect"><button type="primary">查看订单</button></navigator></view></view>
</template><script>
export default {data() {return {};}
};
</script><style>
.container {display: flex;flex-direction: column;align-items: center;padding-top: 150rpx;
}
.icon-success {font-size: 120rpx;color: #09bb07;border: 5px solid #09bb07;border-radius: 50%;width: 180rpx;height: 180rpx;display: flex;justify-content: center;align-items: center;
}
.status-text {font-size: 40rpx;margin-top: 40rpx;margin-bottom: 80rpx;
}
.button-area {display: flex;width: 100%;justify-content: space-around;
}
.plain-btn {background-color: white;border: 1px solid #ccc;
}
</style>
2. 订单列表页 pages/order/list.vue (目标页面)
<template><view><text>这是您的订单列表。</text></view>
</template>

代码解析与运行指南:

  1. 为了模拟,你可以先手动跳转到支付成功页(例如,在首页加一个临时的 <navigator url="/pages/payment/success">)。
  2. 测试 redirect 点击“查看订单”按钮。页面会跳转到订单列表。此时,点击导航栏返回按钮,你会发现你回到了进入支付成功页之前的那个页面(比如首页),而不是支付成功页。这证明了 redirect 成功地替换了页面栈中的当前页。
  3. 测试 reLaunch 重新进入支付成功页。这次点击“返回首页”按钮。页面会跳转到首页。此时,页面栈被完全清空,你无法返回到任何之前的页面,就像刚打开小程序一样。

场景四:navigateBack, targethover-stop-propagation

在这里插入图片描述

用户故事: 在订单详情页,用户可以返回多级页面、跳转到客服小程序,并与页面内复杂组件进行无干扰的交互。

1. 订单详情页 pages/order/detail.vue

为了模拟此场景,你需要手动按顺序打开页面:首页 -> 我的(Tab) -> [添加一个按钮跳转到订单列表] -> [订单列表页添加按钮跳转到订单详情]。这样才能构造出足够深的页面栈。

<template><view class="container"><text class="title">订单详情</text><!-- 场景4.1: 返回多级页面 --><view class="card"><text>假设我们的页面路径是: 我的 -> 订单列表 -> 订单详情。</text><text>点击下方按钮将直接返回“我的”页面。</text><navigator open-type="navigateBack" :delta="2"><button type="default">返回“我的” (返回2级)</button></navigator></view><!-- 场景4.2: 跳转到外部小程序 --><view class="card"><text>点击下方按钮,将打开合作的客服小程序。</text><!-- 注意: app-id需要真实存在且在manifest.json中配置 --><navigatortarget="miniProgram"open-type="navigate"app-id="wxf8e0cf27a58a75e2" path="pages/index/index"><button type="primary">联系客服(跳转到“小程序示例”)</button></navigator></view><!-- 场景4.3: 阻止事件冒泡 --><view class="card"><text>下方卡片整体可点击,但内部按钮的点击效果不会影响卡片。</text><navigator url="/pages/product/detail?id=P002" class="product-card" hover-class="card-hover"><view class="product-info"><text>可点击的商品卡片</text><text>点击空白处或文字,整个卡片会有点击效果。</text></view><!-- @click.native 确保在navigator内button的点击事件能触发 --><button class="fav-button" :hover-stop-propagation="true" @click.native="onFavorite">收藏</button></navigator></view></view>
</template><script>
export default {methods: {onFavorite() {uni.showToast({title: '收藏成功!',icon: 'none'});// 这里会执行收藏逻辑,但不会触发父级navigator的hover效果}}
}
</script><style>
.container { padding: 20rpx; }
.card { margin-bottom: 30rpx; padding: 20rpx; border: 1px solid #eee; border-radius: 8rpx; }
.title { font-size: 36rpx; font-weight: bold; margin-bottom: 20rpx; }
button { margin-top: 20rpx; }.product-card {display: flex;justify-content: space-between;align-items: center;padding: 20rpx;background-color: #f9f9f9;border-radius: 8rpx;
}
.card-hover {background-color: #e0e0e0;
}
.fav-button {margin: 0; /* 重置按钮的默认margin */background-color: #ffc107;color: white;
}
</style>

代码解析与运行指南:

  1. navigateBack & delta: 确保你有至少3层页面栈(如 我的 -> 订单列表 -> 订单详情)。在订单详情页点击“返回‘我的’”按钮,你会看到应用跳过了订单列表,直接回到了“我的”页面。
  2. target="miniProgram": 点击“联系客服”按钮。如果你的环境支持(如微信开发者工具或真机)且 app-id 有效(这里用的是微信官方的“小程序示例”appid),它会拉起另一个小程序。
  3. hover-stop-propagation:
    • 先点击“可点击的商品卡片”的文字或空白区域,整个卡片背景会变灰(card-hover 效果)。
    • 然后,只点击黄色的“收藏”按钮。你会看到按钮有自己的点击效果,并且弹出了“收藏成功!”的提示,但整个卡片的背景不会变灰。这证明了 hover-stop-propagation 成功阻止了点击态的冒泡。

场景五:为 App 端定制页面过渡动画

用户故事: 在 App 端,从商品列表点击某个商品时,希望商品详情页以“渐显”的方式出现,而不是平台默认的侧滑。

1. 商品列表页 pages/product/list.vue (在场景二的代码中已包含)

我们复用场景二中的代码,重点关注那个跳转到详情页的 <navigator>

<!-- 在 pages/product/list.vue 中 -->
<navigatorurl="/pages/product/detail?id=P001"open-type="navigate"class="product-item-link"<!-- 以下两个属性是本场景核心 -->animation-type="fade-in":animation-duration="400"
><button type="default">查看商品P001详情(App有渐变动画)</button>
</navigator>
2. 商品详情页 pages/product/detail.vue (目标页面)
<template><view><text>商品详情页</text><text v-if="productId">商品ID: {{ productId }}</text></view>
</template><script>export default {data() {return {productId: ''}},onLoad(options) {this.productId = options.id}}
</script>

代码解析与运行指南:

  1. 重要: 此效果仅在 App 端可见。请使用 HBuilderX 将项目运行到手机或模拟器上。在小程序开发者工具或 H5 端,这两个属性会被忽略。
  2. 在 App 中,从首页进入商品列表页。
  3. 点击“查看商品P001详情”按钮。
  4. 你会观察到,商品详情页不是从右侧滑入的,而是以一个持续 400 毫秒的渐显动画出现。返回时,它会以“渐隐”动画消失。
  5. 这证明了 animation-typeanimation-duration 成功地定制了 App 端的原生转场动画,提升了应用的独特性和品质感。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

v-for的用法及案例

目录 一.v-for的用法 1.举例1 2.举例2 二.购物车案例 1.代码 2.存在的问题&#xff1a;复选框错位 3.解决方案&#xff1a; 赋值给key属性一个唯一的值 一.v-for的用法 1.举例1 <template><view><view v-for"(item,index) in 10" :key"…

BigQuery对象引用(ObjectRef)全面指南:一站式整合结构化与非结构化多模态数据分析

引言 企业需要同时管理有组织表格中的结构化数据&#xff0c;以及日益增长的非结构化数据&#xff08;如图片、音频和文档&#xff09;。传统上&#xff0c;联合分析这些多样化数据类型非常复杂&#xff0c;通常需要使用不同的工具。非结构化媒体通常需要导出到专门的服务进行…

【开源品鉴】FRP源码阅读

frp 是一款高性能的反向代理应用&#xff0c;专注于内网穿透&#xff0c;支持多种协议和 P2P 通信功能&#xff0c;目前在 GitHub 上已有 80k 的 star。本文将深入探讨其源码&#xff0c;揭示其背后的实现原理。1. 前言 frp 是一款高性能的反向代理应用&#xff0c;专注于内网…

day048-系统负载高排查流程与前后端分离项目

文章目录 0. 老男孩思想1. 系统负载高排查流程1.1 进程/线程相关命令1.1.1 jps1.1.2 jstack1.1.3 jmap1.1.4 top -Hp pid 1.2 排查流程图 2. 前后端分离项目2.1 项目说明2.2 负载均衡2.3 数据库配置2.3.1 安装数据库服务2.3.2 配置数据库环境 2.4 后端配置2.5 四层负载均衡配置…

Spring Boot 牵手EasyExcel:解锁高效数据处理姿势

引言 在日常的 Java 开发中&#xff0c;处理 Excel 文件是一个极为常见的需求。无论是数据的导入导出&#xff0c;还是报表的生成&#xff0c;Excel 都扮演着重要的角色。例如&#xff0c;在企业的财务管理系统中&#xff0c;需要将每月的财务数据导出为 Excel 报表&#xff0…

【ARM AMBA AXI 入门 21 -- AXI partial 访问和 narrow 访问的区别】

文章目录 Overview一、定义区别二、AXI 信号层面对比三、举例说明示例一:Partial Access示例二:Narrow Access四、硬件/系统处理角度五、AXI 总线接口信号举例对比Partial Write 事务:Narrow Write 事务(32-bit Master on 64-bit Bus):六、总结对比表七,软件判断判断 Pa…

使用Ideal创建一个spring boot的helloWorld项目

说明&#xff1a;本篇将介绍如何使用Ideal2024.2.1去创建一个spring boot的helloWorld项目&#xff0c;本篇将包含创建的详细步骤以及spring boot项目的目录结构说明&#xff0c;创建过程中的选项说明等。详细步骤如下&#xff1a;第一步&#xff1a;点击文件——新建——项目&…

国内Ubuntu访问不了github等外网

各位小伙伴们&#xff0c;大家好呀。 大家是不是经常遇到访问不了外网的情况呀。 在Ubuntu中可以这样做。 访问这个网站网站测速-Ping检测-Trace查询-Dig查询-路由跟踪查询-tools.ipip.net&#xff0c; 对于github.com&#xff0c;在这个网站输入github.com&#xff0c;会返…

PDF转换工具,即开即用

在办公室里&#xff0c;这句话被反复验证。每天面对成堆的Word和Excel文件&#xff0c;将它们转换成PDF格式是常有的事。可之前用过的工具&#xff0c;不是一次只能转一个&#xff0c;就是操作繁琐得让人头疼。记得有次赶项目&#xff0c;需要把二十多个文档转成PDF&#xff0c…

2. 你可以说一下 http 版本的发展过程吗

你可以说一下 http 版本的发展过程吗 总结&#xff1a;0.9&#xff1a;只能发送 get&#xff0c;无状态。1.0&#xff1a;新增 post&#xff0c;请求头&#xff0c;状态码&#xff0c;cookie。1.1&#xff1a;新增 put/delete/options/patch&#xff0c;keep-alive&#xff0c…

04-Linux驱动模块的自动加载

概述 上一节&#xff0c;我们讲述了Linux驱动开发的基本的模块代码编写和手动执行模块加载的操作&#xff0c; 这一节&#xff0c;我们讲述嵌入式设备上使用Sysvint引导方式下如何开机自动加载模块的步骤。感兴趣的同学看下使用systemd引导方式的开启自动加载模块的步骤 操作…

【牛客算法】游游的整数切割

文章目录 一、题目介绍1.1 题目链接1.2 题目描述1.3 输入描述1.4 输出描述1.5 示例二、解题思路2.1 核心算法设计2.2 性能优化关键2.3 算法流程图三、解法实现3.1 解法一:基础遍历法3.1.1 初级版本分析3.2 解法二:奇偶预统计法(推荐)3.2.1 优化版本分析四、总结与拓展4.1 关…

笔记本电脑忽亮忽暗问题

关于笔记本电脑忽亮忽暗的问题这个问题困扰了我大半年&#xff0c;最后忽然找到解决方法了---主要的话有三种可能性1.关闭显示器自动调亮的功能2.关闭节能模式自动调亮功能3.调整显卡的功率&#xff0c;关闭自动调亮功能一开始一直都是尝试的第一种方法&#xff0c;没解决。。。…

Qt的顶部工具栏在多个界面使用

Qt的工具栏在多个界面使用1、前言2、创建一个工具栏类2.1 新建一个工具栏类3、提升工具栏类3.1登录界面添加工具栏3.2 创建工具栏对象4、总结1、前言 今天遇到了个问题&#xff0c;顶部的工具栏&#xff0c;像软键盘&#xff0c;时间显示和退出按钮那些&#xff0c;想在多个界…

C#和SQL Server连接常用通讯方式

C#和SQL Server连接通讯 在 C# 中与 SQL Server 建立数据库连接&#xff0c;主要通过 ADO.NET 技术实现。以下是几种常见的连接方式及相关实践&#xff1a; ADO.NET 全面指南&#xff1a;C# 数据库访问核心技术 ADO.NET 是 .NET Framework 中用于数据访问的核心组件&#xf…

安卓10.0系统修改定制化____实现自动开启 USB 调试​的步骤解析 列举常用的几种修改方法

对于安卓开发者、测试人员,甚至是喜欢折腾手机的数码爱好者来说,USB 调试是一个非常重要的功能。它能让手机与电脑相连,实现应用安装、系统调试、数据传输等操作。但每次连接手机都要手动去设置里开启 USB 调试,实在麻烦。其实,通过修改安卓 10.0 的 ROM,就能让手机自动开…

Redisson详细教程 - 从入门到精通

目录 1. 什么是Redisson 2. 为什么要用Redisson 3. 环境准备和配置 4. 基础使用方法 5. 分布式数据结构 6. 分布式锁详解 7. 分布式服务 8. 实际应用场景 9. 最佳实践 10. 常见问题解答 总结 1. 什么是Redisson 简单理解 想象一下,Redis就像一个超级强大的"内…

动态规划VS记忆化搜索(2)

luoguP1434滑雪 题目描述 Michael 喜欢滑雪。这并不奇怪&#xff0c;因为滑雪的确很刺激。可是为了获得速度&#xff0c;滑的区域必须向下倾斜&#xff0c;而且当你滑到坡底&#xff0c;你不得不再次走上坡或者等待升降机来载你。Michael 想知道在一个区域中最长的滑坡。区域由…

如何将服务守护进程化

进程组 什么是进程组 之前我们提到了进程的概念&#xff0c; 其实每一个进程除了有一个进程 ID(PID)之外 还属于一个进程组。进程组是一个或者多个进程的集合&#xff0c; 一个进程组可以包含多个进程。 每一个进程组也有一个唯一的进程组 ID(PGID)&#xff0c; 并且这个 PGID …

【跟着PMP学习项目管理】项目管理 之 范围管理知识点

目录 一、收集需求 1、知识点汇总 2、输入 3、工具 4、输出 二、定义范围 1、知识点汇总 2、输入 3、工具 4、输出 三、创作工作分解结构 1、知识点汇总 2、输入 3、工具 4、输出 四、核实范围 1、知识点汇总 2、输入 3、工具 4、输出 五、控制范围 1、知…