最常用的代码优化技术

博客代码 使用局部状态(轻量级状态)优化博客代码

上两篇介绍了如何用vite2 + Vue3 搭建一个博客站,以及轻量级状态的基础使用,那么二者结合起来会发生什么呢?做个开源博客学(xi)Vite2 + Vue3 (四)实现博客功能 制作一个轻量级的状态管理插件:Vue-data-state 回顾博客代码博客代码里面有三个列表:首页的博文列表、编辑博文里面的博文列表以及讨论列表。三个列表的写了三份代码,但是对比看一下就会发现,这三份代码大同小异嘛。其共同点就是:查询条件、分页要求、数据容器。那么是不是可以针对这几个共同点抽象一下,做成一个共用的函数呢?这个就需要用到轻量级状态里面的局部状态了。为啥一定要用状态管理呢?那是因为可以把不同的功能分布到不同的组件里面,而不用拘泥在一个组件内实现全部功能。比如把查询条件的表单放在单独的组件里面,这样可以简化列表组件的代码,更容易进行管理。定义用于列表需求的局部状态// store-ds/index.jsimport VuexDataState from ‘vue-data-state’// 设置全局状态和局部状态export default VuexDataState.createStore({ global: { // 全局状态 onlineUser: { // 当前登录用户 name:’jyk’ // } }, local: { // 局部状态 // 数据列表,使用前需要先注册 dataListState() { // 显示数据列表的状态 return { // 确保不会重复 findKind: {}, // 查询方式,仅容器,不用写具体的查询字段 find: {}, // 查询关键字,还是容器 page: { // 分页参数 pageTotal: 100, pageSize: 2, pageIndex: 1, // 其实主要是用这个 orderBy: { id: false } // 排序字段,可以写多个 }, _query: {}, // 缓存的查询条件,翻页的时候使用 isReload: false // 重新加载数据,需要统计总数 } } }, init(state) { // 初始化 }}) dataListState定义一个数据列表用的状态,局部状态的优点就是可以在“多套”业务组件里复用,而且可以保证局部状态不会相互影响,博文列表组件、讨论列表组件都可以用这个状态,而不用定义多个。findKind查询方式,这个只定义一个容器,具体的内容在后面的代码里面实现。find查询关键字,记录用户输入的查询内容。具体内容还是在后面的代码里面实现。Page分页信息,这里主要使用 pageIndex,其他的算是附赠吧,毕竟一般都是配套出现的。_query缓存查询条件,用户进行查询的时候需要记录查询条件,然后翻页的时候就可以直接拿出来使用了。缓存起来也便于确定需要哪些查询条件。init初始化状态,这个是给全局状态用的。MVC 的 Control然后我们可以借鉴MVC的思路,做一个control,控制model的加载、状态的变化等功能。建立一个 src/control 文件夹,统一管理相关的代码。// control/data-list.jsimport { watch, reactive } from ‘vue’// 状态import VueDS from ‘vue-data-state’// webSQLimport { webSQLVue } from ‘nf-web-storage’// 获取配置// eslint-disable-next-line import/no-absolute-pathimport blogListInfo from ‘/config/bloglist.config.json’/** * 数据列表的通用管理类 * * 查询条件 * * 分页信息 * * 加载数据 * * 注入局部状态 */export default function dataListControl (jsonFlag) { // 显示数据列表的数组 const _dataList = reactive([]) // 访问 webSQL const { help } = webSQLVue.useHelp() // 访问状态 const { reg, get } = VueDS.useStore() // 子组件里面获取状态 const dataListState = get.dataListState() // 父组件注册状态 const regDataListState = () => { // 注入获取列表需要的状态,便于查询、分页里面修改 const state = reg.dataListState() // 需要的配置信息 const listInfo = blogListInfo[jsonFlag] if (typeof listInfo === ‘undefined’😉 { // 没有设置对应的信息 return state } // 设置具体的查询条件和查询方式 state.find = listInfo.find state.findKind = listInfo.findKind state.page = listInfo.page // 重新加载数据 watch(() => state.isReload, () => { const _query = {} // 设置查询条件 for (const key in state.find) { const value = state.find[key] const kind = state.findKind[key] if (value && value.length > 0 && value > 0) { _query[key] = [kind, value] } } // 缓存查询条件,分页的时候可以直接使用 state._query = _query state.page.pageIndex = 1 // 显示第一页 // 统计总数 help.selectCount(listInfo.tableName, _query).then((count) => { // 设置分页 state.page.pageTotal = count }) // 获取数据 help.select(listInfo.tableName, listInfo.listCol, _query, state.page).then((data) => { _dataList.length = 0 _dataList.push(…data) }) }) // 翻页,依据缓存的查询条件,获取其他页号的数据 watch(() => state.page.pageIndex, () => { // 获取数据 help.select(listInfo.tableName, listInfo.listCol, state._query, state.page).then((data) => { _dataList.length = 0 _dataList.push(…data) }) }) return state } return { regDataListState, // 父组件注册状态 dataList: _dataList, // 父组件获得列表 dataListState // 子组件获得状态 }}虽然代码多了一点,但是这里处理好各种需求,组件里面就可以轻松使用了。读取配置信息 blogListInfo因为博文列表、讨论列表需要的信息都是不一样的,所以不同的信息都放在了一个json文件里面,这里用了vite2 的 import 方式读取,然后按照参数(jsonFlag)获取对应的信息。VueDS.useStore获取轻量级状态的注册等函数。子组件里面获取状态因为 vue 的 inject 必须在 vue 的 setup 的进程里面才可以获取,而在事件的进程里面无法获取,所以只好在这里先把需要的状态获取出来,如果是父组件的话,当然取不出来。regDataListState父组件注册局部状态的函数。从配置信息里面提取对应的信息,设置给 find、findKind、query。监听 state.isReloadisReload 主要针对查询需求,设置好查询条件后对 isReload 取反,就会触发watch,然后这里执行获取数据的操作。在线演示用的是webSQL,正式项目可以使用 axios 向后端申请数据。然后获取数据设置给 dataList。这里需要统计总记录数,而下面的翻页事件里就不需要统计总记录数了。监听 page.pageIndex这个是应对翻页的需求的。分成两个来监听,目的是区分要不要统计总记录数。如果数据量不大的话,统计总数没啥问题,每次翻页都统计一下用户也不会有啥感觉。但是如果数据量大的话,还是每次翻页都去统计一下总数,那么就太浪费性能了。所以这里做了一下区分,翻页的时候不统计总数,重置查询条件的时候才会统计总数。父组件的使用方法我们先来看一个简单情况,讨论列表的使用方式:

{{item.discusser}} ({{dateFormat(item.aTime).format(‘YYYY-MM-DD’😉}})


{{item.agreeCount}} 把分页和讨论的表单都分布出去做成了单独的组件,这样模板里面可以专注讨论列表的设置了。集中目标不分心。// 组件import { ref } from ‘vue’// 组件import discussForm from ‘../components/discuss-form.vue’import pager from ‘../components/pager.vue’// 数据列表的状态import dataListControl from ‘../control/data-list’// 日期格式化const dateFormat = dayjs// 组件的属性,获取博文IDconst props = defineProps({ id: String})// 获取注册函数和数据容器,const { regDataListState, dataList } = dataListControl(‘discussList’😉// 注册状态,设置博文ID为查询条件,获取博文的讨论数据。const discussState = regDataListState()discussState.find.blogId = props.iiscussState.isReload = !discussState.isReload怎么样?是不是很简洁。父组件里面使用首先引入 control/data-list,然后获取状态,根据需求设置好查询条件。最后别忘了使用 dataList 绑定模板。分页控件使用分页做成了单独且可以共享的组件,在组件里面可以直接获取局部状态,给 el-pagination 设置属性,这样就不需要父组件操心了。/src/components/pager.vue 获取状态,绑定模板。// 统一的数据列表的分页组件import { defineProps } from ‘vue’// 数据列表的状态import dataListControl from ‘../control/data-list’// 获取列表的局部状态const { dataListState } = dataListControl()翻页的时候页号会变化,触发 watch 的监听,从而实现翻页获取数据的效果。子组件的使用方法也是一样的步骤,只是不需要注册,而是获取父组件注册的状态,得到状态后,在需要的地方修改即可。这样组件里面的代码就非常简单了。比如上面那个分页组件。我们来看一下讨论表单的组件,模板部分就是一个普通的表单,跳过直接看js部分:import { reactive, watch } from ‘vue’// 数据列表的状态import dataListControl from ‘../control/data-list’// 表单管理import discussFromControl from ‘../control/data-form’// 获取讨论列表的状态const { dataListState } = dataListControl(‘discussList’😉// 表单管理const { discussModel, aNewDiscuss } = discussFromControl() // 日期格式化const dateFormat = dayjs// 组件的属性const props = defineProps({ id: String})// 发布讨论const submit = () => { discussModel.blogId = props.id aNewDiscuss().then((id) => { // 通知列表 dataListState.isReload = !dataListState.isReload })}先获取讨论列表的状态,然后发布讨论成功后,调用讨论列表的状态,从而触发讨论列表重新加载讨论数据。其他代码就不一一介绍了,感兴趣的话可以到 gitee 看源码。轻量级状态 vue-data-state轻量级状态已经发布到 npm ,可以使用yarn a vue-data-state 来安装。

本文内容由互联网用户自发贡献,该文观点仅代表作者本人。聚才发仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,请发送邮件至 tenspace2022@163.com 举报,一经查实,本站将立刻删除。 本文链接:https://www.jucaifa.com/post/67046.html 商机洞察 金融谷 前沿技术

上一篇 2023年10月30日
下一篇 2023年10月30日

相关推荐

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注