使用 EventBus 通过单个文件组件传递 Vue js 搜索过滤器功能

Pass Vue js search filter functionality through single file components with EventBus

我有以下组件:

/components/SearchBlogs.vue 要根据 blog.titleblog.description.

过滤的搜索组件

/components/BlogList.vue 这里我列出了所有的博客项目。

SearchBlogs.vue

<template>
  <div>
    <input type="text" v-model="search" @change="emitSearchValue" placeholder="search blog">
  </div>
</template>

<script>
import { EventBus } from '../event-bus.js'

export default {
  name: 'SearchBlogs',
  data: () => {
    return {
      search: ''
    }
  },
  methods: {
    emitSearchValue() {
      EventBus.$emit('search-value', 'this.search')
    }
  }
}
</script>

BlogList.vue

<template>
<div>
  <div v-for="blog in filteredBlogs" :key="blog">
    <BlogListItem :blog="blog" /> 
  </div>
</div>
</template>

<script>
import BlogListItem from './BlogListItem'
import { EventBus } from '../event-bus.js'

export default {
  name: 'BlogList',
  components: {
    BlogListItem,
  },
  data: () => {
    return {
      blogs: [],
      searchvalue: ''
    }
  },
  computed: {
    filteredBlogs() {
      return this.blogs.filter(blog =>
        blog.name.toLowerCase().includes(
          this.searchvalue.toLowerCase()
        )
      )
    }
  },
  created() {
    fetch('http://localhost:3000/blogs')
    .then(response => {
      return response.json();
    })
    .then(data => {
      this.blogs = data;
    }),
    EventBus.$on('search-value', (search) => {
      this.searchvalue = value;
    })
  }
}
</script>

在另一个 page 组件 Blogs 我注册了两个组件:

<template>
  <div>
    <h1>Blog</h1>
    <TheSidebar>
      <SearchBlogs />
    </TheSidebar>
    <BlogList/>
  </div>
</template>

有人能看出这里缺少了什么吗?我希望,一旦用户在搜索输入中输入内容(来自 SearchBlogs.vue 组件),它就会开始过滤和更新列表。

几个问题,但本质上计算的道具 filteredData 看起来像:

computed: {
    filteredData() {
      return this.experiences.filter(
        el => el.category.indexOf(this.search) > -1
      );
    }
}

此外,在将其值传回时使用引号 'this.search',使其成为字符串。

修复了沙盒

https://codesandbox.io/s/reverent-lamarr-is8jz

看我的解法condesandbox

解释如下: 您不需要使用 EventBus。您可以通过 v-model、使用属性 value 并从输入中发出更新的 value 与搜索组件进行通信。

然后您的主要(列表)组件负责所有逻辑。

  1. 它保持搜索的状态
  2. 保留项目和过滤项目

感谢您的搜索组件非常清晰并且没有数据,这意味着它的责任很小。

如果我可以添加一些内容来帮助您理解,请提出问题

更新

  1. EventBus 在某些情况下是一个很好的补充。你的情况很简单,没有必要添加它。现在你的架构是 "over engineered".
  2. 当您在 EventBus 上添加侦听器时,在 created:hook 上,您应该始终在 Component destroyed 时将其删除。否则你可能会遇到双重调用函数等问题。这很难调试,试试我我去过那里
  3. 采纳我的建议会让您放心 "no-need-to-remember-about-this" 因为 Vue 正在为您做这件事。

希望有所帮助。