使用 EventBus 通过单个文件组件传递 Vue js 搜索过滤器功能
Posted
技术标签:
【中文标题】使用 EventBus 通过单个文件组件传递 Vue js 搜索过滤器功能【英文标题】:Pass Vue js search filter functionality through single file components with EventBus 【发布时间】:2020-10-03 12:20:37 【问题描述】:我有以下组件:
/components/SearchBlogs.vue
搜索组件以过滤 blog.title
和 blog.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>
在另一个页面组件博客我注册了两个组件:
<template>
<div>
<h1>Blog</h1>
<TheSidebar>
<SearchBlogs />
</TheSidebar>
<BlogList/>
</div>
</template>
任何人都可以看到这里缺少什么吗?我希望,一旦用户在搜索输入(来自SearchBlogs.vue
组件)中输入内容,它就会开始过滤和更新列表。
【问题讨论】:
嘿伙计,添加codesandbox我会为你编辑它并提供解决方案。 @Adam Orlov 这是codesandbox的链接希望你能弄清楚,非常感谢! 你想使用 EventBus 吗?没有必要。可以用它来完成,但没有意义。 我已经更新了我的答案。 【参考方案1】:看看我的解决方案condesandbox
这里有一个解释:
您不需要使用 EventBus。您可以通过 v-model
与搜索组件通信,使用 prop value
并从 Input 发出更新的 value
。
那么你的主(列表)组件负责所有的逻辑。
-
它保持搜索状态
它保留项目和过滤的项目
感谢您的搜索组件非常清晰,没有数据,这意味着它几乎没有责任。
如果我可以添加一些内容来帮助您理解,请提出问题?
更新:
-
EventBus 在某些情况下是一个很好的补充。您的案例很简单,无需添加。现在,您的架构“过度设计”。
当您在 EventBus 上添加侦听器时,
created:hook
您应该始终在组件为destroyed
时将其删除。否则你可能会遇到双重调用功能等问题。这很难调试,试试我他去过那里?
接受我的建议会让您感到“无需记住这个”,因为 Vue 正在为您做这件事。
希望有所帮助。
【讨论】:
好的,谢谢您的解释!我在this issue 上的复选框是否适用相同的原则。如果我得到这个工作,我必须在 List 组件上结合 Search 和 Checkbox 组件,它们应该同时工作。 一般来说应该使用什么或建议。有没有 EventBus? 谢谢解释,很清楚。根据您的示例,我尝试添加复选框。你能明白为什么它不工作吗?这是sandbox 的链接。谢谢 @meez 1. 您的过滤逻辑不正确。 2. 您的value:prop
已注册为字符串。它必须是数组。这里⏩codesandbox.io/s/busy-sun-efo5h?file=/src/components/List.vue
我有一个问题。为了构建我的布局和路线,我进行了以下调整:在路线组件中Blogs.vue
我注册了我的组件:<Search v-model="search" /> <Checkbox v-model="checked" /> <List />
。然后在数据对象中:search: "", checked: [], experiences: [],
这应该工作吗?因为它没有过滤?【参考方案2】:
几个问题,但基本上计算出来的 prop filteredData
看起来像:
computed:
filteredData()
return this.experiences.filter(
el => el.category.indexOf(this.search) > -1
);
此外,在将其值传回时,在 'this.search'
周围使用引号,使其成为字符串。
固定沙盒
https://codesandbox.io/s/reverent-lamarr-is8jz
【讨论】:
也可以使用el => el.category.startsWith(this.search)
只是为了理解这个概念。 el => el
这里发生了什么?您何时以及如何使用它?
它是一个缩短的箭头函数,相当于(el) => return el.category.startsWith(this.search)
根据您的示例,我尝试添加搜索框。 ToLowerCase 方法很重要。我还为搜索添加了第二个 EventBus 是否可取?这是sandbox的链接
imo 在主应用程序中使用事件总线是不好的做法(从全局插件公开的事件总线很好,即 this.$modal.open() 等),而是在组件上使用 vues @eventName=""
广告用this.$emit('eventName', this.theValue)
发出它以上是关于使用 EventBus 通过单个文件组件传递 Vue js 搜索过滤器功能的主要内容,如果未能解决你的问题,请参考以下文章