zoukankan      html  css  js  c++  java
  • 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>

    写完能跑起来了,就放心了。。。这都是什么鬼啊

  • 相关阅读:
    使用Wireshark 抓取数据包
    React Native 开发之 (07) 常用组件-View
    Swift开发之 (01) 语法
    React Native 开发之 (05) flexbox布局
    React Native 开发之 (06) JSX
    深入浅出Redis02 使用Redis数据库(String类型)
    React Native 开发之 (04) 例子讲解
    npm命令大全
    npm
    node.js
  • 原文地址:https://www.cnblogs.com/axl-study/p/9884405.html
Copyright © 2011-2022 走看看