一个Vue案例引发的动态组件和全局事件绑定总结只有掌握了知识点,然后才能发现问题并解决问题,才能提升我们的能力,否则就有点霸道了。基于这样的想法,我开始自己搭建一个旅游网站。旅游网站绕不开城市选择,所以在实施城市选择列表时遇到的一些问题,以及解决办法,今天就记录下来做个总结。城市列表选择组件首先说一下我们要实现一个什么样的城市选择组件:当输入框获得焦点时,显示组件点击城市列表更新输入框中的城市显示。城市被保留而不是被重置。接下来我们一步步拆解。第一步是在输入框获得焦点后显示组件。这很简单。我们将焦点事件绑定到输入框,然后将显示状态传递给组件。我们将isShowCityList传递给城市选择器以控制行为。第二步我们不做太多的表达本文想介绍更多的动态组件和全局事件的绑定使用从子组件到父组件的自定义事件$emit传递给父组件。第三步需要我们点击隐藏城市组件的其他地方。有的同学第一印象可能是用input的blur事件(也就是focus事件)。只要我们的输入失去焦点,我们就会隐藏它。其实我的第一印象是一样的,但是我们绑定了input失焦事件之后,当我们选择城市列表的时候,input失去了焦点,所以我们无法选择城市。显然,这种思维方式是不能接受的。所以这里只能通过Vue的全局事件的绑定,然后对我们点击的节点在哪做判断。如果它在城市组件之外,我们将进行隐藏操作。我们在挂载的钩子函数中进行如下操作。mounted(){document.addEventListener("click",e=>{console.log('全局事件被触发');if(!this.$refs.searchCity.contains(e.target)){this.isLoadCityList=false;}});}OK,经过这一步,我们的问题就解决了,只要我们在这个容器外点击,城市列表组件就会被隐藏,我以为就这样结束了,其实不可能,还是我tooyoung,这样做的后果是无论我们点击哪里,都会触发这个事件,即使我们切换到其他组件,这个事件仍然会被触发,显然这不是我们想要的,因为当前事件会无限的触发器无疑会给我们带来意想不到的问题。我们需要的最佳效果一定是当前全局事件在当前组件下起作用。当我们切换到其他组件时,该事件会自动删除,所以我可能想到的是使用beforeDestroy钩子函数来删除这个全局事件。也就是当我们切换到其他组件时,删除这个全局事件。beforeDestroy(){document.removeEventListener("click",()=>{//...});}你觉得我这样能解决问题吗?明明还是不行,还是太年轻了,只是不能解绑事件而已,怎么办?其实有一个坑,一个大坑,因为我不知道这个大坑,查了很多资料也没有发现,因为badidea是错误的,最后问了一个大佬在一个小组中获得答案。不得不说,和前辈的交流很重要,可以帮你避免很多坑。这里如果要解绑,解绑和绑定的两个回调函数必须一致。这意味着什么?看代码你就明白了。如果不这样做,您将无法解决事件。至于更深层次的原因,我不是很明白。稍后我会检查一些信息。methods:{isSearchCityNode(e){if(!this.$refs.searchCity.contains(e.target)){console.log("全局事件被触发");this.isLoadCityList=false;}}},mounted(){document.addEventListener("click",this.isSearchCityNode);},beforeDestroy(){document.removeEventListener("click",this.isSearchCityNode);}第四步需要我们保留城市我们在切换组件时选择的,如果不保留,每次切换到其他组件时,我们选择的城市将被重置为默认值。这种体验肯定不好,也不是我们想要的。之所以被重置是因为我们每次在不同的组件之间切换时,都会创建和销毁组件,这样也会造成重复渲染的问题,对性能不友好。那么我们如何解决这个问题呢?我这里使用keep-alive来解决这个问题,那么keep-alive怎么用,它的作用是什么呢?包装动态组件时,它会缓存不活动的组件实例而不是销毁它们,它不会将自己呈现为DOM元素,也不会出现在父组件链中。但是当我们使用的时候,我们的beforeDestroy钩子函数就会失效,无法执行第三步全局事件的解绑定,因为我们的组件是缓存的,没有销毁。它会自然失败,但我们不要惊慌。当我们使用时,会触发activated和deactivated钩子函数。activated:激活keep-alive组件时调用。deactivated:当keep-alive组件被停用时调用。所以我们不难发现,我们可以利用这两个钩子来实现我们全局事件的绑定和解绑,非常完美。activated(){document.addEventListener("click",this.isSearchCityNode);},deactivated(){document.removeEventListener("click",this.isSearchCityNode);}总结一个城市列表组件的案例,在How中给我们介绍在Vue中绑定和优化全局事件,一定要记住事件的绑定和解绑定是有一个大坑的。我们可以通过创建一个可以缓存的组件,会新增两个钩子函数供我们使用。文中如有不足,欢迎拍砖!