vue 销毁keep-alive

需要解决的问题

项目中列表过多,很多情况在离开页面后需要保存页面的信息和数据。
keep-alive是方便的形式之一,但是在很多情况下还是要销毁原来的数据,便开始思索如何解决这个问题。

填坑

我看到有同事居然这么写了:

	activated () {
		if (this.$route.query.form.path === '.....')  {
			// 重置页面内的数据....
		}
	}

在做code review的时候心里真的是万马奔腾,
然后便决定去封装一个公用的销毁keep-alive的方法。

废话不多说,上代码

App.js


<template>
  <div id="app">
  
    <keep-alive :exclude="excludeName">
      <router-view v-if="$route.meta.keepAlive">router-view>
    keep-alive>
    <router-view v-if="!$route.meta.keepAlive">router-view>
  div>
template>

router.js

  {
    path: '*****',
    name: '*****',
    component: () => import('list'),
    meta: {
      keepAlive: true
    }
  },

list.vue

  computed: {
  	// 获取getter中数据
    ...mapGetters(['excludeName'])
  },
  methods: {
    // 设置store中数据
    ...mapActions('app', ['setExcludeName'])
  },
  created () {
    this.myExcludeName = this.excludeName
    for (let i = 0; i < this.myExcludeName.length; i += 1) {
      /* 
      * 进入页面时从 excludeName 删除当前页面的name
      */
      if (this.myExcludeName[i] === this.$route.query.to.name) {
        this.myExcludeName.splice(i, 1)
        break
      }
    }
    this.setExcludeName([this.myExcludeName])
  },
  activated () {
    // 详情页返回需要执行的代码
  },
  deactivated () {
    let nextPath = this.$route.query.to.path // 下一页面url
    let currentName = this.$route.query.from.name // 当前页面name
	// 当下个页面不是详情页的时候,销毁当前页面
	if (nextPath !== '/detail') {
	  this.setExcludeName(currentName)
	}
  }

初步的思路已经有了,下面开始封装成通用方法,因为涉及到多个钩子函数,这里选择使用mixins:(mixins的具体用法见官方文档:vue.js.)
当前页面可能有多个子级页面,将nextPage修改为数组。

mixins.js

// 定义一个常量,以后直接在数组中增加页面的path就ok了
    const PageArray = [
      {
        currentPage: '/list1',
        nextPage: [ '/detail' ]
      },
      {
        currentPage: '/list2',
        nextPage: [ '/detail1', '/detail2' ]
      }
    ]
export const myDestroyed = {
  computed: {
    ...mapGetters(['excludeName'])
  },
  methods: {
    ...mapActions('app', ['setExcludeName'])
  },
  created () {
    this.myExcludeName = this.excludeName
    for (let i = 0; i < this.myExcludeName.length; i += 1) {
      if (this.myExcludeName[i] === this.$route.query.to.name) {
        this.myExcludeName.splice(i, 1)
        break
      }
    }
    this.setExcludeName([this.myExcludeName])
  },
  deactivated () {
    /*
    * myDestroyed
    *   从 currentPage 页面计入 nextPage 页面时 keep-alive
    *   其他情况均销毁 currentPage 页面
    *
    * 使用注意事项:
    *   router中
    *     meta:{
    *       keep-alive: true
    *     }
    *
    *    组建 name 必须写对
    *
    *  使用方法:
    *     在PageArray中增加currentPage和nextPage
    * */
    let nextPath = this.$route.query.to.path // 下一页面url
    let currentPath = this.$route.query.from.path // 当前页面url
    let currentName = this.$route.query.from.name // 当前页面name
    for (let i = 0; i < PageArray.length; i += 1) {
      let item = PageArray[i]
      if (currentPath === item.currentPage) {
        let isDestroy = !item.nextPage.some(nextItem => {
          // 匹配上: 不销毁当前页面
          return nextPath === nextItem
        })
        if (isDestroy) { // 销毁当前页
          this.setExcludeName(currentName)
          break
        }
      }
    }
  }
}

然后在需要使用的组建中引入就ok了

import { myDestroyed } from '@/mixin/index'
export default {
  name: 'List',
  mixins: [ myDestroyed ]
}

其实,思路很简单,就是在跳转到不需要保存数据的页面时,把当前页面的name放到exclude 数组中就ok了。

你可能感兴趣的:(vue)