Vue3 如何实现一个全局搜索框

18 篇文章 7 订阅
订阅专栏

前言:自从学习 vue 以来,就对 vue 官网全局的 command + K 调出全局关键词搜索这个功能心心念念。恰好最近项目也是需要实现一个全局搜索的功能,也正好可以正大光明的带薪学习这个功能的思路。网上的教程水平参差不齐,而恰好之前的项目中我有做过一个类似于全局弹出面包屑的功能,于是举一反三写出了一个我们项目需要的全局搜索框,特来分享一下自己的思路。

注意:本文不会马上教你如何编写代码,而是作为一个引路人,一步一步引导你全理解思路。会以 “假如我是一个初学者,如果我在学习这个知识的时候,别人能这样告诉我,那么我也可以很快的去理解” 的角度去讲解 ,授人以鱼不如授人以渔。希望你在阅读本文的时候可以拓展思路,举一反三。

一. 文件准备

前期你需要准备三个文件,来完成这个全局搜索框

  1. SearchBar.ts 文件
  2. SearchBar.vue 文件
  3. useSearch.ts 文件

二. 搜索框的样式

样式问题不是本文的重点,你可以花费五分钟在 SearchBar.vue 文件内速写一个非常简易的正方形 div 包裹着一个 input 标签即可快速进行下面的学习。

但是首先我们需要理清思路,这个组件是会出现在我们页面的最顶部的,所以它组件内部需要用到绝对布局。我们去 SearchBar.vue 去设置一个样式给最外层的 div,这里其它样式的写法使用的是 Uno CSS,没用过的小伙伴也不需要担心,它只是单纯的样式,和本文中心内容不牵扯。(CSS写成计算属性在这个场景也毫无特殊意义,只是单纯设计时考虑多了)

三. 渲染函数 h 和 render 函数(重点)

  1. 打开之前准备的 SearchBar.ts 文件,从 vue 里引入这两个函数,并且把在上一步写好的简陋版搜索框(SearchBar.vue)引入到这个文件内。
  2. 看过我之前文章 Vue3实现一个 Toast 的读者可能会比较熟悉一点点,但是在那一篇文章内由于我也是初次接触这两个函数,所以当时总结的也不是特别精确,所以重新捋清思路,这里再讲解一下。
  3. 首先我们从官网的介绍,先看一下这个函数的定义。


可以看出,这个函数第一个参数是必填的,可以是一个 string 和 Component,这篇文章重点讨论参数为 Component 的情况。重点是这个函数的返回值,是一个 VNode,这个你一定不陌生,Virtual Node ,看本篇文章的读者可能对虚拟 dom 的原理可能不是那么清楚,但是我相信你们一定知道它的基本机制。Vue 其实是先渲染 虚拟 dom -->然后 转换成真实 dom

4.先别急着写代码,我想你可能更清楚这样的写法,比如我们前面在 SearchBar.vue 文件内写的简单的弹出框。

整个组件的样式都是在 Vue 提供的 <template> 组件内写的,但是你要知道,Vue 在底层还是通过调用 h() 来完成虚拟 dom 的构建。而 <template> 仅仅只是 Vue 为了让你用熟悉的原生 html 开发而为你提供的语法糖 而已。(嗯,你可以这样理解)

5.那么我们可以根据上面 h() 函数的介绍,它接收的第一参数可以是 Component ,那我们这个 SearchBar.vue 不就是组件吗?那如果我不想使用 <template> 去展示这个组件的话,我是否可以这样写呢?h(SearchBar.vue)。没错,是的,你就是可以这样写。别忘了 h 的返回值就是我们想拿到的 Vnode ,所以按照正确的写法是这样的。

三. 编写 SearchBarMaker 构造函数和 present 方法

  1. 让我们回到 SearchBar.ts 文件。

2. 首先思考,这个搜索框一定有一个出现的函数,和一个消失的函数 ,ok,起名字,一个 present,一个 dismiss 。

3. 接下来我需要创建出一个 VNode ,然后想办法处理成真实 dom。经过上面的学习,第一步马上就可以想到下面的写法。

4. 下面这位更是重量级,render() 函数。虚拟 dom 有了,真实dom 该如何拿到呢? Vue 为我们提供了这样一个函数,这里我们需要重点去看这个函数的类型是值,是一个 RootRenderFuncion 类型的。

5. 这里我们转变一下思路,我们看一下 render 函数的第二个参数是 一个 container:HostElement ,然后让我们打开我们 main.ts 文件,我们跳进 mount的定义部分,

发现神奇的地方了吗,我们虽然不知道 HostElement 的类型是什么,但是你知道你 mount 函数内填的参数是什么了吗?(忘掉的转头自觉复习官网哈。)
没错,就是全局唯一的一个真实 dom,一个朴素无法的,id叫 app 的 div 元素。

由于篇幅限制,在这里你可以先暂时简单的理解,render 函数会将你的虚拟 dom 包装成一个真实 dom 元素,但是你需要给它一个真实的 外壳dom 来告诉它将虚拟 dom 渲染到哪个位置。

6. ok,拿到一个包装后的虚拟 dom ,接下来就是告诉浏览器在哪里渲染这个元素。这里我们需要思考 ,既然是全局都可以弹出的,并且需要在所有组件之上弹出。

那么最简单的方法就是让它出现在 body的第一个元素,那么它一定会和我们网页所有的组件同级别(tips:通常我们所有的页面构成都会写在 body内 的一个 div 内。什么?你问我为什么?请打开你的 index.html 看一下,你是否忘记了我们的 App.vue 是挂在这个真实的,id为 app 的元素内的)

那其实我们的操作的思路就是非常简单的,当我按下全局搜索按钮,那么你就在 <div id="app"> 的元素之前插入我的组件即可。

7. ok,到这里我们已经可以看到基本效果了,我们来测试一下。让我们在 App.vue 组件内随便写一个按钮,然后调用 SearchBarCreator 实例身上的 present 方法。(maker 感觉不是那么合理,之后我们将 SearchBarMaker 变更为 SeachBarCreator 的叫法,仅仅是名字变了而已,逻辑什么的根本没变哦。 )

效果如下:

8. 到这里 searchBar 已经可以呈现在页面上了,但是我们还不知道怎样让它消失,其实也非常简单,我们只需要在合适的时机移除这个 dom 元素即可。

在这里我们需要知道一点,我们需要将 searchBar 提升到当前文件的全局,不能仅只在 open 中去 new 了。

ok,我们测试一下

四. 优化 SearchBarCreator 构造函数的代码逻辑

写到这里的时候,你可能发现了一个小问题,当我一直去按搜索按钮的时候,它会出现多个搜索框,但是我们希望的是它在全局只能出现一个搜索框。换个角度思考,也就是同一时间,这个被我们 new 出来的 SeachBar 实例只能出现一个。思考一下 ,我加一个变量,isShowing 是否正在被展示 ,如果正在被展示的话,那么用户再次调用 present 的时候,我就去调用实例自身的 dismiss 方法让它消失,是否可行呢?

测试一下:

OK,看来完美解决当前的问题了。

五. 编写全局唯一的调用实例

  1. 在上面的这种情况下,我们已经可以在 App.vue 文件内去 new 一个实例来调用这个搜索框了。但是我们加入现在需要在 XXX.vue 文件内调用这个搜索框呢?我难道还需要重新去引入,然后重新 new 吗?nonono,某位大佬说过,程序员都是很懒的,不可能写这种低级的重复代码的。那么该如何实现呢
  2. 打开我们之前准备的 useSearch.ts 文件,我们把之前在 App.vue 的全局生成的这个 SearchBar 实例转换思路,使它在全局的一个 ts 文件内生成一个,然后把这个实例自身的一些方法封装成函数,暴露给外部。那么我就可以在全局任意一个地方去调用这个实例身上的这两个方法。

3. 让我们在 App.vue 去试一下。
这是我们之前的 App.vue 文件的调用方法。

我们改造一下它。

我们再次测试一下功能有没有什么问题


如此一来就方便很多了,我们可以在任意位置去调用这个“唯一的搜索框”

六. 添加全局的快捷键 Command + K

  1. 再此之前,我们需要理解一个概念,注意我们的 main.ts 文件,我们是把谁挂在了全局的那一个 id='app' 的真实 dom 下的?


没错,就是前面我们提到的 App.vue 组件。

2.那么假如我在这个 App.vue 组件挂载的时候,给全局 window 对象身上添加一个键盘事件,是不是就可以了呢?怎么添加呢?其实非常非常简单,要用到见组合按键,我们就需要使用到 “keydown”,具体为什么不是 “keypress” ,读者可以自行查阅这两者的区别,不属于本文的主要探讨内容。

3. 这时候,我们先来按一下 command 看看打印的内容是什么。这里重点的内容是该键盘事件身上的metaKey 属性。

在这里我们还可以推算出按下 “ctrl” 的事件为

4. keydown 事件支持多个按键同时按下。当我们同时按下 “command” 和 “K” 键,会发生什么呢?

但是我们发现好像并没有 K:true 这个属性呀,那我们怎么去判断呢?别着急接着往下看。

5. 我们可以看到键盘事件 event 身上有个 key 属性,它的值恰好是字符串类型的 “k”

这里我直接公布写法,js 允许我们这样判断是否同时按下两个按键。

6. 我们测试一下,我们去吧 App.vue 文件内的这两个按钮给去掉

然后再打印一下我们按下 command 和 k 的时候。

测试一下:

七. 添加出现的动画

  1. 在上面我们可以看到,这样突然的出现好像有一丝丝的突兀。我希望这个搜索框在出现的时候,可以有那么一丝丝的平移效果,(类似于下面的效果)该如何做呢?

2. 我这里介绍一种较为简单的思路,我们在 App.vue 文件的 style 内预设一个 Css 动画,并起好名字。叫做 "searchInput"

3. 然后回到我们 searBar.vue 的组件去,给我们这个组件最外层的起一个好听的名字,我这里就叫做 searchBarWrapper

4. 然后回到我们的 SearchBar.ts 文件内,也就是放我们 SeachBarCreator 构造函数的那个文件内。(tips:不是 useSearch.ts 哦) 我这里解释一下思路,在调用 render 函数后,这个组件其实已经渲染成为一个真实的 dom 元素,只不过我们还没给它指定渲染的位置。既然是真实的 dom ,那么我们就可以通过 document.getElementById这个方法(querySelector同理,一个意思)拿到这个SearchBar.vue组件 ,接下来我只需要在调用 document.body.insertBefore 方法前,给它添加上刚刚我们在 App.vue 里预设好的类名,searchInput ,就完美达成我们想要的效果了。

5. 注意:style ,这个点仅仅是类名选择器,不要忘记了基础知识。

6. 测试一下效果:

八. 自动聚焦

在弹出框的 input 框实现自动聚焦相比于之前讲的就非常简单了,我在这里一笔带过了。只需要在 nextTick 中调用 input 本身的 focus 方法即可。

总结:

之所以不喜欢使用真代码去写文章而大量使用截图的原因是:我自己在搜索到自己想要的文章后,也会喜欢直接看有没有最后的成品代码,然后直接复制就拿过去用了,而往往忽略了自己动手去实现一遍才是真正理解了的过程。

所以我写代码的时候,尽量不写特别复杂的逻辑,而写一些很简单的几行代码去实现某一个功能。是因为我希望你们真正带入自己的思考,和一步步体会这个实现过程,从而举一反三。

如果你认真看了该文章,你也许会明白现在很多组件库的底层实现原理其实就是这样的,比如全局弹出的dialog ,modal 框等等。我们要去理解组件库组件实现的思路,而不是一味的复制粘贴。

这个搜索框有很多可以更加优化的地方,你们可以带入自己的思考去想一想。比如

1.如何保存搜索历史?
2.如何实现实时的给出搜索联想

与君共勉才是我的初衷...

vue实现搜索框记录搜索历史_用Vue.js实现一个简单的搜索框
weixin_39774682的博客
12-20 415
主要用到的知识很简单,简单的vuejs2.0的知识就够了。源码用了.vue构建和ES6,用了webpack打包等等。我资历还浅,先用一个简单的.js的写。先看效果这里有两个组件,一个组件是logo部分的,一个搜索框部分的。html很简单,就是引用两个组件。先来分析,首先一个显示搜索引擎的图片,这里要响应式的,下面选择了不同的搜索引擎图标就要跟着换。所以。后面的倒三角点击时显示下拉列表 。然后是...
vue项目实现一个ctrl+f的搜索功能
01-19
这次在项目中遇到了一个要做一个搜索功能,因为项目是vue的,而且是在手机端,所以对这个搜索功能实现和能做到什么样子都没有底,在网上研究了一会,发现大家的解决方法都各有特色,有引入第三方包的,有遍历的,...
如何在Vue3中实现一个带有自动补全功能搜索框
有我更精彩的博客
06-19 912
前端开发中的自动补全搜索框不仅能够提升用户体验,还能显著提高用户输入效率。在现代Web开发中,Vue.js作为一个非常流行的前端框架,提供了实现这些功能的优秀工具和方法。本文将向您展示如何在Vue3中实现一个带有自动补全功能搜索框
基于Vue.js实现简单搜索框
10-21
主要为大家详细介绍了基于Vue.js实现简单搜索框,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
Vue3纯前端实现搜索功能(名字、手机号)并标红索引
最新发布
weixin_46751076的博客
09-11 336
Vue3纯前端实现搜索功能(名字、手机号)并标红索引
vue实战之搜索框功能实现
weixin_72671719的博客
04-05 2153
【代码】vue实战之搜索框功能实现
Vue 项目如何实现一个全局菜单搜索框
山山而川~
02-06 6389
本篇文章分享一下我在实际开发 Vue 项目时遇到的需要 —— 全局菜单搜索。全局菜单搜索本质是 router 的使用,该功能已经实现,接下来分享一下开发心得。
vue elementui 实现搜索栏公共组件封装的实例代码
10-15
本文将详细介绍如何使用Vue框架结合Element UI库来封装一个搜索栏公共组件。在许多后台管理系统中,搜索栏是一个必不可少的功能,它通常出现在表格页面的顶部,用户可以通过搜索栏输入筛选条件以快速定位数据。为了...
vue2 前端搜索实现示例
08-27
Vue2 前端搜索实现示例 本篇文章主要介绍了 Vue2 前端搜索实现示例,通过对搜索功能实现,展示了 Vue2 的强大功能。下面是对该示例的详细分析和知识点总结。 搜索实现原理 搜索实现的原理非常简单,即通过在...
vue3 搜索框组件封装与功能实现
はんみん的博客
11-11 1464
vue3+ts 搜索框组件封装与功能实现
vue实现搜索功能
12-29
本文实例为大家分享了vue实现搜索功能的具体代码,供大家参考,具体内容如下 methods (要有一定的触发条件才能执行,如点击事件) <input type=text name= id= placeholder=搜索 v-model=search/> <button @click=btn>搜索</button> {{list.name}} {{list.date}}<
vue3实现搜索功能
lw934934的博客
06-27 4525
vue3通过双向数据绑定、filter过滤实现搜索功能
Vue3搜索框(InputSearch)
Mr Dear的博客
08-26 851
带搜索按钮的输入框,支持:自定义搜索按钮;三种大小;带清除图标;带字数提示;前置标签;自定义前缀和后缀;搜索中;禁用;总之,功能丰富,简单易用😁😁
vue3搜索功能
A12536365214的博客
07-29 3146
Vue 3中实现搜索功能可以通过以下步骤进行。假设你已经有一个包含数据列表的组件,并且你想要在该列表中实现搜索功能
vue3 仿Ctrl+F实现页面全局搜索
weixin_43678876的博客
08-27 574
2.通过搜索内容进行比对,给搜索内容外部重新生成一个标签。3.给元素重新赋值html。1.获取元素的html。
Vue-搜索框实现
热爱编程 热爱生活
10-22 9696
一.方法分析 1.字符串匹配 2.v-for循环实时更新元素 3.@click=""实现点击后页面的跳转同时设置不同id来根据内容的不同来跳转到不同页面 二.代码分析: html代码: 1.设置v-model绑定元素内容 2.goPage(data.id) 写一个函数来根据id不同跳转界面 <div class="container" id="div1"> <div class="search bar1"> <form> ..
vue3实现列表搜索功能
合格程序猿
07-01 1616
3列表data的value等于datax的value。/**搜索数据 */
vue3搜索框功能实现
09-04
实现Vue3的搜索框功能,你需要准备三个文件:SearchBar.ts文件,SearchBar.vue文件和useSearch.ts文件。 首先,在SearchBarMaker构造函数和present方法中编写代码。在SearchBar.ts文件中,你可以定义构造函数和实现present方法,用于处理搜索框的逻辑。 接下来,在SearchBar.ts文件中,你需要引入渲染函数h和render函数,并将之前准备好的简陋版搜索框(SearchBar.vue)引入到这个文件中。渲染函数h用于创建Vue组件的虚拟节点,而render函数用于将虚拟节点渲染为实际的DOM元素。这两个函数在Vue3的官方文档中有详细的介绍。 通过这些步骤,你就可以实现Vue3的搜索框功能了。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [Vue3 如何实现一个全局搜索框](https://blog.csdn.net/fang_my/article/details/128059264)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]
写文章

热门文章

  • 关于Vue3的defineProps用法 27747
  • JS中什么是回调函数? 17854
  • JS中function(e) 其中的e到底代表什么 11751
  • 使用 Vue3 开发了四个月,回顾 emit 的用法 9997
  • 前端必备技能之----节流 9034

分类专栏

  • vue 18篇
  • React后台管理系统全记录 7篇
  • react 4篇

最新评论

  • Vue3 如何实现一个带遮罩的 dialog 对话框

    桃子味的汽水: 写的真好 关注了

  • Vue3 如何实现一个全局搜索框

    NGU7180: template是一个语法糖这个说法太棒了,很有启发,谢谢

  • 为了搞清楚 DNS,我花了 1.99 买了一个域名

    普通网友: 大佬的文章写的太精辟了 让我深刻了解了这篇文章的精髓 谢谢大佬分享,希望继续创作优质博文。【我也写了一些相关领域的文章,希望能够得到博主的指导,共同进步!】

  • Vue3 如何实现一个带遮罩的 dialog 对话框

    weixin_47471217: 写的真的好 兄弟 加油

  • TS 函数重载你还不会?来!我教你

    qq_39878412: 好清晰!

大家在看

  • 鸿蒙沉侵式导航状态栏 1011
  • 文心一言 VS 讯飞星火 VS chatgpt (371)-- 算法导论24.4 3题
  • 【趣学C语言和数据结构100例】
  • Clickhouse 23.8.9.54 部署安装 621
  • 线程安全、synchronized和volatile关键字

最新文章

  • 淘宝、京东复制好友链接弹出商品详情是如何实现的
  • HTTP 和 TCP 我知道,但是套接字是什么鬼?
  • 为了搞清楚 DNS,我花了 1.99 买了一个域名
2024年6篇
2023年18篇
2022年82篇

目录

目录

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值

深圳坪山网站建设公司徐州贾汪网站优化价格石家庄网站优化推广有哪些杭州网站的优化南沙网站关键字优化网站排名优化赞易点网络深圳网站优化工具淘宝客网站优化山东商祺网站建设优化网站基础SEO优化教学乐山专业网站优化汤阴县网站优化哪家收费低潍坊兆通网站优化平山网站优化费用携程网站优化宜春广东网站优化南通网站的优化山东哪里有网站优化平台贵州网站优化注意事项河南家装行业网站优化推广方案网站优化中网站排名是什么怎么给别人做网站优化徐水区网站seo优化排名宁波企业如何优化网站免费的网站优化方式有哪些seo网站优化排名推广网站排名优化夌去宙3思温馨网站关键词排名优化工具茂名网站优化托管做网站优化的注意事项合肥长丰网站优化香港通过《维护国家安全条例》两大学生合买彩票中奖一人不认账让美丽中国“从细节出发”19岁小伙救下5人后溺亡 多方发声卫健委通报少年有偿捐血浆16次猝死汪小菲曝离婚始末何赛飞追着代拍打雅江山火三名扑火人员牺牲系谣言男子被猫抓伤后确诊“猫抓病”周杰伦一审败诉网易中国拥有亿元资产的家庭达13.3万户315晚会后胖东来又人满为患了高校汽车撞人致3死16伤 司机系学生张家界的山上“长”满了韩国人?张立群任西安交通大学校长手机成瘾是影响睡眠质量重要因素网友洛杉矶偶遇贾玲“重生之我在北大当嫡校长”单亲妈妈陷入热恋 14岁儿子报警倪萍分享减重40斤方法杨倩无缘巴黎奥运考生莫言也上北大硕士复试名单了许家印被限制高消费奥巴马现身唐宁街 黑色着装引猜测专访95后高颜值猪保姆男孩8年未见母亲被告知被遗忘七年后宇文玥被薅头发捞上岸郑州一火锅店爆改成麻辣烫店西双版纳热带植物园回应蜉蝣大爆发沉迷短剧的人就像掉进了杀猪盘当地回应沈阳致3死车祸车主疑毒驾开除党籍5年后 原水城县长再被查凯特王妃现身!外出购物视频曝光初中生遭15人围殴自卫刺伤3人判无罪事业单位女子向同事水杯投不明物质男子被流浪猫绊倒 投喂者赔24万外国人感慨凌晨的中国很安全路边卖淀粉肠阿姨主动出示声明书胖东来员工每周单休无小长假王树国卸任西安交大校长 师生送别小米汽车超级工厂正式揭幕黑马情侣提车了妈妈回应孩子在校撞护栏坠楼校方回应护栏损坏小学生课间坠楼房客欠租失踪 房东直发愁专家建议不必谈骨泥色变老人退休金被冒领16年 金额超20万西藏招商引资投资者子女可当地高考特朗普无法缴纳4.54亿美元罚金浙江一高校内汽车冲撞行人 多人受伤

深圳坪山网站建设公司 XML地图 TXT地图 虚拟主机 SEO 网站制作 网站优化