前言:自从学习 vue 以来,就对 vue 官网全局的 command + K 调出全局关键词搜索这个功能心心念念。恰好最近项目也是需要实现一个全局搜索的功能,也正好可以正大光明的带薪学习这个功能的思路。网上的教程水平参差不齐,而恰好之前的项目中我有做过一个类似于全局弹出面包屑的功能,于是举一反三写出了一个我们项目需要的全局搜索框,特来分享一下自己的思路。
注意:本文不会马上教你如何编写代码,而是作为一个引路人,一步一步引导你去理解这个组件的设计思路。会以 “假如我是一个初学者,如果我在学习这个知识的时候,别人能这样告诉我,那么我也可以很快的去理解” 的角度去讲解 ,授人以鱼不如授人以渔。希望你在阅读本文的时候可以拓展思路,举一反三。
前期你需要准备三个文件,来完成这个全局搜索框
image.png
样式问题不是本文的重点,你可以花费五分钟在 SearchBar.vue 文件内速写一个非常简易的正方形 div 包裹着一个 input 标签即可快速进行下面的学习。
但是首先我们需要理清思路,这个组件是会出现在我们页面的最顶部的,所以它组件内部需要用到绝对布局。我们去 SearchBar.vue
去设置一个样式给最外层的 div
,这里其它样式的写法使用的是 Uno CSS
,没用过的小伙伴也不需要担心,它只是单纯的样式,和本文中心内容不牵扯。(CSS写成计算属性在这个场景也毫无特殊意义,只是单纯设计时考虑多了)
可以看出,这个函数第一个参数是必填的,可以是一个 string
和 Component
,这篇文章重点讨论参数为 Component
的情况。重点是这个函数的返回值,是一个 VNode
,这个你一定不陌生,Virtual Node ,看本篇文章的读者可能对虚拟 dom 的原理可能不是那么清楚,但是我相信你们一定知道它的基本机制。Vue 其实是先渲染 虚拟 dom -->然后 转换成真实 dom。
4 . 先别急着写代码,我想你可能更清楚这样的写法,比如我们前面在 SearchBar.vue 文件内写的简单的弹出框。
整个组件的样式都是在 Vue 提供的 组件内写的,但是你要知道,Vue 在底层还是通过调用 h() 来完成虚拟 dom 的构建。而 仅仅只是 Vue 为了让你用熟悉的原生 html 开发而为你提供的语法糖而已。(嗯,你可以这样理解)
5 . 那么我们可以根据上面 h() 函数的介绍,它接收的第一参数可以是 Component
,那我们这个 SearchBar.vue
不就是组件吗?那如果我不想使用 去展示这个组件的话,我是否可以这样写呢?h(SearchBar.vue)
。没错,是的,你就是可以这样写。别忘了 h
的返回值就是我们想拿到的 Vnode ,所以按照正确的写法是这样的。
SearchBar.ts
文件。render()
函数。虚拟 dom 有了,真实dom 该如何拿到呢?Vue 为我们提供了这样一个函数,这里我们需要重点去看这个函数的类型是值,是一个 RootRenderFunction
类型的。mount
的定义部分, mount
函数内填的参数是什么了吗?(忘掉的转头自觉复习官网哈。)
没错,就是全局唯一的一个真实 dom,一个朴实无华的id叫 app
的 div 元素。<div id="app">
的元素之前插入我的组件即可。App.vue
组件内随便写一个按钮,然后调用 SearchBarCreator
实例身上的 present
方法。(maker 感觉不是那么合理,之后我们将 SearchBarMaker
变更为 SeachBarCreator
的叫法,仅仅是名字变了而已,逻辑什么的根本没变哦。) searchBar
提升到当前文件的全局,不能仅只在 open
中去 new
了。
写到这里的时候,你可能发现了一个小问题,当我一直去按搜索按钮的时候,它会出现多个搜索框,但是我们希望的是它在全局只能出现一个搜索框。换个角度思考,也就是同一时间,这个被我们 new
出来的 SeachBar
实例只能出现一个。思考一下,我加一个变量,isShowing 是否正在被展示
,如果正在被展示的话,那么用户再次调用 present
的时候,我就去调用实例自身的 dismiss
方法让它消失,是否可行呢?
测试一下:
OK,看来完美解决当前的问题了。
App.vue
文件内去 new
一个实例来调用这个搜索框了。但是我们加入现在需要在 XXX.vue
文件内调用这个搜索框呢?我难道还需要重新去引入,然后重新 new
吗?nonono,某位大佬说过,程序员都是很懒的,不可能写这种低级的重复代码的。那么该如何实现呢App.vue
的全局生成的这个 SearchBar 实例转换思路,使它在全局的一个 ts 文件内生成一个,然后把这个实例自身的一些方法封装成函数,暴露给外部。那么我就可以在全局任意一个地方去调用这个实例身上的这两个方法。App.vue
去试一下。
这是我们之前的 App.vue
文件的调用方法。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 允许我们这样判断是否同时按下两个按键。
command
和 k
的时候。App.vue
文件的 style 内预设一个 Css 动画,并起好名字。叫做 "searchInput" searBar.vue
的组件去,给我们这个组件最外层的起一个好听的名字,我这里就叫做 searchBarWrapper
。SearchBar.ts
文件内,也就是放我们 SeachBarCreator 构造函数的那个文件内。(tips:不是 useSearch.ts 哦) 我这里解释一下思路,在调用 render 函数后,这个组件其实已经渲染成为一个真实的 dom 元素,只不过我们还没给它指定渲染的位置。既然是真实的 dom ,那么我们就可以通过 document.getElementById这个方法(querySelector同理,一个意思)
拿到这个SearchBar.vue组件
,接下来我只需要在调用 document.body.insertBefore
方法前,给它添加上刚刚我们在 App.vue
里预设好的类名,searchInput
,就完美达成我们想要的效果了。在弹出框的 input 框实现自动聚焦相比于之前讲的就非常简单了,我在这里一笔带过了。只需要在 nextTick 中调用 input 本身的 focus 方法即可。
之所以不喜欢使用真代码去写文章而大量使用截图的原因是:我自己在搜索到自己想要的文章后,也会喜欢直接看有没有最后的成品代码,然后直接复制就拿过去用了,而往往忽略了自己动手去实现一遍才是真正理解了的过程。
所以我写代码的时候,尽量不写特别复杂的逻辑,而写一些很简单的几行代码去实现某一个功能。是因为我希望你们真正带入自己的思考,和一步步体会这个实现过程,从而举一反三。
如果你认真看了该文章,你也许会明白现在很多组件库的底层实现原理其实就是这样的,比如全局弹出的dialog ,modal 框等等。我们要去理解组件库组件实现的思路,而不是一味的复制粘贴。
这个搜索框有很多可以更加优化的地方,你们可以带入自己的思考去想一想。比如
1.如何保存搜索历史? 2.如何实现实时的给出搜索联想
与君共勉才是我的初衷...
6月5日,一张券商降薪截图在社交媒体疯传。截图提到,当日上午,某中字头头部券商召开大会,除了MD外全员降薪,且降薪不只是降奖金,而是直接降底薪。按照职级不同,SA1降6K,SA3降8K,VP降8K—10K。据了解,降薪大概率整体属实,但具体幅度有所差异,且不同区域、不同业务条线目前掌握的降薪情况也不尽相同。
今日,蔚来 CEO 李斌在 2023 高通汽车技术与合作峰会上爆料,蔚来第二代技术平台的全系车型已标配第三代骁龙座舱平台。
Meta公司周一(5月22日)推出了一个开源AI语言模型——大规模多语言语音(Massively Multilingual Speech, MMS)模型,可以识别和产生1000多种语言的语音——比目前可用的模型增加了10倍。研究人员表示,他们的模型可以转换1000多种语言,但能识别4000多种语言。
歌手孙燕姿在更新动态中回应了近日引发争议的“顶流AI歌手孙燕姿”,笑称粉丝已经接受她是“冷门”歌手,而AI成为了目前的顶流。
5月31日晚,荣耀方面对澎湃新闻记者表示,上海荣耀智能科技开发有限公司是荣耀位于上海的研究所,是荣耀在中国的5个研究中心之一,重点方向在终端侧核心软件、图形算法、通信、拍照等方面研究开发工作。荣耀强调,坚持以用户为中心,开放创新,与全球合作伙伴一起为用户提供最佳产品解决方案。
据北京市市场监督管理局公示信息,5月24日,苹果电子产品商贸(北京)有限公司因发布虚假广告被北京市东城区市场监督管理局处以20万元的行政处罚。
据外媒5月24日消息,全球最大的个人电脑制造商联想表示,在2023年1-3月期间,该公司裁员了约5%,这是由于PC市场不景气导致的。
日前,有网络博主号称拍摄到了小米首款汽车MS11的高清视频。从视频中可以看出,新车依旧包裹大面积的伪装,据该博主称,他之所以确定这是小米汽车,是因为靠近观察之后,发现它的三角形大灯轮廓和其最初手绘的小米汽车假想图几乎一模一样。
超过 350 名从事人工智能工作的高管、研究人员和工程师签署了这份由非盈利组织人工智能安全中心发布的公开信,认为人工智能具备可能导致人类灭绝的风险,应当将其视为与流行病和核战争同等的社会风险。
日前,以押注“颠覆性创新”著称的ARK Invest创始人Cathie Wood在接受媒体采访时表示,软件提供商将是人工智能狂潮的下一个受益板块。英伟达每卖出1美元的硬件,软件供应商SaaS供应商就会产生8美元的收入。
据报道,阿里巴巴研究员吴翰清已于近期离职,钉钉显示其离职时间是5月19日。在阿里内部,研究员的职级为P10。据消息人士透露,吴翰清离职后,选择AI短视频赛道创业,已经close一轮融资。对于上述消息,截至发稿,阿里尚未回应。
阿里巴巴集团官微宣布,2023年六大业务集团总计需新招15000人,其中校招超过3000人。同时表示,“近日,关于淘宝天猫、阿里云、菜鸟、本地生活各个业务裁员谣言传得很厉害,但谣言就是谣言。我们的招聘正在紧锣密鼓的进行。”
“现今每一个存在的应用都将被AI 2.0重构,我觉得整个AI大模型带来的机遇和技术浪潮,会比过去Windows和安卓大10倍。”李开复表示。
苹果发布Vision Pro头显,正式宣布开启空间计算时代;苹果还发布新款MacBook Air,新款Mac Studio,并展示了iOS17、iPadOS 17、macOS Sonoma和watchOS10等新系统;Vision Pro头显售价3499美元,将于2024年初正式在美国市场发售;华尔街并不看好Vision Pro,苹果股价周一创历史新高后由涨转跌。
5月25日,长城汽车就比亚迪秦PLUS DM-i、宋PLUS DM-i采用常压油箱,涉嫌整车蒸发污染物排放不达标的问题进行举报。
近日,一个名为“贾跃亭”的抖音账号悄然出现,带有“FF创始人、合伙人、首席产品及用户生态官, LeEco 乐视创始人”等标签,IP 地址显示为美国。
5月29日消息,继上周远超预期的财报业绩预测引得股价和市值史诗级暴涨后,今日,英伟达(NVIDIA)创始人兼CEO黄仁勋穿着标志性的皮衣,意气风发地出现在台北电脑展COMPUTEX 2023上,在主题演讲期间先是现场给自家显卡带货,然后一连公布涉及加速计算和人工智能(AI)的多项进展。
近日,苹果位于天猫的Apple Store官方旗舰店挂出直播预告,表示将在5月31日晚19时开启官方直播,这也是苹果官方在电商平台的全球首次直播。
前京东集团副总裁、京东探索研究院副院长梅涛自今年初离职后,确认在 AI 领域创业,成立生成式 AI 公司 HiDream.ai。