前言
自己去写一套mvvm框架(库|解决方案),意义仅在于面试时有谈资吗?
上一次面试时聊到我的mve如何实现动画,因为我的mve是实时操作dom的,不像vue有那么多便利的生命周期。
我一直沉醉于自己发明mve的美妙形而忘色,还没有卷到这一层呢——本来我关注UI的初衷就是苹果系统的动画多么美妙。但沉醉于编程中,却难再想起这档事。
外行看热闹,内行看门道。做事的人常常忘记初衷:仍然是获得别人那般的热闹感。只是做事需要门道,转而关注门道的美感,哪知外行看起来美丽的东西,内部可能是东拼西凑的;而关注内核的小而美,对于外行又常常是丑陋难用的。
我只是一再重复自己的mve是实时操作到dom上去的,不像vue/react有一种异步在里面。没想到去直接说,和jQuery是一样的。
我之前其实也少量研究过动画,感觉css动画虽然美妙,但脱离js的统一完备语言。动画像图片一样,只是一种视觉欺骗,跟业务完全无关。而现实中的物体变动,是因为它们变动必须遵循这样的物理轨迹,电脑里只是为了艺术效果来强行模仿,是一种画蛇添足行为。但是用户就吃这一套啊。
我研究的仍然是逻辑动画,即通过requestAnimation,逐渐将模型值变化到最终结果,它所绑定的元素属性(如位置),便也逐次变化形成动画。
面试官又提了先移动到具体位置计算到终止值,再实施动态变换。大概css动画的本质也是这样的吧。dom的布局已经不是简单的绝对布局可以提前计算。但是过于关注具体元素,mvvm的模型是操纵一批元素。
昨天又看了vue的内置动画组件,大而全的东西是不一样,不过我提供的是小而美的东西,尽量不夹带私货,除解决的核心mvvm问题外,都让用户自己回到原生的html去寻找解决方案。
那么mve里如何实现动画呢?还是用css动画吧,毕竟还有GPU支持。
所有mv*框架似乎都要去实现一个todoMVC( todomvc.com/ ),我也实现了一个,不过目前还在我的dom包里(演示地址 wy2010344.gitee.io/mve-vite-de… 仓库地址 gitee.com/wy2010344/m…
感叹自己的mve写起来换行还是比别人多。不过多是难免的。别人的少是将复杂度隐藏起来了,而且别人还是弱类型。
回到正题:一个简单的todo,动画也是明确的,像iOS的TableView,增加时的动画,和删除时的动画。
增加的动画想一想挺简单的,因为只要设置好对应的transform属性,改变对应属性,就会形成动画。
但是删除动画,因为ArrayModel::remove直接就删除了,我们必须让动画结束时才真删除,之前都还得在界面上。这就需要setTimeout,绑定的动画时间和setTimeout的时间一致(这个应用在setTimeout的时间常量得绑定在transform属性上)
为了不大改,决定将记录组件变成position:relative,这样改变它的left值,就能形成动画。增加是从左边进入列表,删除是从右边退出列表。
先看一下效果
怎么实现的呢?
初始准备
先定义一个动画时间常量,这里定义0.5s
然后给记录组件增加简单的动画
上图其实已经包含一些其它信息,比如我们在todo的记录里定义了一个state的模型
初始化为init,默认是null,销毁是变成destroy。这样刚渲染完成时由于state是init,它的left是-100%,然后立即将state变成null,组件执行left:-100%到left:0的动画。必须设置默认0,这是css动画的规则,不再赘述。
初始动画
但是初始化为state为init,立即变成null,动画效果是没有的(我经过实验得来,大概还是得等这个宏任务完成),所以得这样写:
通过setTimeout,到下一个宏任务去执行属性变化,执行动画(有更好的方法吗?)
销毁动画
初始化动画简单,动画什么时候执行完可以不用管,但销毁不一样,需要在animateS秒后执行对组件的删除。
其实也不是很复杂。
简单的mve的动画就是这样。
如果你的好的想法,希望给小议提出意见或建议。小议知识所限,只是在这里抛砖引玉。
没有你的创造,世界将会少一分精彩。
附录
欢迎使用小议的mve。它包含mve-core与mve-dom两部分,前一部分与dom无关,可自定义其它引擎,后一部分是mve-core在dom上的简单桥接。
git地址
文章包地址:gitee.com/wy2010344/a…
demo地址:wy2010344.gitee.io/mve-vite-de… ( gitee.com/wy2010344/m… )
mve-core:
gitee : gitee.com/wy2010344/n…
github : github.com/wy2010344/n…
mve-dom:
gitee : gitee.com/wy2010344/n…
github : github.com/wy2010344/n…
特点
- 过程式(函数式)基因,比react更早。作者避免在ts/js中使用class/this等概念。
- 无组件概念,完全使用编程语言本身的模块(函数)复用。
- 基础模型只有mve.Value (类似vue的ref而不是react的useState) 和mve.ArrayModel,构建出庞大的页面逻辑。
- 界面布局使用纯ts/js,不引入复杂的xml,更高效地复用。
- mvvm对属性节点针对性更新(受vue启发),性能高。并创新地发现使用mve.ArrayModel与界面片段一一对应(支持同级嵌套),不使用虚拟DOM与任何形式的享元复用,和异步更新。
- 区分与DOM引擎无关的核心模块,可用于其它自定义引擎。并提供简单的dom桥接模块。
- 开放可定制自己的mve使用方式。
创作不易,如果给你带来帮助,欢迎给作者打赏。
微信
支付宝
