前端每周学习分享--第12期
1.VuePress
大家看过不少Vue.js及其子项目的文档,一定发现了它们风格完全一致,界面清爽,读起来很舒服,它们都使用了vuepress。
VuePress是尤大为了支持 Vue 及其子项目的文档需求而写的一个静态网站生成工具,广泛用于编写技术文档 ,可以部署在github上做个人博客。
原理:
在构建过程中,会创建应用程序的服务器渲染版本,通过访问每个路由,来渲染相应的 HTML。
其中, 每个 markdown 文件都使用 markdown-it 编译为 HTML,然后作为 Vue 组件的模板进行处理。这允许你直接在 markdown 文件中使用 Vue,在需要嵌入动态内容时,这种使用方式非常有用。
十分实用的特性:
- md文件可内嵌vue代码
- 可自定义主题
- 利用service worker做离线缓存
- 多语言支持
- 基于git的最近更新
官方文档: https://vuepress.docschina.org/guide/#%E8%BF%90%E8%A1%8C%E5%8E%9F%E7%90%86-how-it-works
快速搭建: https://segmentfault.com/a/1190000016333850#articleHeader1
2.WebWorker
web worker是运行在后台的jacvascript,利用类似线程的消息传递实现并行,独立于其他脚本,不会影响页面的性能。
web worker能够长时间运行,有理想的启动性能以及理想的内存消耗。
worker 创建后,它可以向它的创建者指定的事件监听函数传递消息,这样该worker生成的所有任务都会接收到这些消息。
webworker有专用线程dedicated worker(单窗口专用),sharedWorker(可多窗口共享),以及后来的service worker(目前浏览器支持程度还不高)。
2.1.dedicated worker
使用方法:
worker线程里监听onmessage,
页面线程里创建worker对象:const myworker = new Worker("worker.js")
发送消息:postMessage(msg)
接受消息:onmessage = function(e){const msg = e.data}
msg的数据格式自行定义。
终止worker:myworker.terminate()
例如下面的示例,worker会接收页面上输入的两个数字,计算出乘积后返回结果。
worker.js
onmessage = function(e) {
console.log('Worker: Message received from main script');
let result = e.data[0] * e.data[1];
if (isNaN(result)) {
postMessage('Please write two numbers');
} else {
let workerResult = 'Result: ' + result;
console.log('Worker: Posting message back to main script');
postMessage(workerResult);
}
}
index.html里
const first = document.querySelector('#number1');
const second = document.querySelector('#number2');
const result = document.querySelector('.result');
if (window.Worker) {
const myWorker = new Worker("worker.js");
first.onchange = function() {
myWorker.postMessage([first.value, second.value]);
console.log('Message posted to worker');
}
second.onchange = function() {
myWorker.postMessage([first.value, second.value]);
console.log('Message posted to worker');
}
myWorker.onmessage = function(e) {
result.textContent = e.data;
console.log('Message received from worker');
}
} else {
console.log('Your browser doesn\'t support web workers.')
}
2.2.shared worker
共享进程可以连接到多个不同的页面,这些页面必须属于相同的域(相同的协议,主机以及端口)
在火狐中,共享进程不能在私有与公共文档间进行共享。
SharedWorker.port返回一个MessagePort对象,用来进行通信和对共享进程进行控制。
创建共享进程对象:const myWorker = new SharedWorker("worker.js");
获取端口:
发送消息:myWorker.port.postMessage(msg)
接收消息:myWorker.port.onmessage = function(e) {const msg = e.data}
worker线程获取端口:onconnect = function(e) {const port = e.ports[0]}
启动端口:port.start()
2.3.service worker
Service Worker 可以理解为一个介于客户端和服务器之间的一个代理服务器 ,常用于做离线资源缓存
出于对安全问题的考虑,Service Worker 只能被使用在 https 或者本地的 localhost 环境下。
暂时没有仔细学这块,可以阅读Service Worker —这应该是一个挺全面的整理。
参考文章:
3.代码相关
3.1.元素内文本垂直居中
已知元素高度的话,可以设置line-height:元素高度
.
如果元素高度未知,就不能使用line-height了。
有人会想使用line-height:100%
,会发现这是不行的,这个百分比是相对当前字体尺寸,而不是元素高度。
我使用了flex布局实现
display: flex;
align-items:center;
justify-content:center;
还可以设置padding来使文本看起来垂直居中
padding: 50px 20px;
3.2.微信小程序自定义placeholder的隐藏时机
在一个searchBar组件中,有一个自定的placeholder如下:
<!-- <view
wx:if="{{!inputValue.length}}"
class="placeholder" >
{{placeholder}}
</view> -->
原生的placeholder不是在触发bindinput时隐藏,而是在输入键盘按钮点击时。使用inputValue.length来判断显示自定义的placeholder会在某些输入法中导致拼音预览和自定义placeholder重叠(因为拼音显示的时候value值还没变)
最后选择弃用这个自定义placeholder,使用input组件的placeholder属性,并使用placeholder-class来设置它的样式。
3.3.关于微信小程序原生组件的坑
原生组件有camera、canvas、input (仅在focus时表现为原生组件) 、live-player、live-pusher、map、textarea、video、cover-view、cover-image。
所以当你用canvas画图表、使用地图、播放视频甚至做文本输入时,都是可能遇到相关坑点的。
- 关于原生组件、组件之间的层级关系、
原生组件的层级始终高于普通组件,不论普通组件的z-index设置了多少。
后插入的原生组件可以覆盖之前的原生组件。
原生组件之间的相对层级关系可以通过z-index来调整。
原生组件会遮挡vconsole弹出的调试面板。
cover-view和cover-image可以覆盖在部分原生组件上。
- cover-view的使用
cover-view在做地图、画布、视频上的弹出层时是会用到的,但它有很多使用限制。
cover-view只能内嵌cover-view、cover-image、button,其他元素在真机上就会被cover-view给覆盖住,如果想内嵌radio、picker等就只能自己用这3个可内嵌的元素来实现。
cover-view不支持iconfont,也不支持单边border、background-image
、shadow
、overflow: visible
等。
- input的使用
input在不聚焦时是占位元素,会被原生组件遮挡,聚焦时才使用原生组件渲染。这就会出现input设置了更高的z-index,不聚焦时仍会被其他原生组件遮住。
要解决这个问题,可以使用textarea来代替input。
我的一个解决方案是,加一个标志位来记录input是否聚焦,当不聚焦时,显示一个承载value值的cover-view(它需要绑定一个触发聚焦的点击事件),聚焦时,就显示input组件。
3.4.多个标签页之间的通信方案
-
使用websocket
-
使用localstorage或者cookie
-
使用sharedworker
我遇到的问题是需要在新窗口打开当前网站的新窗口时,能继承上一个窗口的vuex的状态树里的某些数据。这不需要和服务器打交道,最好就在本地。
最后使用localstorage来做,在跳转新窗口前更新localstorage,在新窗口根组件挂载时取出数据。