vue創建緩存導航的過程或者緩存tag???


背景:

在公式做ms管理系統。然后老大看事情做差不錯了,想要優化一下用戶體驗。要我在每次用戶切換頁面后創建一個類似瀏覽器多頁面tag的導航。這樣用戶在使用時方便做數據比較。

最后長這樣

 

分析:

這個放在以前那就是多開一個頁面的事兒,讓瀏覽器幫我們保存數據和結構。放到vue里面,因為我們的結構是根據數據決定的,那就是保存一下數據的概念。保存數據的方式瞬間想到sessionstorage、localstorage,但是顯然這兩個是瀏覽器級別的,我們是有權限控制的所以pass掉。那就只能放在我們頁面的數據里面了。

因為是全局的,你需要在所有頁面都可以讀取、刪除。那就放在vuex這個狀態機里面。

然后狀態機里面你需要做幾件事:

1、添加這個tag(你可能需要判斷是否數量會太多,太多的話會影響性能)

2、更新這個tag(更新根據數組的鍵,就可以了)

3、銷毀這個tag

 

數據

export default {
  state: {
    tags: [],//訪問過的頁面集合
    deepCopy: function(initalObject, finalObject) {
      var finalObject = finalObject || {}
      for (var key in initalObject) {
        var tempProperty = initalObject[key]
        if (tempProperty === initalObject) {
          continue //當自身屬性引用自己的時候,跳過執行,不拷貝,避免相互引用導致內存溢出的情況
        }
        if (typeof initalObject[key] === "object" && initalObject[key] !== null) {
          finalObject[key] = (initalObject[key].constructor === Array) ? [] : {} //區分構造函數
          this.deepCopy(initalObject[key], finalObject[key]) //調用自身函數方法
        } else {
          finalObject[key] = initalObject[key]
        }
      }
      return finalObject
    }
  },
  getters: {
    tags(state) {
      return state.tags;
    }
  },
  mutations: {
    //將tag放進tags
    addTags(state, tag) {
      let index = state.tags.length;
      if (index > 8) {
        state.tags.splice(index > 0 ? index - 1 : 0, 1, state.deepCopy(tag));
      } else {
        state.tags.splice(index > 0 ? index : 0, 0, state.deepCopy(tag));
      }

    },
    /*
     *tag.index和state.tags[tag.index]判斷key值是否正確以及是否存在數據
     *state.tags[tag.index].name == tag.name 確定修改的路徑是否一致,防止刪除時修改
     */
    updateTags(state, tag) {
      if (tag.index !== null && state.tags[tag.index] && state.tags[tag.index].name == tag.name) {
        let data = {
          name: state.tags[tag.index].name,
          data: state.deepCopy(tag.data)
        }
        state.tags.splice(tag.index, 1, data);
      }

    },
    delTags(state, index) {
      state.tags.splice(index, 1)
    },
    //從tag進入時,由緩存初始化數據
    cacheDataInit(state, { that, datashow }) {
      let datas = that.$data;
      Object.keys(datas).forEach((val) => {
        that[val] = datashow[val]
      })
    }
  },
  actions: {
    /*
     *在模塊復用的時候調用的時候更新數據
     *that 頁面this參數
     *to route中的to參數
     */
    beforeRouteUpdate({ commit, state }, { that, to }) {
      let status = that.$route.query.status;

      if (status === 'cache') {
        let index = that.$route.query.key;//該tag在tags數組中的鍵
        let data = {
          index,
          data: that.$data,
          name: that.$route.path
        }
        commit('updateTags', data);
      }
    },
    /*
     *在路由跳轉之前更新數據
     *that 頁面this參數
     */
    beforeRouteLeave({ commit, state }, that) {
      if (that.$route.query.status === 'cache') {
        let index = that.$route.query.key;
        let data = {
          index,//所處的鍵,方便定位到tag
          data: that.$data,//頁面數據
          name: that.$route.path//路由名
        }
        commit('updateTags', data)
      } else {
        let data = {
          name: that.$route.path,
          data: that.$data
        }
        commit('addTags', data)
      }
    },
    /*
     *從vuex更新頁面的數據
     *that 頁面this
     */
    cacheDataInit({ commit, state }, that) {
      let key = that.$route.query.key;
      let datashow = state.tags[key].data;
      commit('cacheDataInit', { that, datashow })
    }
  }
}

 

調用

調用剛開始想在全局直接調用,這樣就不用每一個單獨去寫了啊。然后發現route的全局守衛里面,beforeEach和afterEach這兩個內部都沒辦法使用this。我們內部是一定會調用this來賦值的。所以只能使用組件內守護。beforeRouteEnter(不能讀取this排除)、beforeRouteLeave、beforeRouteUpdate。

beforeRouteLeave:在路由離開之前觸發。那就可以在這個時候添加我們的tag了。

beforeRouteUpdate:在路由更新時觸發。這個時候是不是就可以讀取我們的緩存呢??完美

  created() {
    let status = this.$route.query.status;//根據status狀態來確認是正常的導航還是緩存導航
    if (status === 'cache') {
      this.cacheDataInit(this)
    } else {
      this.getData();//正常獲取數據
    }
  },
  beforeRouteLeave(to, from, next) {//離開之前調用添加tag方法
    this.beforeRouteLeave(this)
    next()
  },
  beforeRouteUpdate(to, from, next) {//路由更新時傳入進入和離開路由進行判斷
    if (!this.$route.query.status && to.query) {
      this.$route.query.key = to.query.key;
      this.cacheDataInit(this)
    } else {
      this.beforeRouteUpdate({ that: this, to })
    }
    next();
  }

tag導航

  <div id="scrollNav" v-if='tags.length'>
    <router-link :to="{path:tag.name,query:{status:'cache',key:key}}" v-for='(tag,key) in tags' :key='key' tag="span">
      {{_navName(tag.name)}}/*_navName是根據tag.name返回導航中文的方法*/
      <i class="el-icon-error" @click.stop="delTags(key)"></i>
    </router-link>
  </div>

 

寫完能跑起來了,就放心了。。。這都是什么鬼啊


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM