普通视图

发现新文章,点击刷新页面。
昨天以前一纸忘忧

ONE DAY 0310 重启 One Day 计划

作者 一纸忘忧
2026年3月10日 22:28

前段时间在微信刷到一篇推文,说的是 AI 时代,为什么我极力推荐你开始写日记? 里面提到的一个「流水账式日记」让我有点兴趣,说到写日记,最后一次写日记好像都是在高中时期了,坦白说这不是一件很容易坚持下去的事情。

记得两年前,刚刚开始写微信公众号的时候,写下的第一篇推文是 Hello World!你好,微信公众号! 后面也陆陆续续写了小半年,最终也没有坚持下去,这次我决定再出发,看看能坚持多久。

与上面推文中提到的观点不同的是,我更加愿意将自己的日记分享出来,在尽可能不泄漏个人隐私的情况下,让更多的人可以看到我的一些日常生活,可以共同交流各种各样的话题,我的日常比较简单,无非就是租房、公司的两点一线,这就是一个底层普通人的普通生活。

接下来我会尽量保持每天都随便写一点东西,如果没有什么好的话题可以记录的话,那就简单记录一下每天的炒股日常,看看能不能混成一个理财博主!

今天有什么流水账呢?无非还是跟 Copilot 对线,没有产出多少有效的东西,花了一早上时间写了产品分类的增删改查,后面发现纯 markdown 格式很难渲染好看的产品展示界面,最终还是决定推倒重来,逐一去写对应的组件。

晚上去接 Q 下班吃饭时,因为一些开发票的事情起了小争执,感觉这个世界这个社会的游戏规则,还是要亲身经历过才能真正懂,靠别人教的话是很难学会的,但是呢话又说回来,我又怎么能确定我的想法就一定是对的呢,只不过同样是站在自己的立场思考问题而已。

成立一周年!开源的本土化中文文档知识库

作者 一纸忘忧
2025年4月29日 23:15

前言

众所周知,在编程开发领域中,英语常常作为国际通用语言,许多开源项目都只提供英文开发者文档,导致英语基础不扎实的开发者在阅读开发文档时会遇到语言障碍。

可能有人会提出疑问,现在的浏览器翻译插件不是已经很成熟了吗?不可否认,浏览器自带的翻译功能确实可以解决大部分的文档阅读问题,但在一些格式较为复杂的场景,浏览器翻译会出现不可控的格式错误,严重的时候甚至会影响文档语义。

之前在给 Vue.js 中文文档贡献翻译时就在想,大多数开源项目的文档也是开源的,可不可以 Fork 一份到我的仓库来进行翻译,然后部署来提供中文文档的访问。

在去年的四月份,当时在辽宁出差,客户现场停产的时候,连续好几天在酒店里带薪摸鱼,正好有时间开始做这件事情,于是便创建第一个仓库,有了第一个 Commit 提交。

最初只是想着翻译文档来帮助自己学习使用,所以文档也只是部署到了自己的域名上面,直到我开始翻译第二个项目的时候,想着能不能给所有流行的开源项目提供一个可以持续发展的中文文档生态,利用庞大的开源社区来共同维护本土化的中文文档翻译。

于是,便有了今天要介绍的开源项目——简中文档!

项目介绍

2024 年 4 月 29 日,从辽宁出差回来的第二天,我注册了用户名为 zhcndoc 的 Github 组织,同时也注册了 zhcndoc.com 域名作为项目的主要入口,因此将这一天当作项目的成立时间。

根据 BCP 47(Best Current Practice 47)标准规定,zh_CN 表示简体中文的意思,英文单词 documentation 可以翻译成「文档」,取其缩写 doczh_CN 结合,拼起来可以变成 zhcndoc,表示「简体中文文档」的意思,简称为「简中文档」。

项目官网:https://www.zhcndoc.com

项目仓库:https://github.com/zhcndoc

截止目前,简中文档总共维护着 25 个开源项目的中文文档,其中 7 个是作为官方文档的镜像,Nuxt 中文文档是最多开发者访问的,下面是一些推荐的中文文档:

项目链接
Nuxthttps://nuxt.zhcndoc.com
Tailwind CSShttps://tailwindcss.zhcndoc.com
VueUsehttps://vueuse.zhcndoc.com
UnoCSShttps://unocss.zhcndoc.com
Denohttps://deno.zhcndoc.com
Nuxt I18nhttps://nuxt-i18n.zhcndoc.com

详情可以查看简中文档官网的项目探索

一周年

在过去的一年里,我没有公开宣传过简中文档项目,仅仅只是在 issues 中稍微提起,以及在微信群里交流时推荐给群友查阅,但依靠搜索引擎的自然流量,也给简中文档带来了一些知名度。

2024 年 5 月集成了 Umami 数据统计之后,截止目前总共收获了 45.4w 浏览量和 7.5w 访问次数,累计访客大约 4 万人,其中 83% 的流量来自于百度,12% 的流量来自于 Bing。

在网站 SEO 方面,根据站长工具查询,截止目前百度权重 2,搜狗和必应权重 1。

百度作为中文互联网最大的搜索引擎,自从收录之后一直保持稳定的关键词排名和收录;Google 对新网站的收录不太友好,目前没有太多的曝光;Bing 在去年 11 月对 zhcndoc.com 全域进行了屏蔽,清空了所有收录,直到前段时间经过多次申诉才解除限制,恢复了收录和权重;搜狗以及其他搜索引擎没有针对性的操作。

未来计划

尽管简中文档已经诞生一周年,但我认为它仍是一个处于建设初期的项目,还有很多翻译中的规范没有制定,以及贡献翻译的流程没有完善。本着集思广益的理念,欢迎大家加入简中文档,一起出谋划策,构建一个更好的本土化中文文档知识库。

梅开二度,土区 iCloud 再次涨价

作者 一纸忘忧
2024年9月11日 14:54

为了保证手机和电脑数据的可靠性,自从用上 Apple 全家桶以来,我就注册了一个土区的 Apple ID 来开通 iCloud 订阅,然后将主号国区的 Apple ID 拉入其家庭成员中,以此来共享 iCloud 订阅的 200G 存储空间,用于备份重要数据和相册等内容。

国区的 iCloud 200G 订阅价格为 20 元/月,最早土区的 200G 价格仅为 19.99 土耳其里拉,换算成人民币大约是四块钱一个月,可谓是性价比极高。

关于土耳其里拉和人民币的汇率换算,考虑到大多数人都没有外币卡,而是使用从闲鱼等平台购买的礼品卡进行充值,所以按照目前闲鱼平台的最低价格,100 土耳其里拉等于 20 元人民币,如果有其他渠道或许能做到更低的价格。

然而在 2023 年 6 月 Apple 发来邮件,土区 iCloud 订阅开始了第一次涨价,从 19.99 里拉涨到了 39.99 里拉,直接翻了一倍,换算过来的价格来到了八块钱一个月。

尽管订阅价格涨了一倍,但相对国区的 iCloud 二十块钱一个月还是有一定优势在的,于是我咬咬牙继续保持着订阅。

但就在最近,我再次收到了 Apple 发来的邮件,土区 iCloud 再次宣布涨价,而且更上次一样又是翻了一倍,从 39.99 里拉涨到了 79.99 里拉,换算过来约等于十六块钱。

但因为闲鱼上土耳其礼品卡的价格也会随之波动,前面提到的汇率换算是最低的价格,如果加上一些波动,那么土区 iCloud 订阅几乎和国区的价格持平。

既然如此,我想着也没必要使用土区 iCloud 家庭共享订阅的方式了,接下来应该会考虑整一台 NAS 来替换掉 iCloud,继续存储和备份一些重要的数据。

阿里云高校计划免费领取五年 ECS 服务器

作者 一纸忘忧
2024年7月22日 15:41

阿里云是国内领先的云计算服务商,但其产品在平日里并不算物美价廉,高昂的价格拦住了不少在校大学生或者并不富裕的开发者们。

然而就在前段时间,阿里云推出了名为“阿里云高校计划”的扶持活动,所有通过学生认证的账号均可直接领取一张 300 元的无门槛代金券,可直接抵扣购买、升级、续费等费用。

经过我的测试,不管是专科还是本科甚至研究生,也不管是全日制还是非全日制,只要是学信网在籍的都可以顺利通过认证。

如果已经毕业很长时间了,或者实在是弄不到学生认证的资格,可以通过公众号「一纸忘忧」联系我,有偿提供已认证的账号,账号支持更换绑定手机号,确保账号所属权能够得到保障。

接下来就是本文的主要内容,如何使用这张 300 元的无门槛代金券,购买五年阿里云 ESC 服务器。

领取代金券

活动地址:https://t.aliyun.com/U/7uRdEp

随机红包:https://t.aliyun.com/U/X6r6Fw

  1. 完成实名验证
  2. 完成个人实名后进行学生认证
  3. 领取 300 元的无门槛代金券
  4. 领取一个 20-100 的随机红包

如果没有学生认证可以通过公众号「一纸忘忧」联系我,有偿提供已认证的账号。

选购服务器

打开 ECS 选购页面:https://t.aliyun.com/U/htA8pV

选择地域为:华北 6(乌兰察布)

实例规格:突发性能实例 t6(ecs.t6-c4m1.large)

突发性能实例会限制 CPU 使用频率,如果一开始需要配置环境等操作,建议先打开无性能约束模式,可能会产生一定费用,后期可以自行关闭。

然后选择一个你熟悉的操作系统,我这里选的是 Debian 12。系统盘类型选择「高效云盘」,容量调整为 20 G。

重点来了,在带宽和安全组选择分配公网 IPv4 地址,并且选择按使用流量计费,然后再勾选升级至 CDT 计费。

开通云数据传输 CDT 计费后,每个月赠送 200GB 公网流量可用于服务器流量计费,但只有其中的 20GB 流量可用于中国内地地域。

需要注意的是,超出免费额度后的流量价格为 0.8元/G,如果你的服务器有对外使用的需求,请注意设置带宽限制,避免因恶意攻击导致流量费用飙升。

如果没有什么大带宽的需求,这里我建议将带宽设置小一点,比如设置成 5Mbps,一般就不会导致太大的流量费用支出。

选择购买年限

最后可以在右侧选择需要购买的年限,可以看到 4 年的费用可以全部由代金劵支付,而如果选择 5 年的话,也仅仅只需要再支付四十多块钱,这个价格也算得上超值了。

各位可以根据自己的需求来选择,如果有其他疑惑的地方,也可以在下方留言我们一起讨论。重要的事情说三遍,如果没有学生认证可以通过公众号「一纸忘忧」联系我,有偿提供已认证的账号。(别问为什么只有一遍,前面已经说过两遍了)

HTML Video 在 Vue 中消失的 muted 属性

作者 一纸忘忧
2024年3月23日 10:38

公司有个新项目由我这边独立选型开发,项目需求是做一个英文的产品展示官网,考虑到项目比较简单且周期不长,最终决定使用 Nuxt 框架来进行开发。

开发过程还算顺利,但中途遇到一个 Bug 花了我不少的时间,在网上找了许久,仅能检索到极少数相关内容,都是在 Vue 的 Github 仓库中的 issues,且最终仍未能够找到问题所在,当然这也许并不是 Bug,而是框架本身设计的就是这样。

以下是我的解决思路,如果各位大佬有别的见解,请指出交流。

问题现象

在产品展示的官网首页有一个全屏的 video 元素,视频默认自动播放,在大多数现代化浏览器的最新版本中,要实现这个功能,需要在 video 元素中加入 autoplay 属性,且还需要设置一个 muted 属性用于默认静音播放。

可以看到在第一次页面加载时是正常自动播放的,且此时 DOM 结构跟在 Vue 模板里写的代码是一样的。

这时候切换一下路由到产品页面,再切回首页时就出现了问题,原来 video 元素中的 muted 莫名其妙的消失了,导致视频自动播放也随之失效。

问题分析

起初我以为是 Nuxt 路由切换的问题,测试了使用 Nuxt 提供的 navigateTo() 方法和 Vue 路由提供的 $router.push() 方法,均存在该问题。

<div class="flex items-center justify-center">
  <img
    class="logo h-9 w-72 cursor-pointer"
    src="/logo.png"
    @click="$router.push('/')"
  />
</div>

第二次测试了给页面设置 keepalive: true 来实现路由缓存,但仍未解决该问题,且因此引出了其他的 Bug,没往其深究所以暂且按下不表。

definePageMeta({
  layout: 'full-screen',
  keepalive: true,
})

第三次测试了给 video 元素通过 v-bind 去动态绑定 muted 属性,不管是通过 ref 定义的值还是直接绑定 :muted="true",均未能解决问题。

<video
  src="car.mp4"
  class="w-full h-full object-cover"
  autoplay
  loop
></video>

我开始怀疑是不是 Nuxt 的问题,于是我第四次使用另一个纯 Vue 的项目做了测试。得出结果首次加载就失去了 muted 属性,但诡异的是视频仍可以实现自动播放,这个奇怪的问题逐渐变得扑朔迷离。

最终在 Vue 的 Github 仓库中找到了一个还未解决的 issues,遇到了跟我一样的问题。

这是一个在 2022 年 10 月 12 日创建的 issues,至今为止仍未关闭。值得一提的是,底下有一条回复指出「Vue 不应该真的破坏原生浏览器功能」,但可能这确实是 Vue.js 的 Bug。

问题解决

最终我不再去纠结问题所在,开始着手准备解决方案。既然通过动态绑定属性不能解决问题,那就只能使用最原始的方案了,通过操作 DOM 去出发元素的播放事件。

onMounted(() => {
  const videos = document.getElementsByTagName('video')
  Array.from(videos).forEach((video) => {
    video.play()
  })
})

在 Vue 挂载完成之后,通过 document.getElementsByTagName('video') 去拿到首页的所有视频元素,再依次触发播放事件,如此就能够在切换路由再切回首页时,视频仍能够保持自动播放。

尽管如此可以简单的解决问题,但感觉这并不是最终的解决方案,其问题核心应该还是出现在框架上,希望能够有大佬能深入研究一下,也能给我指点一二。

WordPress 设置文章 post_name 与 ID 同步

作者 一纸忘忧
2023年7月20日 22:44

前言

我一直有个强迫症,看着 WordPress 的文章中有个字段 post_name 如果不设置的话,就会默认使用标题 title 作为 post_name,导致使用 post_name 作为文章 URL 的时候会出现中文,看着很不协调。

然而我又不想手动去设置 post_name,于是乎想着能不能将 post_name 默认设置成与 ID 相同。

批量替换现有数据

首先将已经发布的文章给全部替换掉,直接用 SQL 语句

UPDATE wp_posts SET post_name = ID;

这里的 wp_posts 是 WordPress 数据库中的文章表。

发布文章自动修改

要在 WordPress 中每次发布或更新文章时,默认将 post_name 设置为与 ID 相同,可以通过添加自定义功能来实现此功能。

打开 WordPress 主题文件夹中的 functions.php 文件,在文件的末尾添加以下代码:

function set_postname_as_id( $post_id ) {
    $post = get_post( $post_id );
    $post_name = $post->post_name;
    $post_id = $post->ID;

    if ( $post_name != $post_id ) {
        $args = array(
            'ID' => $post_id,
            'post_name' => $post_id,
        );
        wp_update_post( $args );
    }
}
add_action( 'save_post', 'set_postname_as_id' );

保存并上传 functions.php 文件到您的 WordPress 主题文件夹。

每当发布或更新文章时,WordPress 将检查文章的 post_name 是否与 ID 相同。如果不同,它将自动更新 post_name 为 ID。请注意,这将影响所有类型的文章,包括页面和自定义文章类型。如果只想应用于特定类型的文章,可以在 set_postname_as_id 函数内添加适当的条件检查。

比如我用的是 B2 主题,我想替换所有的文章类型,除了 page 页面,可以改成下面这样:

function set_postname_as_id( $post_id ) {
    // 获取文章对象
    $post = get_post( $post_id );

    // 获取当前文章的 post_name 和 ID
    $post_name = $post->post_name;
    $post_id = $post->ID;

    // 检查文章类型是否为 page,如果是则返回
    if ( $post->post_type == 'page' ) {
        return;
    }

    // 检查 post_name 是否与 ID 不同
    if ( $post_name != $post_id ) {
        // 准备要更新的文章参数
        $args = array(
            'ID' => $post_id,
            'post_name' => $post_id,
        );

        // 更新文章的 post_name 为 ID
        wp_update_post( $args );
    }
}

// 在保存文章时触发自定义功能
add_action( 'save_post', 'set_postname_as_id' );

Vue.js 中的 v-model 和 model-value 区别

作者 一纸忘忧
2023年3月28日 15:58

Vue.js 中的 v-modelmodel-value 都是用于实现表单数据的双向绑定的指令。

v-model 是 Vue.js 提供的一个语法糖,可以让开发者在模板中更方便地实现表单数据的双向绑定。当在一个表单元素上使用 v-model 时,它会自动监听元素的 inputchange 事件,并将表单元素的值同步到相应的 Vue 组件数据中,反之亦然。例如:

<input v-model="message" />

这会将表单元素的值和 Vue 实例中的 message 数据双向绑定。如果用户在表单元素中输入了值,那么 message 数据会自动更新;如果 message 数据发生了变化,表单元素中的值也会自动更新。

model-value 是在 Vue 3 中新增的一个属性,用于在自定义组件中实现表单数据的双向绑定。与 v-model 不同的是,model-value 不是一个指令,而是一个属性,需要在自定义组件的选项中进行配置。例如:

app.component('my-component', {
  props: {
    modelValue: String
  },
  emits: ['update:modelValue'],
  template: `
    <input :value="modelValue" @input="$emit('update:modelValue', $event.target.value)" />
  `
})

这里定义了一个名为 my-component 的自定义组件,并在其 props 中定义了一个名为 modelValue 的属性。组件的模板中使用了这个属性来实现表单元素的值绑定,同时在表单元素的 input 事件中触发了一个名为 update:modelValue 的自定义事件,将输入的值作为参数传递给父组件。在使用这个自定义组件时,可以像下面这样使用 v-model 来实现表单数据的双向绑定:

<my-component v-model="message" />

总的来说,v-model 是 Vue.js 中用于实现表单数据双向绑定的常用指令,而 model-value 是在自定义组件中实现表单数据双向绑定的一种新的方式。

一款强大的 Linux 监控工具:Cockpit

作者 一纸忘忧
2022年11月4日 12:08

介绍

Cockpit 是一个易于使用、集成、易于浏览和开放的基于 Web 的服务器界面。

  • 系统日志信息查看
  • 系统存储信息查看
  • 仪表盘
  • 系统配置与系统基本操作
  • Docker 容器监控
  • 系统网络监控
  • K8s 集群管理(我没测试)
  • Web 命令行终端
  • ......

总之功能强大就对了。

安装

我这里是用 CentOS 7 版本的,此外 Cockpit 还另外支持其他多种 Linux 发行版。

来自官网的截图:

sudo yum install -y cockpit cockpit-docker cockpit-machines cockpit-dashboard cockpit-storaged cockpit-packagekit
sudo systemctl enable --now cockpit.socket
sudo firewall-cmd --permanent --zone=public --add-service=cockpit
sudo firewall-cmd --reload

也可以安装其他模块来扩展 Cockpit 的功能(yum install -y 模块名)。

然后就可以浏览器访问 9090 端口了。

用户名和密码就是 Linux 服务器的用户名和密码,登录即可进入首页。

阿里云高校计划免费领五年 ECS 服务器

作者 一纸忘忧
2024年7月22日 15:41

阿里云是国内领先的云计算服务商,但其产品在平日里并不算物美价廉,高昂的价格拦住了不少在校大学生或者并不富裕的开发者们。

然而就在前段时间,阿里云推出了名为“阿里云高校计划”的扶持活动,所有通过学生认证的账号均可直接领取一张 300 元的无门槛代金券,可直接抵扣购买、升级、续费等费用。

经过我的测试,不管是专科还是本科甚至研究生,也不管是全日制还是非全日制,只要是学信网在籍的都可以顺利通过认证。

如果已经毕业很长时间了,或者实在是弄不到学生认证的资格,可以通过公众号「一纸忘忧」联系我,有偿提供已认证的账号,账号支持更换绑定手机号,确保账号所属权能够得到保障。

接下来就是本文的主要内容,如何使用这张 300 元的无门槛代金券,购买五年阿里云 ESC 服务器。

领取代金券

活动地址:https://t.aliyun.com/U/7uRdEp

随机红包:https://t.aliyun.com/U/X6r6Fw

  1. 完成实名验证
  2. 完成个人实名后进行学生认证
  3. 领取 300 元的无门槛代金券
  4. 领取一个 20-100 的随机红包

如果没有学生认证可以通过公众号「一纸忘忧」联系我,有偿提供已认证的账号。

选购服务器

打开 ECS 选购页面:https://t.aliyun.com/U/htA8pV

选择地域为:华北 6(乌兰察布)

实例规格:突发性能实例 t6(ecs.t6-c4m1.large)

突发性能实例会限制 CPU 使用频率,如果一开始需要配置环境等操作,建议先打开无性能约束模式,可能会产生一定费用,后期可以自行关闭。

然后选择一个你熟悉的操作系统,我这里选的是 Debian 12。系统盘类型选择「高效云盘」,容量调整为 20 G。

重点来了,在带宽和安全组选择分配公网 IPv4 地址,并且选择按使用流量计费,然后再勾选升级至 CDT 计费。

开通云数据传输 CDT 计费后,每个月赠送 200GB 公网流量可用于服务器流量计费,但只有其中的 20GB 流量可用于中国内地地域。

需要注意的是,超出免费额度后的流量价格为 0.8元/G,如果你的服务器有对外使用的需求,请注意设置带宽限制,避免因恶意攻击导致流量费用飙升。

如果没有什么大带宽的需求,这里我建议将带宽设置小一点,比如设置成 5Mbps,一般就不会导致太大的流量费用支出。

选择购买年限

最后可以在右侧选择需要购买的年限,可以看到 4 年的费用可以全部由代金劵支付,而如果选择 5 年的话,也仅仅只需要再支付四十多块钱,这个价格也算得上超值了。

各位可以根据自己的需求来选择,如果有其他疑惑的地方,也可以在下方留言我们一起讨论。重要的事情说三遍,如果没有学生认证可以通过公众号「一纸忘忧」联系我,有偿提供已认证的账号。(别问为什么只有一遍,前面已经说过两遍了)

坚持日更一个月,不同自媒体平台数据表现如何

作者 一纸忘忧
2024年4月1日 10:38

四月已至,祝大伙们愚人节快乐,今天不分享技术资讯,来聊聊关于我在自媒体平台坚持日更一个月收获了什么。从上个月 4 号开始,一共写下了 28 篇推文,其中大部分还是来自互联网优质内容的翻译。目前仍处于一个探索学习的阶段,在搬运内容的同时,尽可能输出自己的一些想法。

那么下面就让我们一起来看看,对于像我这样的分享编程资讯的博主,目前正在运营的几个自媒体平台在流量和收益上面都表现如何?每个平台的数据分析有点多,想看总结的直接滑到文末。

公众号

在我第一篇推文中有提到过,促使我产生创作的想法,正是因为微信公众号的推送机制从私域转向了公域,让刚刚起步的账号也有了被推荐的机会,所以公众号是我发文顺序的第一个平台。

公众号后台的数据分析包含以下纬度:阅读、分享、跳转阅读原文、收藏、发表篇数,虽然每篇推文还有点赞、在看、转发等数据,但后台没有统一查看的地方,只能单篇查询。

不过好在后台提供了下载数据明细功能,通过 Excel 去计算得出,阅读次数 34236、阅读人数 29459,收获了 896 次分享、396 次收藏。单日最高浏览量 8815 次阅读,看起来应该是有几篇文章被推荐进入流量池了,表现不错。

公众号想要成为流量主在图文中插入广告获取收益,需要达到 500 个粉丝才能开通,因为刚刚开始做账号,所以没能达到此门槛,故公众号平台暂无收益。

哔哩哔哩

哔哩哔哩本身是一个专注于视频的平台,但其仍有一个可以写图文的板块叫做「专栏」,想着以后也许会往视频创作方向去发展,所以也把哔哩哔哩纳入其中。

哔哩哔哩创作中心的数据包含以下几个纬度:浏览、评论、收藏、点赞、分享、硬币。我的账号电磁力等级还没达到 LV3,没能开通创作激励计划,所以展示还没有收益,以下只展示专栏的数据。

哔哩哔哩的数据实在一言难尽,整整一个月的浏览量仅有 622,单日最高浏览量为 86,收获了 3 条评论、1 个点赞、1 个硬币,除此之外收藏、分享均为 0。尽管该数据表现极差,但在本文中仅仅只能排倒数第二,下文还有个数据更差的平台。

知乎

知乎是一个分享专业知识的平台,对编程类的内容欢迎度也很高,所以我也将知乎作为主力平台之一。知乎的主要内容形式还是以问答为主,不过它也有一个支持写图文的板块叫做「文章」,尽管流量可能不如问答的内容,但胜在知乎的用户基数较大,蚊子腿也是肉,写文章也能获得不少流量。

知乎的创作中心包含以下几个纬度:阅读、赞同、喜欢、评论、收藏、分享。

在最近的 30 天,收获了 16508 次阅读、114 次赞同、51 次喜欢、51 条评论、209 次收藏、53 次分享,单日最高阅读为 5314。知乎平台本身是有创作收益机制的,也许是我流量还不够多,所以全月总收益为 0。

掘金

掘金可以说是最专业对口的一个平台,其本身就专注于编程知识的分享,尽管平台用户基数不大,当相关性特别高,所以这也是主力平台之一。

其后台创作中心有以下几个维度:展现、阅读、点赞、评论、收藏。

总共收获 593516 次展现、37449 次阅读、274 次点赞、113 条评论、249 次收藏。掘金是三月份数据表现最好的平台,当仍是 0 收益。

头条号

从头条号往下都是一些不是特别相关的平台了,其本质是偏向休闲娱乐类的内容,故对编程知识类的内容不是特别友好,以下就简单过一遍数据,在文末在同一总结。

总共收获 100404 次展现、6307 次阅读、79 次点赞、23 条评论,表现中规中矩,展现量高但是点进来阅读的人并不多,转换比很低。

但是!头条号是第一个开始有收益的平台,经过一个月的努力,收获了 2.6 元创作收益。

百家号

百家号主要依赖于百度搜索的生态系统,其流量来源入口都是百度搜索引擎和百度 APP,其表现数据也只能说是一般般。

总共收获 23947 次推荐、1986 次阅读、16 条评论、12 次点赞、157 次收藏、34 次分享。值得一提的是,百家号是唯二有收益的平台,目前总收益为 2.97 元。

企鹅号

下面有请本文年度垫底选手————企鹅号登场,总共收获了 127 次阅读,其余数据均为 0,这是一个很夸张的平台,其后台表示会将内容统一推送至包括 QQ 浏览器、腾讯新闻、腾讯微视、腾讯视频、腾讯体育等各大企鹅系的平台,但我至今仍未能在其中找到我自己的推文,对于内容流量来源仍是个谜。

CSDN

最后一个平台相信大家都不陌生,就是大名鼎鼎的 CSDN,相信早已臭名昭著。其实我一开始并没有选择这个平台,是 3 月中旬观察到哔哩哔哩和企鹅号的数据表现不佳后,才决定拓展一下发文平台。总共收获 15987 次阅读、362 次点赞、286 次收藏。

总结

可以看出,单从阅读量的角度去排序,得出结论:掘金 > 公众号 > 知乎 > CSDN > 头条号 > 百家号 > 哔哩哔哩 > 企鹅号。值得一提的是,我发现 CSDN 和百家号两者含有人机灌水的嫌疑,CSDN 是表现在内容一发出就收获大量点赞和收藏,但却无一人评论,百家号则是表现在评论区出现大量与文中内容毫无相关性的评论。

从收益角度来说,目前仅有头条号和百家号产生了创作收益,3 月总收益为 5.57 元。只能说期待公众号早日达到 500 粉丝的门槛开通流量主吧,其他平台是不太指望能产生收益了。

从编辑内容和发布内容去看,知乎、掘金、CSDN 三者均支持 Markdown 格式的文档,不用担心文档的格式排版、表现最佳;公众号和头条号对富文本格式兼容性表现较好,基本上复制过去就能使用;哔哩哔哩、百家号、企鹅号对格式的兼容性最差,甚至不支持代码格式的展示。

鉴于以上的数据表现,后续将暂停在哔哩哔哩和企鹅号发文了,减少相关性不高的平台,提高内容质量才是重中之重。以上就是 3 月的自媒体总结,期待 4 月的精彩表现。

HTML Video 元素在 Vue 中消失的 muted 属性

作者 一纸忘忧
2024年3月23日 10:38

公司有个新项目由我这边独立选型开发,项目需求是做一个英文的产品展示官网,考虑到项目比较简单且周期不长,最终决定使用 Nuxt 框架来进行开发。

开发过程还算顺利,但中途遇到一个 Bug 花了我不少的时间,在网上找了许久,仅能检索到极少数相关内容,都是在 Vue 的 Github 仓库中的 issues,且最终仍未能够找到问题所在,当然这也许并不是 Bug,而是框架本身设计的就是这样。

以下是我的解决思路,如果各位大佬有别的见解,请指出交流。

问题现象

在产品展示的官网首页有一个全屏的 video 元素,视频默认自动播放,在大多数现代化浏览器的最新版本中,要实现这个功能,需要在 video 元素中加入 autoplay 属性,且还需要设置一个 muted 属性用于默认静音播放。

可以看到在第一次页面加载时是正常自动播放的,且此时 DOM 结构跟在 Vue 模板里写的代码是一样的。

这时候切换一下路由到产品页面,再切回首页时就出现了问题,原来 video 元素中的 muted 莫名其妙的消失了,导致视频自动播放也随之失效。

问题分析

起初我以为是 Nuxt 路由切换的问题,测试了使用 Nuxt 提供的 navigateTo() 方法和 Vue 路由提供的 $router.push() 方法,均存在该问题。

第二次测试了给页面设置 keepalive: true 来实现路由缓存,但仍未解决该问题,且因此引出了其他的 Bug,没往其深究所以暂且按下不表。

第三次测试了给 video 元素通过 v-bind 去动态绑定 muted 属性,不管是通过 ref 定义的值还是直接绑定 :muted="true",均未能解决问题。

我开始怀疑是不是 Nuxt 的问题,于是我第四次使用另一个纯 Vue 的项目做了测试。得出结果首次加载就失去了 muted 属性,但诡异的是视频仍可以实现自动播放,这个奇怪的问题逐渐变得扑朔迷离。

最终在 Vue 的 Github 仓库中找到了一个还未解决的 issues,遇到了跟我一样的问题。

这是一个在 2022 年 10 月 12 日创建的 issues,至今为止仍未关闭。值得一提的是,底下有一条回复指出「Vue 不应该真的破坏原生浏览器功能」,但可能这确实是 Vue.js 的 Bug。

问题解决

最终我不再去纠结问题所在,开始着手准备解决方案。既然通过动态绑定属性不能解决问题,那就只能使用最原始的方案了,通过操作 DOM 去出发元素的播放事件。

在 Vue 挂载完成之后,通过 document.getElementsByTagName('video') 去拿到首页的所有视频元素,再依次触发播放事件,如此就能够在切换路由再切回首页时,视频仍能够保持自动播放。

尽管如此可以简单的解决问题,但感觉这并不是最终的解决方案,其问题核心应该还是出现在框架上,希望能够有大佬能深入研究一下,也能给我指点一二。

JavaScript 运行时层出不穷,谁的兼容性表现最好?

作者 一纸忘忧
2024年3月20日 10:37

近日,随着 WinterJS 1.0 的发布,Bun 这边也加快了开发进展,截止发文,Bun for Windows 目前通过了 Bun 测试套件的 93.88%,一旦 Bun for Windows 通过了 Bun 测试套件的 95% ,Bun 将发布支持 Windows 的 Bun 1.1 版本。

JavaScript 运行时越来越多优秀的选手加入对局,在很久以前以前仅限于客户端的 JavaScript,终于可在服务端大展身手。然而随着众多的运行时发布,相互之间的兼容性难以保持平衡。

对此 Cloudflare 与 Vercel、Shopify 将与 Node.js 和 Deno 的个人核心贡献者合作,共同成立一个新的社区小组,命名为 WinterCG,该小组汇集了三个最大的 JavaScript 环境,为开发人员提供了灵活性和选择,同时创建边缘计算的未来标准。

为了能够更直观的查看不同运行时的兼容性表现,Vercel 工程师 Tom Lienard 宣布与 Matt Kane、UnJS、CanadaHonk 和 Open Web Docs 人员合作推出一个新的开源项目 Runtime Compat,用于显示不同 JavaScript 运行时之间的 API 兼容性,下面让我们一起看一下 Runtime Compat 有什么好玩的有趣的功能吧。

项目介绍

在不同的 JavaScript 运行时中显示 API 的兼容性。数据是使用 mdn-bcd-collector 中的运行时测试自动生成的,并以 MDN 浏览器兼容性数据格式发布。

警告:当前数据并非 100% 准确,而是自动生成的。

关于数据

数据是使用 mdn-bcd-collector 项目中的测试生成的。这些最初是为 MDN 的 browser-compat-data 创建的,该数据支持 MDN Web Docs 和 CanIUse 等网站。这些测试旨在在浏览器环境中运行,因此我们使用了一个稍微修改过的测试工具版本,以便让它们能够在非浏览器运行时执行。

每个运行时代码略有不同,因为它们被设计成以不同方式调用。广义上分为两组:可直接从 CLI 运行的和通过 HTTP 请求调用的其他类型。对于后者,我们使用项目自己的开发服务器,然后使用 start-server-and-test 来启动服务器并请求运行测试文件的函数。

每个运行时目录中都会生成一个 data.json 文件,其中包含了测试结果。如果要检查特定测试失败原因,请首先检查此文件内容,因为它包含了每个测试的代码和错误消息。

然后另一个脚本处理这些文件,并将其与 browser-compat-data 项目关于每个 API 的元数据结合起来,并将数据作为 JSON 文件写入 runtime-compat-data 目录,然后发布到 npm 作为 runtime-compat-data 模块。

可以在本地运行这些测试,但实际数据生成过程是通过 GitHub Actions 运行完成,如果有任何更改,则会打开 PR 。

局限性

实际测试是设计在浏览器中运行的,因此可能存在不一致性。出于同样的原因,它们也不会测试任何 WinterCG 特定功能。

通常使用托管服务来运行几个支持的运行时。这些通过开发库或服务器在本地进行测试,可能与生产环境有所不同。

一些运行时可能会定义特定的 API 对象或方法,但作为一个存根或空操作而不是实际功能。在大多数情况下,这将被显示为受支持的。通常这些功能在浏览器环境之外没有意义,但已经实现以允许代码跨平台运行。

这些测试是为浏览器创建的,因此它们对其环境做出了一些假设。我们尽量解决尽可能多的问题,但仍然存在错误负面影响。例如,大多数请求和 URL 测试都假定它们可以创建相对 URL。由于设计原因,在大多数非浏览器运行时中这种方式无法工作,因为没有 location.href 供其相对参照。目前这意味着很多这些测试报告为失败,即使运行时支持其中的大部分功能。

测试仅针对每个运行时的最新稳定版本进行,因此数据仅显示该功能当前是否受支持。在大多数情况下,这些运行时会定期更新,所以这不应该是一个问题。唯一的例外是 Node.js,它经常使用旧版本运行。对于这种情况,您可能希望将数据与 MDN 文档进行比较,其中包含有关旧版本 Node 的支持详细信息。

相关链接

在线查看:https://runtime-compat.unjs.io

项目地址:https://github.com/unjs/runtime-compat

UI 和 UX 全面升级,Node.js 新官网预览版发布!

作者 一纸忘忧
2024年3月8日 08:52

Node.js 新官网已正式发布了 Beta 预览版本,现正积极招募测试志愿者,以收集广大用户的真实体验与宝贵建议。如果你对 Node.js 新官网的设计和功能充满好奇,或者想要为 Node.js 社区的发展贡献一份力量,那么请踊跃参与,共同见证新官网的蜕变。

新官网的体验地址已经公布,你可以在浏览器中直接访问下方官网地址进行体验。同时,我们也欢迎你在 Github 仓库中提供反馈和建议,帮助 Node.js 社区不断完善新官网。

体验地址

官网地址:https://beta-node-js-org.vercel.app

项目地址:https://github.com/nodejs/nodejs.org

全新首页

在体验新官网的过程中,我感受到了其 UI 和 UX 设计的显著提升。全新设计的首页给人一种焕然一新的感觉。从视觉效果到页面布局,再到内容的展示,都展现出了更加专业和精致的风格。Node.js 的介绍也更加突出和全面,让人一眼就能领略到它的魅力。

特别值得一提的是,新官网在搜索框功能上进行了优化,提供了全站检索的功能。无论你想要查找文档、博客还是下载资源,都能通过搜索框轻松找到。这一改进大大提升了用户的检索效率,让使用体验更加便捷。

在体验过程中,我也发现了一些需要改进的地方,例如首页的 Node.js LTS 下载按钮的箭头设计可能需要调整,以更符合用户的认知习惯;此外,右侧代码块在切换时造成的页面闪动也需要进一步优化,以提升用户体验。

学习页面

学习页面进行了全新改版,从两列布局升级为三列布局,左侧导航菜单采用树型目录形式,便于用户快速定位所需内容。右侧新增阅读时长、反馈入库及文档目录等功能,为用户带来更为便捷的学习体验。

在使用过程中也发现了一些可以优化的地方,比如当滚动左侧导航目录时,点击菜单后目录会自动滚回顶部,这影响了用户的浏览体验。此外,建议考虑在文档顶部加入面包屑导航,以便用户更好地了解当前位置。

关于页面

关于页面的设计延续了学习页面的风格,采用了相似的布局结构,确保用户在切换页面时能够保持一致的浏览体验。

值得一提的是,在介绍页的顶部新增了一处引人注目的 Node.js 吉祥物「火箭龟」的图片,这不仅为页面增添了几分趣味性,同时也作为品牌元素,加深了用户对 Node.js 的认知和记忆。

下载页面

下载页面在交互方式上进行了优化,采用下拉选择组件的形式供用户选择历史版本、操作系统以及系统架构,使操作更为简便快捷。这一改进特别适用于需要下载特定历史版本的用户,提高了他们的操作效率。

博客页面

博客页面的布局变化较大,内容也更加丰富多样。除了最新的 Node.js 新闻、案例研究、教程和资源外,还增加了多个 Tab 筛选功能,方便用户快速找到感兴趣的内容。

然而在体验过程中,发现点击 Events Tab 时出现了 404 错误页面,这可能需要进一步修复。

文档页面

文档和 Certification 页面目前没有明显变化,仍然保持了现有的 API 文档页面和对应站点的跳转,这可能是因为这两个页面的内容相对稳定,不需要进行大规模的调整。

总结

Node.js 新官网的 Beta 预览版本在设计和功能上都有了显著的提升,为用户提供了便捷和舒适的体验,在细节方面仍有一些需要改进的地方。期待广大测试志愿者能够积极参与体验,并提供宝贵的反馈和建议,共同推动新官网的完善和优化。

感谢你的关注与支持!让我们一起期待 Node.js 新官网的正式发布,为 Node.js 社区的发展注入新的活力!

往期回顾

  1. Node.js 特别吉祥物:「火箭龟」引领新篇章!
  2. Bun v1.0.30 正式发布,即将提供 Windows 稳定版本!
  3. Hello World!你好,微信公众号!

WordPress 设置文章 post_name 与 ID 同步

作者 一纸忘忧
2023年7月20日 22:44

前言

我一直有个强迫症,看着 WordPress 的文章中有个字段 post_name 如果不设置的话,就会默认使用标题 title 作为 post_name,导致使用 post_name 作为文章 url 的时候会出现中文,看着很不协调。

然而我又不想手动去设置 post_name,于是乎想着能不能将 post_name 默认设置成与 ID 相同。

批量替换现有数据

首先将已经发布的文章给全部替换掉,直接用 sql 语句

UPDATE wp_posts SET post_name = ID;

这里的 wp_posts 是 WordPress 数据库中的文章表

发布文章自动修改

要在 WordPress 中每次发布或更新文章时,默认将 post_name 设置为与 ID 相同,可以通过添加自定义功能来实现此功能

打开 WordPress 主题文件夹中的 functions.php 文件,在文件的末尾添加以下代码:

function set_postname_as_id( $post_id ) {
    $post = get_post( $post_id );
    $post_name = $post->post_name;
    $post_id = $post->ID;

    if ( $post_name != $post_id ) {
        $args = array(
            'ID' => $post_id,
            'post_name' => $post_id,
        );
        wp_update_post( $args );
    }
}
add_action( 'save_post', 'set_postname_as_id' );

保存并上传 functions.php 文件到您的 WordPress 主题文件夹

每当发布或更新文章时,WordPress 将检查文章的 post_name 是否与 ID 相同。如果不同,它将自动更新 post_name 为 ID。请注意,这将影响所有类型的文章,包括页面和自定义文章类型。如果只想应用于特定类型的文章,可以在 set_postname_as_id 函数内添加适当的条件检查。

比如我用的是 b2 主题,我想替换所有的文章类型,除了 page 页面,可以改成下面这样

function set_postname_as_id( $post_id ) {
    // 获取文章对象
    $post = get_post( $post_id );

    // 获取当前文章的 post_name 和 ID
    $post_name = $post->post_name;
    $post_id = $post->ID;

    // 检查文章类型是否为 page,如果是则返回
    if ( $post->post_type == 'page' ) {
        return;
    }

    // 检查 post_name 是否与 ID 不同
    if ( $post_name != $post_id ) {
        // 准备要更新的文章参数
        $args = array(
            'ID' => $post_id,
            'post_name' => $post_id,
        );

        // 更新文章的 post_name 为 ID
        wp_update_post( $args );
    }
}

// 在保存文章时触发自定义功能
add_action( 'save_post', 'set_postname_as_id' );

konva.js 阻止 click 事件冒泡到父元素

作者 一纸忘忧
2023年3月29日 15:40

前言

KonvaJS 中,事件冒泡是默认启用的,这意味着当在子元素上触发事件时,该事件将向上传播到父元素。因此,如果在图层上注册了 click 事件并在其上创建了一个组,那么单击该组也将触发该事件。

KonvaJS 并没有 stopPropagation() 方法来防止事件冒泡。相反,KonvaJS 使用了自己的事件系统来管理事件,事件传递和事件监听器。

KonvaJS 中,可以使用事件对象的 stopPropagation() 方法来阻止事件传播到上级元素。在 KonvaJS 中,事件对象是一个 Konva.Collection 类的实例,它是事件发生时所有相关节点的集合。可以使用它来访问事件目标节点和其他相关节点。

例子

以下代码演示了如何使用 KonvaJS 事件系统来防止父级元素的 click 事件触发:

const stage = new Konva.Stage({
  container: 'container',
  width: 500,
  height: 500,
});

const layer = new Konva.Layer();
stage.add(layer);

const group = new Konva.Group();
group.on('click', (event) => {
  // 阻止事件传播到父级元素
  event.cancelBubble = true;
  
  // 处理组的click事件
  // ...
});

layer.on('click', (event) => {
  // 在此处理父级元素的click事件
  // ...
});

在这个例子中,当单击组时,事件对象的 cancelBubble 属性被设置为 true,以防止事件继续传播到父级元素。这样,父级元素的 click 事件就不会触发了。

需要注意的是,由于 KonvaJS 的事件系统与浏览器的事件系统不同,因此它的用法也略有不同。具体来说,事件对象没有 stopPropagation() 方法,而是使用 cancelBubble 属性来实现相同的效果。

Vue 的 v-model 和 model-value

作者 一纸忘忧
2023年3月28日 15:58

Vue.js 中的 v-modelmodel-value 都是用于实现表单数据的双向绑定的指令。

v-model 是 Vue.js 提供的一个语法糖,可以让开发者在模板中更方便地实现表单数据的双向绑定。当在一个表单元素上使用 v-model 时,它会自动监听元素的 inputchange 事件,并将表单元素的值同步到相应的 Vue 组件数据中,反之亦然。例如:

<input v-model="message" />

这会将表单元素的值和 Vue 实例中的 message 数据双向绑定。如果用户在表单元素中输入了值,那么 message 数据会自动更新;如果 message 数据发生了变化,表单元素中的值也会自动更新。

model-value 是在 Vue 3 中新增的一个属性,用于在自定义组件中实现表单数据的双向绑定。与 v-model 不同的是,model-value 不是一个指令,而是一个属性,需要在自定义组件的选项中进行配置。例如:

app.component('my-component', {
  props: {
    modelValue: String
  },
  emits: ['update:modelValue'],
  template: `
    <input :value="modelValue" @input="$emit('update:modelValue', $event.target.value)" />
  `
})

这里定义了一个名为 my-component 的自定义组件,并在其 props 中定义了一个名为 modelValue 的属性。组件的模板中使用了这个属性来实现表单元素的值绑定,同时在表单元素的 input 事件中触发了一个名为 update:modelValue 的自定义事件,将输入的值作为参数传递给父组件。在使用这个自定义组件时,可以像下面这样使用 v-model 来实现表单数据的双向绑定:

<my-component v-model="message" />

总的来说,v-model 是 Vue.js 中用于实现表单数据双向绑定的常用指令,而 model-value 是在自定义组件中实现表单数据双向绑定的一种新的方式。

1679989833734.png

Cockpit:一款强大的Linux监控工具

作者 一纸忘忧
2022年11月4日 12:08

介绍

Cockpit是一个易于使用、集成、易于浏览和开放的基于 Web 的服务器界面。

  • 系统日志信息查看
  • 系统存储信息查看
  • 仪表盘
  • 系统配置与系统基本操作
  • Docker容器监控
  • 系统网络监控
  • k8s集群管理(我没测试)
  • Web命令行终端
  • ......

总之功能强大就对了。

安装

我这里是用centos7版本的,此外cockpit还另外支持其他多种linux发行版

来自官网的截图:

sudo yum install -y cockpit cockpit-docker cockpit-machines cockpit-dashboard cockpit-storaged cockpit-packagekit
sudo systemctl enable --now cockpit.socket
sudo firewall-cmd --permanent --zone=public --add-service=cockpit
sudo firewall-cmd --reload

也可以安装其他模块来扩展cockpit的功能(yum install -y 模块名)

然后就可以浏览器访问9090端口了

用户名和密码就是linux服务器的用户名和密码,登陆即可进入首页。

Git Commit Message提交规范

作者 一纸忘忧
2022年5月19日 20:38

前言

上个月公司来了位前端大佬,给我们团队制订了一些技术方面的规范,其中有一项是关于在Git上提交代码写Commit Message的一些规范,开始我还觉得多此一举,看了许多大型项目的commit记录之后,才知道这个规范算是行业里的标准。

先来看看我的CodeStudy项目里是写的什么Commit Message

再看看尤雨溪大佬的作品Vue框架的Commit Message

果然一个规范的Commit Message真的能让人眼前一亮,可以快速了解到该commit的内容和涉及的功能模块,下面说说规范化Commit Message能带来什么好处。

规范化的好处

  • 便于程序员对提交历史进行追溯,了解发生了什么情况。
  • 一旦约束了 Commit Message,意味着我们将慎重的进行每一次提交,不能再一股脑的把各种各样的改动都放在一个 git commit里面,这样一来整个代码改动的历史也将更加清晰
  • 格式化的 Commit Message才可以用于自动化输出 Change log

Git提交规范

<type>(<scope>):<subject>
<body>
<footer>
名称作用
type用于说明 Git Commit 的类别,只允许使用下表的标识
scope用于说明 Commit 影响的范围,比如数据层、控制层、视图层等
subjectCommit 目的的简短描述,一般不超过50个字符
body可忽略,可多行,详细的描述,与header之间空一行
footer可忽略,一般用于不兼容更新或关闭issue,与body之间空一行
类型描述
sync同步主线或分支的bug
merge代码合并
revert回滚到上一个版本
chore构建过程或辅助工具的变动
test增加软件测试
perf优化相关,比如提升性能、体验
refactor重构,既不是新增功能,也不是修改bug的代码变动
style格式,不影响代码运行的变动
docs文档撰写或更新
fix / to修复bug,可以是QA发现的bug,也可以是研发自己发现的bug
feat新功能(feature)

插件推荐

在VS Code上面强烈推荐Commit Message Editor插件,可以快速生成Git Commit Message

❌
❌