使用 EventBus 通过单个文件组件传递 Vue js 搜索过滤器功能
Pass Vue js search filter functionality through single file components with EventBus
我有以下组件:
/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>
在另一个 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'
,使其成为字符串。
修复了沙盒
看我的解法condesandbox
解释如下:
您不需要使用 EventBus。您可以通过 v-model
、使用属性 value
并从输入中发出更新的 value
与搜索组件进行通信。
然后您的主要(列表)组件负责所有逻辑。
- 它保持搜索的状态
- 保留项目和过滤项目
感谢您的搜索组件非常清晰并且没有数据,这意味着它的责任很小。
如果我可以添加一些内容来帮助您理解,请提出问题
更新:
- EventBus 在某些情况下是一个很好的补充。你的情况很简单,没有必要添加它。现在你的架构是 "over engineered".
- 当您在 EventBus 上添加侦听器时,在
created:hook
上,您应该始终在 Component destroyed
时将其删除。否则你可能会遇到双重调用函数等问题。这很难调试,试试我我去过那里
- 采纳我的建议会让您放心 "no-need-to-remember-about-this" 因为 Vue 正在为您做这件事。
希望有所帮助。
我有以下组件:
/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>
在另一个 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'
,使其成为字符串。
修复了沙盒
看我的解法condesandbox
解释如下:
您不需要使用 EventBus。您可以通过 v-model
、使用属性 value
并从输入中发出更新的 value
与搜索组件进行通信。
然后您的主要(列表)组件负责所有逻辑。
- 它保持搜索的状态
- 保留项目和过滤项目
感谢您的搜索组件非常清晰并且没有数据,这意味着它的责任很小。
如果我可以添加一些内容来帮助您理解,请提出问题
更新:
- EventBus 在某些情况下是一个很好的补充。你的情况很简单,没有必要添加它。现在你的架构是 "over engineered".
- 当您在 EventBus 上添加侦听器时,在
created:hook
上,您应该始终在 Componentdestroyed
时将其删除。否则你可能会遇到双重调用函数等问题。这很难调试,试试我我去过那里 - 采纳我的建议会让您放心 "no-need-to-remember-about-this" 因为 Vue 正在为您做这件事。
希望有所帮助。