vue-virtual-scroller
star 数:10346
npm 下载量:260944
npm 上次更新时间:2022-10-18
GitHub:Akryum/vue-virtual-scroller
star 数:10346
npm 下载量:260944
npm 上次更新时间:2022-10-18
GitHub:Akryum/vue-virtual-scroller
在 Vue 3 中,有一个需求,想要通过判断用户是否传入事件处理函数,如果传入事件处理函数证明点击事件需要被处理,来决定是否给元素添加 pointer 的样式,因此我们需要有一种方式能访问到传入的事件处理函数。
在看 Vue 源码的时候我们知道其实本质上事件处理函数也是挂载在 props
上的,因此我尝试直接通过 $props
去获取,结果发现并无法获取,结合之前看的源码,props
本质上也是一个 Proxy,在这个 Proxy get
的时候会去判断这个属性是否显式地在 props
上定义,如果是的话才会返回,否则就不返回,直观的表现就是无法访问到这个属性。很明显我们是通过 defineEmits
去定义的事件,因此 props
这个 Proxy get
的时候并不会将事件处理函数返回。
本质上就是通过判断某个时机来去修改样式,实现方案就分解成:时机、修改样式这两个问题了。
常见的方法有:
媒体查询
/* 系统设置浅色模式 */
@media (prefers-color-scheme: light) {}
/* 系统设置深色模式 */
@media (prefers-color-scheme: dark) {}
通过媒体查询可以获取到系统当前的设定,从而直接修改对应的样式。
在支持 css 变量的浏览器环境中,更常见的做法是通过媒体查询动态地修改 root 下面的 css 变量,然后具体的组件样式使用 css 变量来作为样式值,这样可以将样式都收拢到一个地方,方便维护。
这个方法的缺点是,浅色模式和深色模式会跟着系统设置来,并没有办法由用户手动地去切换。
data set + css 属性选择器
我们可以通过元素标签上的 data set 存放一些属性,自然也可以在根元素上去定义一个 data-theme 属性,属性值可以是 light 和 dark。
在用户第一次进入页面的时候,可以通过 window.matchMedia('(prefers-color-scheme: dark)').matches
来获取系统当前的设置,为 data-theme 属性配置一个默认值,然后通过 css 属性选择器来定义 css 变量,和上面的方法一样实现深色模式。
这个方法的好处是 data-theme 这个属性是可以由 js 修改的,我们可以做一个按钮或者选择器来给用户手动切换与自动跟随系统,这个也是现在许多系统都有提供的功能。同时由于有了 js 的加入,我们也可以将这个值记录在 localStorage 这种持久化存储里面,记录用户上次的使用习惯,在用户再次进入页面的时候就取出来,而不是通过媒体查询去查询了。
在我们开发过程中,有些时候会遇到容器内添加元素的需求,一般往下添加是没问题的,但是当我们有在运行过程中动态往上方添加元素时,就会发现不同浏览器有不同的行为。很常见的一种场景就是消息列表向上滚动加载的场景。
这一段代码可以模拟这种case:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div id="container" style="display: flex; gap: 10px; flex-direction: column;">
<div style="background: red; height: 100px; width: 100px;"></div>
<div>bottom</div>
</div>
<script>
const container = document.getElementById('container')
setInterval(() => {
const div = document.createElement('div')
div.style.background = 'red'
div.style.height = '100px'
div.style.width = '100px'
container.insertBefore(div, container.firstChild)
}, 300)
</script>
</body>
</html>
在使用类似 vuepress 等静态站点生成库时,我们经常需要通过编写 markdown 文件中的 frontmatter 来标识一些功能与文章的属性。每次需要手动编写 frontmatter,或者从旧的文档 cv 过来,是比较低效的行为。因此是否可以通过一些方法来提升写文章的体验,更加高效开搞?
针对在平时开发工作中这种重复 cv 的情况,我们的解法一般都是使用代码片段来提效。我将这个思维也复制到了 markdown frontmatter 上。我可以通过编写一个 snippet 来快速地生成所需的 frontmatter。
body {
/* 需要滚动的容器再添加 overflow: scroll */
overflow: hidden;
}
组内在搞前端工程化提效相关内容,VSCode 插件也属于其中的一部分,因此最近在学习如何写 VSCode 插件。
在阅读了官方的文档后,发现 VSCode 插件有许多可以支持的功能:
在上述功能中,我们一眼就看到了实际用于提效的功能,也就是对编程语言的功能扩展。这其中也包含了两个方向:Declarative language features(声明性语言功能)、Programmatic language features(编程语言功能)。前者是一些通过配置项实现的功能,后者是一些通过实际代码实现的逻辑,各有适用的场景。
公司内部的日志系统使用的是 ELK 框架,即 ElasticSearch、Logstash 和 Kibana 三个开源组件结合使用,完成更强大的用户对日志的查询、排序、统计需求。一般这套框架上还会使用 Filebeat 这个组件用于监控日志的变化,并传给 Logstash 这个管道。
流程是:Filebeat 监控日志变化并收集日志,通过 Logstash 这个管道上报到 ElasticSearch 中,最终通过 Kibana 展示 ElasticSearch 中的数据。
我这边是前端开发,因此需要关注的点主要在日志的收集与上报这块,这一块是和后端不一样的,后端使用了公司集成的开发框架即可实现开箱即用的日志上报功能。前端侧这边在公司的大前端部门也有提供对应的日志与埋点上报 SDK watchdog
。
项目结构:Vue2 与 Vue3 共存的组件库,采用 pnpm workspace Monorepo 方式组织仓库。
由于项目中有 Vue2 与 Vue3 的组件,因此需要搭两套文档,Vitepress 与 Vuepress2+只支持 Vue3 的宿主环境,Vue2 的组件库文档只能使用 Vuepress1.x 搭建。
依赖这块,package.json 中以 vue3 为主,vue2 通过别名的方式安装与引用。
//package.json
{
"devDependencies": {
"vue": "^3.3.4",
"vue2": "npm:vue@2.7.15"
}
}
// 用于匹配是否被 i18n 块包裹
const i18nKeyPattern =
/(?:i18n(?:-\w+)?[ (\n]\s*(?:key)?path=|v-t=['"`{]|(?:this\.|\$|i18n\.|[^\w\d])(?:t|tc|te)\()\s*['"`](.*?)['"`]/gm
const str = "$t('当有效期结束时间到了,是否直接下线?')"
// Array(2) ["$t('当有效期结束时间到了,是否直接下线?'", "当有效期结束时间到了,是否直接下线?"]
i18nKeyPattern.exec(value)
// null
i18nKeyPattern.exec(value)
// true
i18nKeyPattern.test(value)
// false
i18nKeyPattern.test(value)