效果:点击搜索或者按下ctrl+k键 ,页面就会出现搜索框
搜索框页面(SearchBar.vue)
搜索框的ts (SearchBar.ts)
封装的搜索框hook (useSearch.ts)
在app.vue中出现搜索框 (App.vue)
1.搜索框页面(SearchBar.vue)(搜索框样式自己写)
<template>
<div id="searchBarWrapper" ref="searchBarWrapper" class="search"
>
<div class="searchBox">
<div class="topChange">
<div class="botBox">
<el-input
v-model="inputLeft"
class="w-50 m-2"
:placeholder="placeholderText" >
<!-- @blur="blurChange" -->
<template #suffix>
<el-icon class="el-input__icon"
><search
/></el-icon>
</template>
</el-input>
</div>
</div>
</div>
</div>
</template>
<script lang="ts" setup>
import { defineComponent,nextTick } from 'vue'
nextTick(()=>{
//自动对焦
cleanSerachKeyword();
inmpuModal.value?.focus();
})
</script>
<style>
.search{
width: 300px;
height: 40px;
background-color: aqua;
}
</style>
2.搜索框的ts (SearchBar.ts)
import { h, render } from "vue"
import SearchBar from "./SearchBar.vue"
export default class SearchBarCreator {
container: HTMLElement
appElement: HTMLElement | null
showing: boolean
_dismiss: () => void
constructor() {
this.container = document.createElement("div")
this.showing = false
this.appElement = document.body.querySelector("#app")
this.present.bind(this)
this.dismiss.bind(this)
this._dismiss = this.dismiss.bind(this)
}
present() {
// console.log('进入方法了')
// const SearchBar2 = h(SearchBar);//虚拟dom生成VNode
// console.log('1')
// render(SearchBar2, this.container)//VNode生成真是DOM
// console.log('2')
// document.body.insertBefore(this.container, document.body.firstChild)
if (this.showing) {
this.dismiss()
} else {
const SearchBar2 = h(SearchBar)
render(SearchBar2, this.container)
const searchBarWrapperDOM =
this.container.querySelector("#searchBarWrapper")
searchBarWrapperDOM?.classList.add("animate-searchInputAnimation")
document.body.insertBefore(this.container, document.body.firstChild)
this.showing = true
this.appElement?.addEventListener("click", this._dismiss)
}
}
dismiss() {
// if(this.container){
// render(null,this.container);
// document.body.removeChild(this.container);
// }
if (this.showing && this.container) {
render(null, this.container)
document.body.removeChild(this.container)
this.showing = false
this.appElement?.removeEventListener("click", this._dismiss)
} else {
console.log("不需要关闭")
}
}
}
3.封装的搜索框hook (useSearch.ts)
import SearchBarCreator from "../views/exe/searchBar/searchBar"
const searchBar=new SearchBarCreator();
function openSearchBar(){
searchBar.present();
}
function closeSearchBar(){
searchBar.dismiss();
}
export default{
openSearchBar,
closeSearchBar
};
4.App.vue
<script lang="ts" setup>
import {
ref,
defineComponent,
getCurrentInstance,
nextTick,
onMounted,
onUpdated,
} from "vue";
import { RouterView } from "vue-router";
import { useRouter } from "vue-router";
import GlobalHeader from "./components/GlobalHeader/index.vue";
import GlobalFooter from "./components/GlobalFooter/index.vue";
import backTop from "./components/backTop/index.vue"
import useSearch from "./hook/useSearch"
const {openSearchBar,closeSearchBar}=useSearch
onMounted(()=>{
window.addEventListener("keydown",(e)=>{
if(e.ctrlKey && e.key==="k"){
//同时按下 ctrl 和 k
openSearchBar()
}
})
})
</script>
<template>
<RouterView />
<!-- <div>
<button @click="openSearchBar">搜索</button>
<button @click="closeSearchBar">关闭</button>
</div> -->
</template>
<style scoped>
@keyframes searchInput {
from{
transform:translateY(50px);
}
to{
transform: translateY((0px));
}
}
.searchInput{
animation: searchInput 1s;
}
html,body,#app{
min-height: 100vh;
}
</style>
聚焦输入框: