main.html如何控制后退,Vue.js轻松实现页面后退时,还原滚动位置

前言

从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-vuet-scroll指令就能帮你处理页面的全局滚动条和div元素自身的滚动条

code社区api为例子

main.js

import Vue from 'vue'

import router from './router/'

import vuet from './vuet/'

export default new Vue({

el: '#app',

vuet,

router,

render (h) {

return h('router-view')

}

})复制代码

vuet/index.js

import vuet from './vuet'

export default vuet复制代码

vuet/vuet.js

import Vue from 'vue'

import Vuet from 'vuet'

import topicList from './topic-list'

import topicDetail from './topic-detail'

Vue.use(Vuet)

const vuet = new Vuet({

data () {

return {

loading: true, // 请求中

loaderr: false // 请求失败

}

},

pathJoin: '-', // 父子模块的连接路径

modules: {

topic: {

list: topicList,

detail: topicDetail

}

}

})

vuet.beforeEach(({ path, params, state }) => {

state.loading = true

state.loaderr = false

})

vuet.afterEach((err, { path, params, state }) => {

state.loading = false

state.loaderr = !!err

})

export default vuet复制代码

vuet/topic-list.js

export default {

routeWatch: 'query', // 定义页面的更新规则

data () {

return {

data: [],

tabs: [

{

label: '全部',

value: 'all'

},

{

label: '精华',

value: 'good'

},

{

label: '分享',

value: 'share'

},

{

label: '问答',

value: 'ask'

},

{

label: '招聘',

value: 'job'

}

]

}

},

async fetch ({ route }) {

const { tab = '' } = route.query

const { data } = await window.fetch(`https://cnodejs.org/api/v1/topics?mdrender=false&tab=${tab}`).then(response => response.json())

return {

data

}

}

}复制代码

vuet/topic-detail.js

export default {

routeWatch: 'params.id', // 定义页面的更新规则

data () {

return {

data: {

id: null,

author_id: null,

tab: null,

content: null,

title: null,

last_reply_at: null,

good: false,

top: false,

reply_count: 0,

visit_count: 0,

create_at: null,

author: {

loginname: null,

avatar_url: null

},

replies: [],

is_collect: false

}

}

},

async fetch ({ route }) {

const { data } = await window.fetch(`https://cnodejs.org/api/v1/topic/${route.params.id}`).then(response => response.json())

return {

data

}

}

}复制代码

router/index.js

import router from './router'

export default router复制代码

router/router.js

import Vue from 'vue'

import VueRouter from 'vue-router'

import TopicList from '../pages/topic/List'

import TopicDetail from '../pages/topic/Detail'

Vue.use(VueRouter)

const RouterView = {

render (h) {

return h('router-view')

}

}

const router = new VueRouter({

routes: [

{

path: '/',

component: RouterView,

children: [

{

path: '',

name: 'topic-list',

component: TopicList

},

{

path: '/:id',

name: 'topic-detail',

component: TopicDetail

}

]

}

]

})

export default router复制代码pages/topic/List.vue

  • {{ item.label }}

  • {{ item.title }}

export default {

mixins: [

// 设置模块的更新规则

mapRules({

route: 'topic-list'

}),

// 连接模块的状态

mapModules({

list: 'topic-list'

})

]

}

复制代码

pages/topic/Detail.vue

{{ detail.data.title }}

export default {

mixins: [

// 设置模块的更新规则

mapRules({

route: 'topic-detail'

}),

// 连接模块的状态

mapModules({

detail: 'topic-detail'

})

]

}

复制代码

总结

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值