1.需求:微信内置浏览器,5分钟跳出收藏提示,点击任意位置提示消失。
目的:提高用户留存。
封装一个WxCollect公共组件,用到了utils中的微信判断,localStorage的存/取函数。
定时器,local存储wx_collect标记,弹出后wx_collect一直为true。
遮罩层:外部的div,z-index比较高,使其遮在最上面。外部的点击函数,改变v-if的值。
2.需求:浅色模式和暗黑模式的主题切换。
目的:优化用户体验。
user的设置组件中,调用公共的主题切换类,中的点击函数。
在主题切换类中,点击函数调用了设置函数,并传递参数value(light/dark)。
设置函数中,通过原生js(const el = document.getElementsByTagName('html')[0];)拿到第一个html标签(<html></html>),classList.remove(this.value)把类移除, classList.add(value)添加新的类。然后把主题的值放到local中,下次改变再覆盖这个值。
light不用设置,是默认的。
dark的话,在assets文件夹添加一个dark.css文件,html.dark{ } 里面定义全局变量,比如--White1。
在main.ts引入这个css文件。
element的暗黑模式也引入了,这里自己定制了一些具体颜色等,放在html.dark覆盖了element的部分样式。
3.需求:后台,信息模块,点击用户/角色id,跳转到用户/角色模块,并获取指定id的查询结果。
目的:优化后台使用体验。省去了手动复制,再点击查询的步骤。
在信息模块拿到id,通过this.$router.push跳转路由,到用户/角色模块。路由末尾包含id。
在用户/角色组件中,通过const id = this.$route.query.id,拿到url的id。
用户/角色模块,用到了公共的page-table组件。
page-table组件中,有一个对象,以及设置对象的方法。
在用户/角色模块,调用设置对象的方法,设置这个对象,设置成只包含一个id,查询,刷新,从而获取查询结果。
4.i18n国际化多语言支持,main.ts中import然后use之后,{{$t('x.y')}},x和y是配置的。
5.滚动加载,InfiniteLoading在组件中import,然后使用这个组件。@infinite事件,绑定自己定义的函数。
6.自定义样式,覆盖element组件库。
在assets下建立.css文件,比如:
.el-button--primary{
background: var(--Blue1);
color: var(--White4);
}
定义样式,覆盖原来的。
在main.ts引入这个css文件。
7.埋点
目的:统计用户各种事件等,进行数据分析。
数据库:clickhouse,列式存储。(mysql,oracle属于行式存储)
自定义指令:点击事件用v-click-trace,曝光用v-show-trace。自定义指令全局注册(定义时调用了traceManager的类)。
后端交互等:traceManager的类,里面constructor定时器4秒,每隔4s看一次,用到类的post传一次,发一次请求。传之前清空。
用trace多个对象压到一个list数组里,把list存在本地。
比如:trace({key:value});
优化
最开始是每次触发到埋点,都发一次请求。登录,可能请求发不出去,直接刷新了。
压缩成list,然后存在本地,隔4s发一次。
1.保证了每次都能监控到。2.压缩成list,减少了请求数,优化了一些性能。
8.流式回复
sse:Server-Sent Events服务器推送事件。
通过sse-ts这个npm包,来进行sse(小程序不支持,用的websocket)。
定义一个方法,传入角色id,用户输入的消息,重新发送,灵感对话,以及,message函数,error函数,done函数,instruct函数。
message函数
eventSource.addEventListener监听到message,通过onMessage的content(新增的内容),传到handleMessage的message中,传到answerAppend的message中,传到 lastMsg.reply += delta。
用户发出新消息后,会在addInput中,将lastMsg放到msgs数组的开头。
监听msg.reply,传入setText作为answer,在updateRuntime中,answerRuntime是answer的一部分,通过定时器调用自身,进行添加字数的流式回复。
instruct函数
敏感词之类的。
输入敏感直接弹窗。
回复敏感就回退,随机回复一句话。
//SSE来自sse-ts库。
//url是接口地址。
//sseOptions中有method(可能是POST),payload接口传入数据(POST的话有传入)。
const eventSource = new SSE(url, sseOptions);
//监听事件,默认是message(回复的信息),可以error错误,close关闭
eventSource.addEventListener('close', function(event){});
//启动流
eventSource.stream();
9.消息列表
1.停止
通过SSE.close()这个api进行关闭。
前端显示
发送是send函数,send中有doPost,doPost有req.cancel,将req给request。
点击取消,会执行request的cancel,即为req的cancel。
req的cancel中,有close和answerCancel,answerCancel会在所有消息中,删除这次问和答。并且重置回复的消息。
因为每次问新消息之类的,都会重置回复消息。
2.切换角色,再回来会显示
切换角色时,后端消息继续接受,前端只显示到,上次显示出来的部分。
当前这条消息,每次更新拼接之前,都要通过isReqActive判断:这条消息的角色id,和当前页面的id是否一样。
正常一样的话,才会继续打字机式回复,否则不再更新。
第一次点开的角色,或者切换的角色,消息列表会重新刷新,触发restoreStatus,拿到:上次用户的输入框输入,和最后一条未回复完成的消息。
3.最新消息如何存在服务端
不管前端是否渲染完,后端只要确定拿完整条信息,就在后端中放到消息列表。
10.官网
网址:根据window对象的网址,,mounted中使用不同的config配置。
图片:2个v-if。type如果是swipe,进入滑动组件,遍历imgs。big/small则动态img(:src)。
样式:动态class,根据type和screen等。全部遍历,通过媒体查询,移动端用display:none隐藏screen-pc图片。