在公司使用 vue 写 h5 已经一年多了,想着总结下期间的一些心得

第一篇主要写如何动态缓存 h5 页面。

为了让 h5 体验足够好,一个最好的方式就是充分利用缓存,而不是每次都会向后端请求数据。

下面有这样一个需求,用户从首页 A 进入某个列表页 B 时需要实时获取最新的数据,然后点击某条消息进入详情页 C,再返回列表页 B 时,希望能够直接利用缓存数据不发送请求,并记住当前列表页 B 滚动的位置。

了解 vue 的童鞋可能都会想到 keep-alive,但又如何控制页面什么时候利用缓存什么时候不用呢?这里我用到了 vuex 来保存保存需要缓存的页面名字。

首先,先在应用最顶层的页面 App.vue 里如下设置 keep-alive:

<template>
  <keep-alive :include="cacheComponents">
    <router-view />
  </keep-alive>
</template>

<script>
...
computed: {
    ...mapState(['cacheComponents']),
   ...
}
</script>
...
复制代码

其中 cacheComponents 是需要缓存的页面组件的名称组成的数组,维护在 vuex 的全局状态里面。

state.js 文件

const state = {
    cacheComponents: ['B'],
}

export default state;
复制代码

mutation.js 文件

const mutations = {
  ADD_CACHE_COMPONENT(state, component = {}) {
    if (!state.cacheComponents.includes(component.name)) {
      state.cacheComponents = [...state.cacheComponents, component.name];
    }
  },

  REMOVE_CACHE_COMPONENT(state, component = {}) {
    if (state.cacheComponents.indexOf(component.name)) {
      state.cacheComponents.splice(
        state.cacheComponents.indexOf(component.name),
        1,
      );
    }
  },
};

export default mutations;
复制代码

这样我们就可以通过 vuex 的 commit 对全局 state 中的 cacheComponents 数组进行操作,来动态控制需要缓存的页面。

那么我们又如何知道在什么时候改变 cacheComponents 呢?其实可以利用 vue-router 中router 实例的 beforeEach 进行监听,如下

route.js 文件

import Vue from 'vue';
import Router from 'vue-router';
import routes from './route-list';
import store from '@/common/store';
import cachedCompHandler from '@/common/utils/cachedCompHandler';

Vue.use(Router);

const router = new Router({
  routes,
});

router.beforeEach((to, from, next) => {
  cachedCompHandler(to, from, store);
  ...
}
复制代码

其中 cachedCompHandler 方法如下,当从 A 进入 B 时, 从 cacheComponents 去除 B , 否则加上 B:

export default function cachedCompHandler(to, from, store) {
  if (from.name === 'A' && to.name === 'B') {
    store.commit('REMOVE_CACHE_COMPONENT', {
      name: 'B',
    });
  } else {
    store.commit('ADD_CACHE_COMPONENT', {
      name: 'B',
    });
  }
}
复制代码

最后又会有一个问题,就是如果这个是一个待审批的列表,用户点击某项进入详情页,返回的时候希望该项不在列表里,但同时又要利用缓存不发送请求。

这个时候就要配合 keep-alive 对应的 vue 生命周期 activated / deactivated了,这个生命周期就是被 keep-alive 的组件唯一能够触发的钩子。

当用户成功处理了某个事项,返回列表时可以通过 localstorage 或 url 将 id 传回来,在列表页面 B 中的 activated 钩子里,将维护在组件状态 data 里的对应数据进行清除即可。