搜索组件

117 阅读1分钟

对于搜索这是项目中用得非常多的,下面就对此进行封装 现在有一个需求:要求用户在输入框里输入搜索的内容后,当前搜索关键字出现在导航栏,按下回车键实现搜素,并且刷新当前页面后当前输入的关键字仍然在

image.png

具体代码: sec/components/SearchInput.vue

<template>
    <div class="search">
        <el-input v-model="keyword" placeholder="请输入搜素关键字" clearable @clear="handleClear" @keyup.enter="handleSearch">
        </el-input>
    </div>
</template>

<script setup>
import { ref, watchEffect } from 'vue';
import { useRoute, useRouter } from 'vue-router';


const router = useRouter();
const route = useRoute();
const keyword = ref(route.query.keyword || '')

//  监听 URL query 变化,并更新 keyword 值
watchEffect(() => {
    keyword.value = route.query.keyword || ''
})

const handleSearch = () => {
    router.push({
        path: route.path,
        query: {
            ...route.query, // 保留当前 url
            keyword: keyword.value // 新增关键字到 url
        }
    })
}

const handleClear = () => {
    keyword.value = ''
    router.push({
        path: route.path,
        query: {
            ...route.query, // 保留当前 url
            keyword: null // 置空
        }
    })
}
</script>

<style lang="scss" scoped>
.search {
    width: 200px;
    display: flex;
    align-items: center;
    height: 40px;
}
</style>

App.vue

<template>
  <div class="top-navbar">
    <div class="left-section">
      <div class="logo">
        <router-link to="/">
          <h1>TechBlog</h1>
        </router-link>
      </div>
      <NavMenu class="nav-menu"></NavMenu>
      <SearchInput></SearchInput>
    </div>
    <div class="right-section">
      <router-link class="login-link" to="/login">登录</router-link>
    </div>
  </div>
  <div class="main-content">
    <div class="container">
      <router-view />
    </div>
  </div>
</template>

<script setup>
import NavMenu from '@/components/NavMenu.vue';
import SearchInput from '@/components/SearchInput.vue';
</script>

<style lang="scss" scoped>
.top-navbar {
  display: flex;
  justify-content: space-between;
  align-items: center;
  width: 100%;
  height: 60px;
  background-color: #f5f5f5;
  padding: 0 20px;
  box-sizing: border-box;
  border-bottom: 1px solid var(--el-menu-border-color);
}

.left-section {
  display: flex;
  align-items: center;
}

.nav-menu {
  border-bottom: none !important;
  margin-left: 20px;
}

.logo {
  height: 40px;
}

.logo a {
  text-decoration: none;
}

.right-section a {
  text-decoration: none;
}

.main-content {
  width: 100%;
  padding: 20px;
  box-sizing: border-box;
}

.container {
  max-width: 1000px;
  margin: 0 auto;
}
</style>