核心是区分原生titleNView搜索框(仅App/H5有效)与手写自定义导航栏(全平台兼容);选错路径则小程序无法显示搜索框。

uni-app 自定义导航栏实现搜索跳转,核心不是「写一个搜索框组件」,而是分清两个路径:原生 titleNView 搜索框(仅 App/H5 有效)和手写自定义导航栏(全平台兼容)。选错路径,小程序里就根本看不到搜索框。
用 titleNView.searchInput 实现原生搜索跳转(App/H5 专用)
这是最轻量的方案,但只在 App 和 H5 生效,微信/支付宝等小程序完全不识别 searchInput 配置。一旦你项目要上小程序,这条路直接走不通。
-
pages.json中对应页面配置必须包含app-plus.titleNView.searchInput,且不能设"navigationStyle": "custom"(否则原生导航栏被干掉,searchInput就没了) - 监听事件只能用
onNavigationBarSearchInputClicked,不是input或change—— 它只在用户点击搜索框时触发,不传输入内容,只负责跳转 - 跳转时若需带参数(比如搜索类型),得靠 URL query 传递:
uni.navigateTo({ url: '../search/search?type=post' }) - 搜索框 placeholder、圆角、背景色等样式都通过
searchInput对象配置,不支持 slot 或自定义 icon
手写自定义导航栏 + 搜索跳转(全平台兼容)
当你要同时支持小程序时,必须关掉原生导航栏,自己用 <view></view> 写一个顶部区域。这时搜索跳转逻辑完全由你控制,但要注意状态栏适配和点击穿透问题。
- 先在
pages.json页面级 style 中设"navigationStyle": "custom",否则手写导航栏会和原生重叠 - 在页面
<template></template>顶部加一层<view class="custom-navbar"></view>,里面放<input>或可点击的搜索容器(如<view></view>) - 点击后调用
uni.navigateTo跳转,URL 可拼接关键词(如果用了 input,需绑定v-model并在跳转前读取值) - 务必用
uni.getSystemInfo动态计算状态栏高度,否则安卓/IOS/小程序顶部位置错乱;customBar高度 ≠ 固定值 44px 或 90px
onNavigationBarSearchInputClicked 不触发?检查这三点
这个生命周期钩子非常脆弱,常见失效原因不是代码写错,而是配置或平台限制没看清。
- 当前页面未在
pages.json中配置app-plus.titleNView.searchInput,哪怕只写{}也得有这个字段 - 误把
navigationStyle设为"custom"—— 一设就废,原生导航栏没了,自然也没searchInput可点 - 在微信小程序调试器里测试,它压根不解析
searchInput,也不会报错,只会静默忽略整个titleNView配置
搜索页接收参数并触发检索的典型写法
跳转过去只是第一步,搜索页得知道“该搜什么”“按哪种类型搜”。别依赖全局变量或缓存,用 URL query 最稳妥。
- 跳转时传参:
uni.navigateTo({ url: '../search/search?q=uniapp&type=doc' }) - 在
search.vue的onLoad中取参:onLoad(query) { this.keyword = query.q || ''; this.type = query.type || 'all'; } - 不要在
mounted里发起请求 ——onLoad才是 uni-app 页面首次加载时获取 query 的唯一可靠时机 - 如果需要历史记录,
uni.setStorageSync('searchHistory', [...old, keyword]),记得去重和长度限制(避免爆 localStorage)
真正麻烦的从来不是怎么跳,而是跳完之后怎么让搜索页知道自己该搜什么、在哪搜、用什么 UI 渲染。原生 searchInput 给不了输入内容,手写导航栏又得自己管兼容性——选哪条路,取决于你第一个要上的平台是什么。











