【发布时间】:2020-11-09 11:57:47
【问题描述】:
我有一个父组件,它有条件地呈现两个子组件之一:
<template>
<div>
<!-- other code that changes conditional rendering -->
<folders v-if="isSearchingInFolders" :key="1234"></folders>
<snippets v-if="!isSearchingInFolders" :key="5678"></snippets>
</div>
</template>
这些组件中的每一个都在本地使用相同的 mixin (searchMixin),如下所示:
<template>
<div>
<div>
<snippet
v-for="item in items"
:snippet="item"
:key="item.id">
</snippet>
<img v-if="busy" src="/icons/loader-grey.svg" width="50">
</div>
<button @click="getItems">Get More</button>
</div>
</template>
<script>
import searchMixin from './mixins/searchMixin';
import Snippet from './snippet';
export default {
components: { Snippet },
mixins: [searchMixin],
data() {
return {
resourceName: 'snippets'
}
},
}
</script>
每个组件在功能上都是等效的,但标记略有不同,因此在本示例中,文件夹可以替换为片段,反之亦然。
我使用的 mixin 看起来像这样(简化):
import axios from 'axios'
import { EventBus } from '../event-bus';
export default {
data() {
return {
hasMoreItems: true,
busy: false,
items: []
}
},
created() {
EventBus.$on('search', this.getItems)
this.getItems();
},
destroyed() {
this.$store.commit('resetSearchParams')
},
computed: {
endpoint() {
return `/${this.resourceName}/search`
},
busyOrMaximum() {
return this.busy || !this.hasMoreItems;
}
},
methods: {
getItems(reset = false) {
<!-- get the items and add them to this.items -->
}
}
}
在父组件中,当我通过更改 isSearchingInFolders 变量来切换渲染时,预期的组件将被销毁并从 DOM 中删除(我已通过从 destroyed() 生命周期挂钩记录来检查这一点。但是 searchMixin被包含在那个组件中似乎没有被销毁并且仍然似乎在监听事件。这意味着当EventBus.$on('search', this.getItems)行在更改从父组件主动呈现后触发时,this.getItems()被触发两次。一次为文件夹和一次用于 sn-ps!
我期待组件的 mixin 与组件本身一起被销毁。我是否误解了组件销毁的工作原理?
【问题讨论】:
-
我还没有找到一个优雅的解决方案。然而,与此同时,我使用
active: true在mixin 数据中使用active布尔切换构建了一个解决方法。然后在destroyed()生命周期挂钩中,我使用this.active = false将其设置为false。然后,在this.getItems()方法 -if (this.active) { do some stuff }中执行任何操作之前,我会检查 mixin/组件的活动状态。这有效并防止在不应该调用 mixin 操作时调用它们。但是,对此的任何见解将不胜感激! -
应该有一种机制可以取消订阅该事件。这通常在
destroy钩子中完成,如下所示:EventBus.$off('search', this.getItems) -
啊哈!就是这个。非常感谢!所以这实际上是由全局可用的
EventBus仍在监听搜索事件引起的,而不是组件本身,对吗?如果您想将此添加为答案,我很乐意接受。 -
我添加了一个答案,其中还包括您在评论中的问题。
标签: javascript vue.js vuejs2 vue-component mixins