1

我有一个有效的 Vue Js 搜索,但我希望能够tags在我的 JSON 中搜索该字段。我怎么做?我知道我必须添加另一个过滤条件,|| this.list_search...但是如何遍历标签并返回标签的父级?

任何帮助将不胜感激。

<!doctype html>
<html lang="en" class="min-h-screen bg-gray-300 dark:bg-gray-900" hidden>
  <head>
    <meta charset="utf-8" />
    <meta http-equiv="x-ua-compatible" content="ie=edge" />
    <title>Vue Search</title>
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <link href="https://unpkg.com/font-awesome@^4.0/css/font-awesome.min.css" rel="stylesheet" />
    <link href="https://fonts.gstatic.com" rel="preconnect" />
    <link href="https://fonts.googleapis.com/css2?family=Roboto:wght@100;400;700&amp;display=swap" rel="stylesheet" />
  </head>
  <body class="min-h-screen bg-gradient-to-b from-gray-50 dark:from-gray-800 to-gray-300 dark:to-black bg-fixed text-gray-500">

    <div class="page min-h-screen flex flex-col" v-cloak>
      <header></header>
      <main class="py-8">
        <section class="mx-auto max-w-xl">
          <fieldset class="py-8 px-4 relative">
            <input type="search" id="search" v-model="list_search" class="appearance-none py-3 px-5 w-full bg-gray-500 bg-opacity-10 block rounded-md transition duration-300 focus:(bg-white outline-none shadow-xl ring(& current)) relative z-20" placeholder="Search" />
            <label for="search" class="w-8 h-8 flex items-center justify-center absolute z-10 right-5 top-1/2 transform -translate-y-1/2"><i class="fa fa-fw fa-search"></i></label>
          </fieldset>
          <section v-if="!list_results.length" class="text(gray-500 opacity-50) font-bold text-2xl uppercase tracking-wider text-center">No Results</section>
          <ul class="divide(y gray-500 opacity-10)">
            <li v-for="(item, index) in list_results" class="p-4">
              {{ item.title }}
              <ol v-if="item.tags" class="-mx-2 px-1 text-xs flex flex-wrap">
                <li v-for="(tag, index) in item.tags" class="p-1"><b class="px-1 py-px inline-block rounded bg-gray-500 bg-opacity-25">{{ tag.title }}</b></li>
              </ol>
            </li>
          </ul>
        </section>
      </main>
      <footer class="mt-auto py-8 px-4 border(t gray-500 opacity-10) text(gray-500 opacity-50) text-xs font-bold uppercase text-right">
        Made with <svg xmlns="http://www.w3.org/2000/svg" class="-mt-1 mx-1 text-red-500 inline-block" width="16" height="16" viewBox="0 0 16 16" role="img" aria-labelledby="foot-love"><title id="foot-love">Love</title><polygon class="fill-current" fill-rule="evenodd" points="8 6 11 3 15 7 8 14 1 7 5 3"></polygon></svg> by <a href="http://craigerskine.com/" class="mx-1">Craig Erskine</a>
      </footer>
    </div>

    <script src="https://unpkg.com/vue/dist/vue.min.js"></script>
    <script>
      // data
      var app = new Vue({
        el: '.page',
        data() {
          return {
            list_search: null,
            list: [
              {
                title: 'Colleries unexhaustibly',
                tags: [
                  { title: 'Some Tag 1' },
                  { title: 'Ultra Tag 2' },
                  { title: 'Mega Tag 3' }
                ]
              },
              {
                title: 'Reliableness slippingly'
              },
              {
                title: 'Nyctalopy interacinous'
              },
              {
                title: 'Surculose lovesickness'
              },
              {
                title: 'Nonfrosted manicure'
              },
            ],
          }
        },
        computed: {
          list_results(){
            if(this.list_search){
              return this.list.filter((item)=>{
                return this.list_search.toLowerCase().split(' ').every(v => item.title.toLowerCase().includes(v))
              })
            } else {
              return this.list;
            }
          }
        }
      });
    </script>

    <script type="module">
      import {tw, setup, silent} from "https://cdn.skypack.dev/pin/twind@v0.16.11-QeLZmrfZsMzGLVRytSNH/mode=imports,min/optimized/twind/shim.js"
      import {css, theme, apply} from "https://cdn.skypack.dev/pin/twind@v0.16.11-QeLZmrfZsMzGLVRytSNH/mode=imports,min/optimized/twind/css.js"
      import * as colors from "https://cdn.skypack.dev/pin/twind@v0.16.11-QeLZmrfZsMzGLVRytSNH/mode=imports,min/optimized/twind/colors.js"
      import typography from "https://cdn.skypack.dev/pin/@twind/typography@v0.0.2-CxlC88Z1FhV6a2lXcLpI/mode=imports,min/optimized/@twind/typography.js"
      setup({
        mode: silent,
        theme: {
          fontFamily: {
            sans: ['Roboto', 'sans-serif'],
          },
          extend: {
            colors: {
              gray: colors.gray,
            },
          },
        },
      })
      tw(() => ({
        '@global': {
          ':root v-cloak': apply('hidden'),
        }
      }))
    </script>

  </body>
</html>
4

1 回答 1

0

搜索功能应包括标签标题:

new Vue({
  el: '.page',
  data() {
    return {
      list_search: null,
      list: [{
          title: 'Colleries unexhaustibly',
          tags: [{
              title: 'Some Tag 1'
            },
            {
              title: 'Ultra Tag 2'
            },
            {
              title: 'Mega Tag 3'
            }
          ]
        },
        {
          title: 'Reliableness slippingly'
        },
        {
          title: 'Nyctalopy interacinous'
        },
        {
          title: 'Surculose lovesickness'
        },
        {
          title: 'Nonfrosted manicure'
        },
      ],
    }
  },
  computed: {
    list_results() {
      if (this.list_search) {
        return this.list.filter((item) => {

          // create an array of tag titles (or [])
          const tags = item.tags?.map(({
            title
          }) => title.toLowerCase()) ?? []

          // create the full array that must have a match
          const arr = [item.title.toLowerCase(), ...tags]

          // return true if some of the items include the search
          return arr.some(e => e.includes(this.list_search))
        })
      } else {
        return this.list;
      }
    }
  },
});
<script src="https://unpkg.com/vue/dist/vue.min.js"></script>

<div class="page">
  <input type="text" v-model="list_search" /> {{ list_search }}
  <hr> FULL LIST:<br />
  <ul>
    <li v-for="(item, i) in list" :key="i">
      {{ item.title }}, (
      <span v-for="(tag, j) in item.tags" :key="j">
        {{ tag.title }},
      </span>)
    </li>
  </ul>
  <hr> SEARCHED LIST:<br />
  <ul>
    <li v-for="(item, i) in list_results" :key="i">
      {{ item.title }}, (
      <span v-for="(tag, j) in item.tags" :key="j">
        {{ tag.title }},
      </span>)
    </li>
  </ul>
</div>

于 2021-04-18T11:44:04.313 回答