【vue3+pinia】为了取悦前台小姐姐,我简单做了个撤销重做功能,结果......😭
事情是这样的
作为一个20多年母胎solo的☀阳光新青年,在这20多岁的年龄段,每隔一段时间都难免会感受到孤独寂寞的感觉🆒。
特别是作为一个程序员,每天面对的不是代码就是代码,在这种长期隔绝两性交互的情况下,我有时候甚至觉得,我眼前跳动的代码,有时候也眉清目秀起来。
所以为了抑制我这种想法,我必须时常觅寻小姐姐聊天,这种需求前提下,在聊天的时候更多是我主动取悦小姐姐(这是我应该做的)🐕。
最近喜欢和前台的一位小姐姐聊天,这位小姐姐是个很特别的人,怎么特别呢,就是那种你一看上去就很特别的人,今天早上刚到公司,就看见她在工作了,刚想上去打招呼,发现不对,只见她眉头紧锁,难道是有什么烦心事吗?
是轮到我出马的时候了!一个箭步我就扑上去,立马开始暖男模式,一顿关心之后,发现原来是被公司的低代码系统烦到了。
什么!一个可视化操作的系统竟然没有撤销重做功能!还烦到我的女神!罪不可赦!
为了让女神继续开心,我拍着胸口说,放心,交给我!
说干就干
既然打包票了,那么就开干吧。
思路:在可视化的操作下,记录操作变化前后的数据,利用下标选定当前的数据进行展示,撤销则-1,重做则+1
公司的低代码项目是一个vue3
+pinia
的项目,我花了几分钟的时间去了解技术和项目就开始敲代码
功能原理
整个功能的设计原理,用技术方式来说就是,状态管理下数据的时间回溯功能,用大白话来说就是,一个数组记录数据,根据下标来取。
整个图展示一下数据的过程
看得懂吗?看不懂,没关系,来写代码
import { defineStore } from 'pinia'
import { ref } from 'vue'
export const useDesign = defineStore('test', () => {
// 快照栈堆
const queue = ref([])
// 栈堆下标
const pointer = ref(0)
// 栈堆的限制
const LIMIT = 30
// 记录功能
const record = () => {
// do something ...
}
return {}
})
简单的创建一个pinia
模块,三个变量分别是用来记录数据的数组queue
、记录下标的pninter
以及数组长度限制LIMIT
,这个限制是用来限制记录的次数的。
接下来实现record
的功能,那么我们先构思一下,怎么去写这个功能,这个功能是干什么的。
按照上面的思路,这个记录功能包括,将数据写入数组,LIMIT限制的控制,以及撤销后数据的控制(时间悖论)
时间悖论是什么?就是比如A回到过去,在A的祖父结婚前杀死祖父。既然A的祖父已死,就不会有A的父亲;没有A的父亲,也不会有A。既然A不存在,就不可能回到过去,杀死A的祖父。
大家明白了吗,我讲得这么明白,如果还不明白,那就看下面的图。
简单来说就是喜新厌旧💯。
const record = (data) => {
// 如果当前的下标不是在最新的时间点,那么证明用过了撤销功能,那么新开一条时间线
while (pointer.value < queue.value.length - 1) {
queue.value.pop()
}
pointer.value++
queue.value.push(data)
// 如果超过限制,那么把数组第一个元素去掉
if (queue.value.length - 1 > LIMIT) {
queue.value.shift()
}
}
啪一声,很简单,记录的功能就写完了。
既然解决了整个功能里面最复杂的部分,那么其他两个很简单,也直接上代码吧。
// 撤销 下标-1
const undo = () => {
--pointer.value
return queue.value[pointer.value]
}
// 重做 下标+1
const redo = () => {
++pointer.value
return queue.value[pointer.value]
}
这两个功能很简单,就是根据操作返回对应时间点的数据快照。
下面给上整个模块的完整代码
import { defineStore } from 'pinia'
import { ref } from 'vue'
export const useDesign = defineStore('design', () => {
// 快照栈堆
const queue = ref([])
// 栈堆下标
const pointer = ref(0)
// 栈堆的限制
const LIMIT = 30
const record = (data) => {
while (pointer.value < queue.value.length - 1) {
queue.value.pop()
}
pointer.value++
queue.value.push(JSON.parse(JSON.stringify(data)))
if (queue.value.length - 1 > LIMIT) {
queue.value.shift()
}
}
// 撤销
const undo = () => {
--pointer.value
return JSON.parse(JSON.stringify(queue.value[pointer.value]))
}
// 重做
const redo = () => {
++pointer.value
return JSON.parse(JSON.stringify(queue.value[pointer.value]))
}
return {
record,
undo,
redo,
}
})
接下来我们就可以在项目中使用这个pinia
的模块了
现在main.js
注册pinia
import App from './App.vue'
import { store } from '@/pinia'
const app = createApp(App)
app
.use(store)
.mount('#app')
export default app
编辑页面文件test.vue
<script setup>
// 引入模块
import { useDesign } from '@/pinia/design'
// 注册
const useDesignStore = useDesign()
// do something
</script>
这样子这个功能就完成了。
功能的一些细节
什么时候需要用record
功能,这样子就要看大家系统对撤销和重做功能的颗粒度把控,有些需要在修改文字也要控制,有些只需要在增删改查控制。
程序员只是写程序的,怎么用功能当然是产品的事。
最后结局
我发布了这个功能之后并告诉了前台小姐姐。
得到了小姐姐的认可,她非常的开心,我所做的一切都是值得的。
既然得到了认可,那么我再大胆点,约她出去吃个晚饭,顺便请她吃个雪糕,然后看个电影,嘿嘿。
心想,饭也吃了,电影也看了,总不可能让我回家吧。
结果!!!
啊!!!原来一切的一切,都是我的一厢情愿。
就这样吧,我还是和我的代码一起过算了。
转载自:https://juejin.cn/post/7219189380807000124