Vue.js 轻松实现页面后退时,还原滚动位置

2017-06-12 07:14:29 +08:00
 1340641314

前言

Vue.js 2.x发布之后,陆陆续续做了七八个项目,摸索出来了一套自己的状态管理模式,我将之称为Vuet。它以规则来驱动状态更新,它带来的是开发效率上的飙升,它就像草原,而你是野马,任你随意驰骋,总之它是为敏捷开发而诞生。

缘由

在大型的 Vue 应用程序开发中,多组件通信、多页面通信,往往是跨不过的坎,一个页面组件中往往参杂着页面获取数据的代码和响应用户操作的代码,稍有不慎,就使得代码混乱不堪。A、B、C 三个页面中,都需要同样的数据,然后每一个页面都写一次、发送一次请求,不久之后,代码就十分臃肿了。因此我们就需要vuex这样的第三方库来管理状态了

Vuet 诞生初衷

从列表点击进去到详情,从详情返回后,我们期望能显示回原来的位置,而不是整个页面重新初始化,重新请求数据,这样带来的是用户体验的极度糟糕的,我们期望能有一种规则来定义状态应该如何更新,这便是Vuet.js诞生的初衷。它以规则来定义状态的更新,它也是一种 Vue.js 全新的状态管理模式。天生的规则驱动,使得本次教程的主题,也将变得异常简单,因为我们只需要定义好页面更新的规则即可实现。

有了 Vuex 还需要 Vuet 做什么?

Vuex 和 Vuet 的出发点不一样,Vuex 不建议直接更新状态,而是通过提交mutation来更新状态,而 Vuet 则是允许的。因此 Vuex 和 Vuet 是可以配合使用的,并且有着不同的应用场景,该用Vuex 的地方就用 Vuex,可用Vuet 的地方,就可以使用 Vuet

开始

上面废话了那么久,也是因为Vuet.js才刚刚诞生,急需大家的支持。嗯,接下来我们开始本次的主题!

目录结构

|-- pages                 // 页面组件
|   |-- topic             // 主题模块
|       |-- Detail.vue    // 主题详情
|       |-- List.vue      // 主题列表
|-- router                // router 相关
|   |-- index.js          // 入口文件
|   |-- router.js         // 实例化 VueRouter
|-- vuet                  // vuet 相关
|   |-- index.js          // 入口文件
|   |-- topic-detail.js   // 主题详情的状态
|   |-- topic-list.js     // 主题列表的状态
|   |-- vuet.js           // 实例化 Vuet
|- index.html             // 程序页面入口文件
|- main.js                // Vue 实例化入口文件

上面是我们本次项目的基本目录结构

安装模块

npm install vue vue-router vuet --save

这些都是基本的模块,想必不用多说,大家都知道的。

route 规则

先给出官方文档地址 本章的主题,核心就是在route规则身上,它能帮你获取、更新、重置页面的状态,配合v-route-scroll指令就能帮你处理页面的全局滚动条和 div 元素自身的滚动条

code 社区 api 为例子

  <template>
    <!-- 
        设置指令监听全局滚动条,
        注意了,光是设置指令可不行,还需要在组件中使用 route 规则,
        来处理页面滚动的操作,
        局部滚动条直接去掉.window 即可
        如果需要同时记录全局滚动条和 div 滚动条直接设置.window.self 即可
        它能做到 N 多个滚动位置记录,具体看官方文档喔!
        注:记录 div 滚动的话,需要设置一个 name 来识别
        v-route-scroll="{ path: 'topic-detail', name: 'xxx' }"
    -->
    <div v-route-scroll.window="{ path: 'topic-list' }">
      <header>
        <ul>
          <li v-for="item in list.tabs">
            <router-link :to="{ name: 'topic-list', query: { tab: item.value } }">{{ item.label }}</router-link>
          </li>
        </ul>
      </header>
      <ul class="list">
        <li v-for="item in list.data">
            <router-link :to="{ name: 'topic-detail', params: { id: item.id } }">{{ item.title }}</router-link>
        </li>
      </ul>
    </div>
  </template>
  <script>
    import { mapRules, mapModules } from 'vuet'
  
    export default {
      mixins: [
        // 设置模块的更新规则
        mapRules({
          route: 'topic-list'
        }),
        // 连接模块的状态
        mapModules({
          list: 'topic-list'
        })
      ]
    }
  </script>
  <style scoped>
  
  </style>
  <template>
    <div v-route-scroll.window="{ path: 'topic-detail' }">
      <h3>{{ detail.data.title }}</h3>
      <div v-html="detail.data.content"></div>
    </div>  
  </template>
  <script>
    import { mapRules, mapModules } from 'vuet'
  
    export default {
      mixins: [
        // 设置模块的更新规则
        mapRules({
          route: 'topic-detail'
        }),
        // 连接模块的状态
        mapModules({
          detail: 'topic-detail'
        })
      ]
    }
  </script>
  <style scoped>
  
  </style>

总结

咋的一看,Vuet 看起来也不是很复杂,只需要定义好模块状态,然后在组件中设置对应的规则来更新模块的状态即可。其实 vuet 自带的 route 规则能够支持同时记录全局滚动条、div 自身的滚动条,这样就能大大的提升了我们的用户体验

6625 次点击
所在节点    分享创造
13 条回复
yu7er
2017-06-12 08:01:46 +08:00
不错不错,vuex 应该是官方库。。
1340641314
2017-06-12 08:21:33 +08:00
@yu7er 是的
dnxbf321
2017-06-12 09:37:22 +08:00
可以用 vue-router 和 vuet 配合?
1340641314
2017-06-12 09:57:21 +08:00
@dnxbf321 可以和 vue 的全家桶配合使用,和 vue-router 配合,才能发挥 vuet 的全部潜力
del1214
2017-06-12 11:21:47 +08:00
自己也实现过一次,不过远没有楼主思考的深入,已 star
123s
2017-06-12 11:54:36 +08:00
单是你这个需求的话应用不大,刚刚才习惯 vuex 那一套,不想再搞新的。
1340641314
2017-06-12 11:59:06 +08:00
1340641314
2017-06-12 12:01:07 +08:00
@123s 这个其实只是 vuet 中的一小部分功能,它是可以很好的和 vuex 来配合的,具体的话,就需要自己来权衡了。近期有时间的话,会陆陆续续发布一些相关的教程
123s
2017-06-12 13:05:41 +08:00
@1340641314 必须有教程,现在前端一天就一个新的概念,累
natforum
2017-06-12 13:57:14 +08:00
贝爷打野归来已成大佬,而我还在原地踏步
1340641314
2017-06-12 14:00:38 +08:00
@123s 确实是,其实我也是因为一直没有找到合适的状态管理模式,所以才自己造了一套,希望能减轻开发的负担
1340641314
2017-06-12 14:00:54 +08:00
@natforum 哈哈,其实我也只是个小菜逼
shuimuyian
2017-09-09 21:26:42 +08:00
楼主是 "狼族小贝" 吗

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/367698

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX