# ispn_vue **Repository Path**: mo__om/ispn ## Basic Information - **Project Name**: ispn_vue - **Description**: No description available - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 1 - **Forks**: 1 - **Created**: 2021-11-06 - **Last Updated**: 2022-01-03 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # ispn_vue ## 为什么采用vuex        考虑到即时通信的情况,多组件很多时候都需要共享数据,而vuex是集中储存管理所有应用的组件状态的一种技术,所以采用vuex管理共享数据,事实证明,这种通信软件对于数据的共享简直达到了极致。store是与后端通信唯一的通道,非常容易维护。 ## 为什么用了很多mixin文件        初衷是想用mixin文件进行不同的仓库(store)操作,写到后面发现我的操作和数据都是在仓库里,就导致了你会发现几乎所有组件里都没有数据和操作。        优点:更改和查看数据唯一通道,易于维护,同时可以不用在每个组件里重复编写一些获取仓库数据的操作,直接引入mixin操作即可,特别是写到writeSpan.vue获取点击id号时会感觉mixin真香,但要注意mixin文件里的属性不要重名,否则一个组件引入多个mixin属性重名会导致引入有误        缺点:易读性变差,组件内的操作方法没有在组件里,需要到mixin文件中进行查看,为此我特别在所有组件里的mixin操作都进行注释,增加可读性。同时mixin属性名的变化会需要在所有组件里更改。注意:钩子函数不要写进mixin里,多组件引用时会导致难以控制的错误。(比如可能这个create()是给这个组件的,但是写到了mixin里了另一个组件在引用时会调用这个钩子函数发送难以预测的错误) ## 功能实现思路 #### 基本路线        组件.vue调用store的action方法去访问api,api去mock拿数据回到各自的store后把自己的state更新,组件.vue去拿数据更新自己,切记,minxin只是方便的手段,不是必须的,minxin的代码可以写到各文件中,见 “为什么用了很多mixin文件"        最简单看懂代码文件路径:leftFriendList.vue里的数据是怎么来的->然后去看store文件夹下的mixins下的userListMixin.js->modules下的userLis.js(即仓库)->api文件下的对应api->mock文件夹下的services下的userList.js        为了便于维护,稍微一般的地方都进行了大量注释,请结合注释阅读,大部分功能实现都依照这个思路,更复杂的js逻辑需要结合源码结合注释进行阅读 #### 输入功能      基本设想,后端无法提供数据,若有后端可以将输入框的内容先传到后端,再从后端拿到所有聊天数据,再进行渲染。为了模拟这种情况,可以将新输入的数据上传到localSrtroage,再从localStroage中提取渲染。    难点:        1.如何将不同聊天输入框对应不同的stroage。               可以通过每个不同好友的id对应不同stroage的键值去获取        2.如何在输入框获得当前聊天好友的id               好巧不巧,我在currentRecordMixin中写了当前面板好友的id(其实是我后面加的),然后直接引入mixin拿到当前聊天好友id就可以匹配不同stroage        3.存取在stroage里要怎么实现字符串数组拼接 用数组的concat方法强制打平,每次都添加新的字符数组        4.之后在聊天面板想要提取id然后渲染,遇到问题就是v-for渲染时key值就是与上面的li数据库提取数据时Key值会重复,我用了+100详看源码解析        5.然后我本来是用计算属性想去监视localstroage去实现vue的实时渲染更新,但发现计算属性无法监视深层对象,然后又想用watch去深度监视,但是没法获得Id,最后决定写一个store存当前id号的新输入数据,然后聊天记录面板再来这里提取数据,就可以实现实时更新啦,也就是利用了computed监视store的变化而不是localStroage这个对象的变化。Send时去commit,初次加载面板也会有update去刷新当前切换的聊天对象的聊天记录,回过头发现原来设立的localStroage库会这么有用 #### 好友列表        初次加载在组件的钩子函数调用时调用action去访问数据拿到store然后getters去根据搜索框输入词实时匹配出getter给list组件去渲染 #### 点击不同气泡跳到不同界面        列表每个item即不同的人被点击后method方法把这个item.id传到仓库的action方法拿这个id去访问后端拿回来聊天面板所需的一切东西放到currentRecord仓库,不同的组件再去仓库取,详见下图 ![在这里插入图片描述](https://img-blog.csdnimg.cn/eded2978204b4a5e9cf29ef5efb600a2.png?x-oss-process=image/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBAfuelnuS7mX4=,size_20,color_FFFFFF,t_70,g_se,x_16) ![在这里插入图片描述](https://img-blog.csdnimg.cn/c93e7097692e46e1a89729e96eab739f.png) #### 不同聊天框和气泡堆叠        列表每个li也即item被点击时向methods的changeCurrent方法传递自己的id,然后去currentRecord仓库的action方法去拿这个和这个id的聊天记录存到state里,这个currentRecord仓库只存当前聊天界面的聊天记录对方头像和姓名,然后组件会去渲染,渲染的逻辑基本是类名加不加的一些逻辑,我觉得写的挺好,但是可以封装到另一个组件中,才不会html里都是js逻辑。 #### 所有好友列表功能和进入聊天功能        最开始的一级路由区分个人信息竖条右边到底是聊天部分还是朋友圈,二级路由区分列表和面板是聊天好友部分还是所有好友部分,用了路由同级展示多个组件页面,搜索框是在二级通用的,keyup后会同时把输入框的内容传到两个列表的仓库去给getter用,进入聊天功能其实就是把路由路径换了,详见下图 ![在这里插入图片描述](https://img-blog.csdnimg.cn/7486e9d126cd4f8e942d08396b0b2caf.png?x-oss-process=image/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBAfuelnuS7mX4=,size_20,color_FFFFFF,t_70,g_se,x_16) #### 所有好友列表功能和进入聊天功能        其实很简单,脑子突然有了这个创意,点击申请好友或者send后,设置一个定时器,里面的方法是去改mock的对象数据或者往本地储存里加数据,然后再调用两个仓库的一些方法去action,就会再次渲染。 #### 动画 ##### 动画1.0        切换路由时,新界面的进入动画和旧界面的退出动画会同时播放,为了避免这种情况,我特地利用了v-if的切换动画特性,过程为先给路由页面设置动画时,有两个div,一个是真的要展示面板,另一个是假的空的。        当点击一个路由以后,会先改变仓库的move为false,然后这时候有个计时器,在这个计时器到时之前,list和span会执行退出动画,这时候有两种情况,一种是第一个计时器时间够长,执行完退出动画以后空的list和span会进入,另一种情况是计时器很短,空的进入动画甚至退出动画还没播放完,计时器到时间,路由切换,这个时候move依旧还是false,新路由界面的空list和span会播放进入动画,第二个计时器在这个时候开始计时,如果第二个计时器时间足够长,那么空list和span有足够的时间进入并杵在那里,直到第二个计时器到时间,如果第二个计时器很短,那么会还没进入move马上变为true,空面板退出执行真面板进入动画。如果没有第一个计时器退出动画会没有,没有第二个计时器会没有进入动画。第一个计时器太短会导致退出动画来不及播放,第二个倒是不会,所以可以疯狂压榨,其实两个计时器的时间就是空白面板的时间,只有这两个足够短,才能最大限度减少空白时间。        之后加了一个朋友圈的动画和搜索框的动画,当在聊天列表和朋友列表切换时搜索框的动画不会收到路由切换的影响,相当于recordName在切换,但是点击朋友圈后搜索框甚至整个路由页面都会没有掉,就相当于点击朋友列表时recordspan的外div会瞬间没有,所以它的leave动画时间必须小于路由切换的时间才不会出现瞬间消失,因此我甚至使用了两个clock,当点击朋友圈路由时,我设置了更长时间的clock以便退出动画有更完整的播放。 ##### 动画2.0         假如没有v-else,那么不需要一个空白面板的进入和退出,动画会更快,第一个计时器只要负责动画退出,第二个计时器甚至没了意义,appear在于只是第一次出现时即刷新页面时有效,后面就会不用appear了,不需要mode=out-in,因为没有了另外的else但是左边列表因为是直接在transition里所以关键是切换路由时一定要让第一个clock慢一点,否则会切换到另一个路由时旧列表还没退出完毕就会同框卡住。第二个时钟的意义还在于路由切换需要时间,如果在朋友圈或者全部好友列表刷新页面再点击聊天列表会看到朋友圈先退出想再进是因为第二个时钟如果没有的话,路由切换还没完成但是moveIf被设为了true,它想再进,就在这时路由切换好了,新界面再出来就会卡住。        这样一来动画留白减少百分之50,渲染速度提升百分之50,流畅度提升百分之50