11月
27
将代码给到客户端的时候,有时候不想让源码被对方看到。就得使用加密的方式。这里尝试 Laravel Source Encrypter
https://github.com/SiavashBamshadnia/Laravel-Source-Encrypter
安装配置扩展
- 先去下载
phpbolt
扩展。对方提供了到 php8.2 的扩展,支持 win、linux、mac 的。
https://phpbolt.com/download-phpbolt/
打开上边的地址,输入您的 email 以及用户名,点击提交。他们会把文件下载链接发到邮箱里。下载出来就好。
- 安装 - 查看扩展的存放位置。 这里先尝试在 homestead 环境下安装。
# 查看 php 版本,了解当前的 php 版本信息
php -v
# 查看扩展的位置
php -i | grep extension_dir
# 这里是这样的
extension_dir => /usr/lib/php/20220829 => /usr/lib/php/20220829
sqlite3.extension_dir => no value => no value
- 安装 - 将 phpbolt.so 文件复制到该目录下。
# 在本地,将扩展文件放到映射的 code 目录下。方便移动。
cd /usr/lib/php/20220829
sudo mv ~/code/bolt.so ./
- 修改 php.ini 文件,重新启动。
php -i |grep php.ini
# 输出
# Loaded Configuration File => /etc/php/8.2/cli/php.ini
# vim 打开 php.ini 文件
sudo vim /etc/php/8.2/cli/php.ini
# 移动到末尾
GG
# i 进入编辑模式,加入下边的配置
extension=bolt.so
# 保存退出
:wq
# 重启 php-fpm
sudo /etc/init.d/php8.2-fpm restart
# 查看扩展
php -m | grep bolt
通过 php -m | grep bolt
的确是可以看见 bolt 扩展的存在。但是呢,如果通过 http 服务,访问获取 bolt,是没有看到 bolt 的信息的。这个时候,使用 bolt 的函数就会报错。如下。
Call to undefined function bolt_decrypt() in
其实, bolt 的扩展还没完。我们继续配置。
cd /etc/php/8.2/fpm/conf.d
sudo vim 20-bolt.ini
# 添加一下内容,保存退出
extension=bolt.so
# 重启
sudo /etc/init.d/php8.2-fpm restart
再看看 phpinfo
信息,这个时候就有了
安装和使用 Laravel-Source-Encrypter
扩展装好了,那么就要用在项目中。这里我新建一个新的 laravel 项目来搞。当前 laravel 版本是 laravel 10, php 版本是 8.2 。
composer create-project laravel/laravel bolt.com --prefer-dist
cd bolt.com
项目创建好了之后,就按照 https://github.com/SiavashBamshadnia/Laravel-Source-Encrypter 来就可以了。
最后,将打包好的文件(默认 encrypted 下的)替换掉之前的文件。
这样就可以了。
感觉还是蛮方便好用的。
加密后的代码,如下边这样的。
11月
25
将 web 项目打包成桌面应用程序是一种常见的方式。用到的工具有 electron 和 tauri 等。这里使用 tauri。
准备工作
- 安装配置 tarui 环境。 https://tauri.app/zh-cn/v1/guides/getting-started/prerequisites
- 准备一个 web 项目。
tauri 是可以从零开始创建项目,然后去完善项目的。但是,有的时候,项目已经完成了,这个时候,就需要在项目中加入 tauri。然后再构建打包了。
11月
25
工作和学习中,多显示器同时工作的情况是常态。那么在多个显示器之间来回切换应用是个很有效率的操作。 win 系统,默认就有这样的快捷键。mac,默认没有,得自己设置一下。 ### 操作
https://zhuanlan.zhihu.com/p/657556266
https://support.apple.com/zh-cn/HT201236
按照上边这个文章讲的来就可以搞定了。记得填入的文字一定不能错。 我的设定是这样子的。
# 移动到视网膜显示器(macbook pro 我放在左边)
⇧ + ⌥ + ←
# 移动到外接显示器(外接显示器,我放在右边)
⇧ + ⌥ + →
# 全屏和退出全屏
⌃ + ⌘ + f
好,就这三个快捷键。
还是不够好啊。全屏状态下,快捷键失效是什么鬼。
最后
- 在多个显示器间移动应用程序,win 的体验比 mac 好太多了。
- 在单个显示器间切换桌面, mac 又比 win 好。
就这么明显的体验,官方咋就做不好呢。
11月
24
用了 ts 的 vue3 项目,会经常遇到类型问题。组件问题也是类型问题的一种。这里简单总结一下写法。
组件类型声明
无论是第三方库,还是自定义组件,都可以通过这种方式来搞定。
这里分别以 element plus 中的组件和自定义组件为例。
# element plus 的 ElTable 组件
<template>
<el-table ref = "userTableRef">
<el-table-column property="nickname" label="昵称" />
</el-table>
</template>
<script setup lang="ts">
import { ref } from 'vue'
import type { ElTable } from "element-plus";
const userTableRef = ref<InstanceType<typeof ElTable>>()
</script>
下边是自定义组件。
<template>
<MediaPlayer ref="mediaPlayer" />
</template>
<script setup lang="ts">
import { ref } from 'vue'
import MediaPlayer from '@/components/MediaPlayer/MediaPlayer.vue'
const mediaPlayer = ref<InstanceType<typeof MediaPlayer>>()
</script>
最后
定义好了类型后,代码提示就很友好了。
11月
21
github 指定 ssh key。之所以会出现这个问题,是因为对于 github,只允许存在一份 ssh key。如果该 ssh key 绑定了 A 账号,B 账号则绑定不了。这个时候就需要再生成一份 ssh key,对新的 ssh key 进行绑定。但是,推送拉取代码的时候,默认是 ~/.ssh/id_rsa
。所以这个时候,特定的代码指定特定的 ssh key 就很有必要了。
解决问题
- 绑定 ssh key 时,出现 github Key is already in use 的问题。
- 多个 ssh key,特定项目指定特定的 ssh key 的问题。
先生成新的 ssh key
# 后边的参数 -f 指定生成 ssh key 对的名字
# 可以不加该参数,回车生成的时候,自己手动输入名字
ssh-keygen -t rsa -C email@email.com -f github
# 一直回车,干到生成为止,此时, `~/.ssh/` 下也许有好几份 ssh key 文件了
特定项目指定 ssh key
这个,在 config 中指定就可以。就像设置 user.name 和 user.email 一样。因为是特定项目使用特定的 ssh key。所以这个时候,不适合使用 --global 参数。
# ~/.ssh/github 这个对应生成的 ssh key 私钥文件
git config core.sshCommand "ssh -i ~/.ssh/github"
# 后边,再 git push 就会 ok 了
git remote add origin xxx
git push --set-upstream origin main
终点
到最后,就是这两个重要的命令。 生成 ssh key 对。进入项目目录,指定 ssh key。 ok 搞定。
# 生
ssh-keygen -t rsa -C email@email.com -f github
# 指
cd xxx
git config core.sshCommand "ssh -i ~/.ssh/github"
11月
20
在 ts 中,如果对一个接口对象的属性进行 delete 的话。该 delete 必须为可选属性。否则就会报 The operand of a 'delete' operator must be optional.
错误。\
比如:
interface User {
nickname: string
gender: number
}
const user:User = {nickname: 'vini', gender: 1}
delete user['gender']
# 这个时候就会报错。只需将 User 接口的 gender 定义改为 下边这样即可
interface User {
nickname: string
gender?: number
}
在 strictNullChecks 中使用 delete 运算符时,操作数现在必须为 any、unknown、never 或为可选(因为它在类型中包含 undefined)。否则,使用 delete 运算符是错误的。
11月
16
有这么一个场景。一堆宽高不一样的图片,按一定的宽高比放在一个容器里。并且,随着父容器宽度的变化,图片的宽高也随着变化。这里,主要用到 div 的一个属性 aspect-ratio。再结合媒体查询,就可以很容易做成自适应的展示。
https://developer.mozilla.org/zh-CN/docs/Web/CSS/aspect-ratio
https://github.com/vinistudy/autoImglist
部分示例代码
# img-con 使用 relative,方便 div 内部元素使用觉得定位,在图片上展示更多的信息
.media-con {
display: inline-block;
box-sizing: border-box;
padding: 0 8px;
width: 33%;
}
.media-con .img-con {
width: 100%;
height: auto;
aspect-ratio: 3/2;
overflow: hidden;
position: relative;
}
.media-con .img-con .img {
width: 100%;
height: 100%;
object-fit: cover;
}
可以根据外层容器的宽度不同,动态的设置 media-con 的百分比。比如,33%。超过 3 张自动换行。 20%,超过 5 张自动换行。数据合适就好。
11月
09
element plus 官方给出的单选实现,不是我想要的。估计也不是很多人想要的。很多人想要的应该是多选那样的选。但是吧,多选不是单选。所以需要改造。如果官方自己实现就多好啊。
https://element-plus.org/zh-CN/component/table.html#%E5%A4%9A%E9%80%89
改造方向。
- 去掉标题栏的选择框。这个用 css 可以实现。
- 将多选改为单选。(永远将已选的对象出栈,再 toggleRowSelection 过去)
部分代码
# template
<el-table ref = "table" @select="handleTableChange">
</el-table>
# script setup ts
import type { ElTable, ElTableColumn } from "element-plus";
const table = ref<InstanceType<typeof ElTable>>()
function handleTableChange(val: Record<string, any>[]) {
if (val.length > 1) {
const row:Record<string, any>|any = val.shift()
if (table.value) {
table.value?.toggleRowSelection(row, false)
}
}
}
# style scss (怕污染可以加特定父类)
th {
&.el-table-column--selection {
.el-checkbox {
display: none;
}
}
}
11月
09
在做一些特殊的展示的网站的时候,只需要按照一定比例的缩放就可以。这种不像栅格化的自适应(比如 bootstrap),这种也更好写。按照设计图的尺寸,换算做出来就可以。下边有两种方案。
https://juejin.cn/post/6966103143402700837
上边链接介绍的是满屏的自适应缩放。有的时候,是根据宽度做自适应。就是设计页高度远远大于宽度的情况。这个时候,只需要按照宽度自适应就可以。其实,还是用到上边的思路。采用上边的第二种方案,使用 rem 自适应。只是计算方法稍微改变一下。
# js
function setFontSize() {
const designWidth = 1440
const fontSize = document.documentElement.clientWidth < designWidth ?
12 * (document.documentElement.clientWidth / designWidth) : 12
const htmlElement: HTMLHtmlElement | null = document.querySelector('html')
if (htmlElement) {
htmlElement.style.fontSize = fontSize + 'px'
}
}
# scss
$design_width: 1440; //设计稿的宽度,根据实际项目调整
@function px2rem($px) {
$design_font_size: 12;
@return ($px/$design_font_size) + rem;
}
这个时候,似乎和高度已经没有关系了。
在这个情况下,如果媒体宽度大于设计图的宽度,内容宽度就是设计图宽度。对内容做居中处理。
# bootstrap 居中就是这么写的
margin-left: auto;
margin-right: auto;
# dom 结构
<div class="full-container">
<div class="design-wrap">
</div>
</div>