如题,我花了一个多小时,参照 nuxt 文档,把搜索功能给加上了,记录一下相关代码。

可以选择放在 components/<Search /> 里面,然后引入到 head 模板,也可以单独创建一个页面,我选择的是后者。

新建一个页面模板 /pages/search.vue

<template>
  <div>
    <HeaderMe />
    <div class="wrapper">
      <PageSidebar />
      <div class="archive">
        <h2>{{ article.attributes.title }}</h2>
        <div class="article-content markdown-body" v-html="article.html"></div>
        <div class="search">
          <input v-model="searchQuery" type="search" autocomplete="off" placeholder="文章关键词" />
          <ul v-if="articles.length">
            <li v-for="article of articles" :key="article.slug">
              <NuxtLink :to="article.path+'/'">{{ article.title }}</NuxtLink>
               <!-- 在url地址后加一个/配置全站的url格式防止错乱 -->
            </li>
          </ul>
        </div>
      </div>
    </div>
  </div>
</template>

<script>
import HeaderMe from "@/components/HeaderMe";
import PageSidebar from '@/components/PageSidebar';
export default {
  components: {
    HeaderMe,
    PageSidebar
  },
  data () {
    return {
      searchQuery: '',
      articles: []
    }
  },
  async asyncData () {
    // 调用 search.md 内的数据
    const article = await import(`~/content/search.md`);
    return {
      article
    };
  },
  watch: {
    async searchQuery (searchQuery) {
      if (!searchQuery) {
        this.articles = []
        return
      }
      this.articles = await this.$content('posts') // posts 是文章所在的文件夹的名称
        .limit(10)
        .search(searchQuery)
        .fetch()
    }
  }
}
</script>

关于样式的编写不怎么重要我就放下面了。

css 代码
.wrapper {
  min-height: 300px;
  .archive {
    padding: 25px 2% 15px;
    .article-content {
      font-size: inherit;
      line-height: 1.8;
      color: inherit;
      margin-top: 20px;
    }
    .search {
      margin-top: 16px;
      input {
        width: 100%;
        background-color: #edf2f7;
        color: #2f495e;
        outline: none;
        border: none;
        border-radius: 30px;
        padding: 4px 20px;
        box-sizing: border-box;
        transition: all 0.1s linear;
        &:focus {
          box-shadow: 3px 2px 10px rgb(0 0 0 / 20%);
        }
      }
      ul {
        margin-top: 6px;
        list-style: none;
        li {
          a {
            display: block;
            padding: 6px 14px;
            line-height: 1.6;
            transition: all 0.2s linear;
            &:hover {
              background: #edf2f7;
            }
          }
        }
      }
    }
  }
}
@media (max-width: 520px) {
  .wrapper {
    .archive {
      .search {
        ul {
          li {
            a {
              border-bottom: 1px solid #ddd;
            }
          }
        }
      }
    }
  }
}