跳至主要內容
如何搭建自己的个人博客

一、方案汇总

方案 平台 成本 优缺点
方案一:社区平台 - 飞书

- 语雀

- CSDN/博客园

- 其他技术社区
经济上:0

技术上:无
优点:

- 方便,0成本

- 背靠社区

- 有后台管理


缺点:

- 比较难自定义页面
方案二:Github Pages/Vercel + Hexo/Vuepress - Github Pages

- Github + Vercel

- Gitee Pages(Pro关闭了)
经济上:0

技术上:需要了解前端知识
优点:

- 自定义能力强

- 主题多


缺点:

- 这类博客一般是纯静态网页,一般没有后台或数据统计

- 需要一定前端知识
方案三:云服务器 + Wordpress - 云服务器 + Wordpress 经济上:需要一台云服务器(0~100/月,新用户/学生优惠)

技术上:无,了解前端/后端更好
优点:

- 主题多

- 有后台管理


缺点:

- 经济上有一定成本
方案四:微信公众号以及其他各类公众号 - 申请公众号 经济上:0

技术上:无
优点:

- 方便,0成本

- 背靠社区

- 有后台管理


缺点:

- 比较难自定义页面

yyshino大约 3 分钟FrontEnd博客
如何阅读源码

作者:lgd8981289

搬运自 https://github.com/lgd8981289/vue-next-mini

简介

那么在上一小节中我们已经知道了如何对vue的源代码进行debugger ,但是如果想要学习或者了解 vue的代码执行,那么光靠 debugger是不够的,除此之外我们还需要掌握另外一个能力,那么如何阅读源代码

阅读源代码的误区

很多同学在去阅读源代码的时候,都会面临一个误区,那就是:我需要把源代码中每一行代码都读明

这是一个非常不对的行为,很容易让我们 事倍功半


yyshino大约 3 分钟FrontEnd源码分析
Vue3源码解析

Vue响应式

原理

Proxy与Object.defineProperty

  1. Proxy
    1. Proxy 将代理一个对象(被代理对象),得到一个新的对象(代理对象),同时拥有被代理对象中所有的属性。
    2. 当想要修改对象的指定属性时,我们应该使用代理对象进行修改
    3. 代理对象 的任何一个属性都可以触发 handler 的 getter 和 setter
  2. Object.defineProperty
    1. Object.defineProperty 为指定对象的指定属性设置属性描述符
    2. 当想要修改对象的指定属性时,可以使用原对象进行修改
    3. 通过属性描述符,只有 被监听 的指定属性,才可以触发 getter 和 setter

yyshino大约 15 分钟FrontEndVue源码分析
WeakMap与Map的区别

WeakMap与Map的区别

WeakMap

  1. key必须是对象
  2. key是弱引用
弱引用与强引用
  • 弱引用:不会影响垃圾回收机制。即: WeakMap 的 key 不再存在任何引用时,会被直接回收。

  • 强引用:会影响垃圾回收机制。存在强应用的对象永远不会被回收。

对比示例

<script>

    let obj1 = {
        name: '张三'
    }
    let obj2 = {
        name: '张三'
    }

    // 强引用
    const map = new Map()
    // 弱引用
    const weakMap = new WeakMap()
    map.set(obj1,'value')
    weakMap.set(obj2,'value')

    obj1 = null
    obj2 = null

    console.log('map',map) // Map(1) {{…} => 'value'}
    console.log('weakMap',weakMap) // WeakMap {} 空
    
    /**
    此时 WeakMap 中不存在任何值,即: obj2不存在其他引用时, WeakMap 不会阻止垃圾回收,基于obj2的引用将会被清除。这就证明了 WeakMap 的 弱引用特性。
    */
</script>

yyshino小于 1 分钟FrontEndJS
手写reduce

MDN参考

https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/reduce

语法

reduce(callbackFn)
reduce(callbackFn, initialValue)

yyshino大约 2 分钟FrontEndJS手写系列
手写call、apply、bind

手写call、apply、bind

总结

  • 三者都可以改变函数的this对象指向
  • 三者第一个参数都是this要指向的对象,如果如果没有这个参数或参数为undefined或null,则默认指向全局window
  • 三者都可以传参,但是apply是数组,而call是参数列表,且apply和call是一次性传入参数,而bind可以分为多次传入
  • bind是返回绑定this之后的函数,apply、call 则是立即执行

yyshino大约 2 分钟FrontEndJS手写系列
并发请求
    /**
     * 在某些场景下,页面的请求数可能会有很多,
     * 比如:抓取、分片上传等,如果我们需要等一个请求完成后,
     * 再发起下一个请求,是必效率会比较低。
     * 为了提升效率,我们可以同时发出多个请求,但数量又不能太多,
     * 如若某请求完成,剩余等待的请求继续补位执行,
     * 将请求的结果(不论成功或失败),按原有数组的顺序返回。
     */

    /**
     * 11-并发事件
     * @param {string[]} urls 请求地址数组
     * @param {number} max 最大并发数
     */
    function consurRequest(urls, max) {
        return new Promise((resolve,reject) => {
            // 判断传入urls长度,为空直接返回[]
            if(urls.length === 0){
                resolve([])
                return
            }

            const results = []
            let count = 0 // 标识请求的完成数量
            let index = 0 // 下一个请求

            // 发送请求
            async function request(){
                // 退出逻辑
                if(index === urls.length){
                    return
                }

                // 存储 index,保持后续请求结果数组与urls数组对应
                const i = index
                const url = urls[index]
                index++
                try {
                    const resp = await fetch(url)
                    // resp加入到 results中
                    results[i] = resp
                } catch (err) {
                    // err 加入到results
                    results[i] = err
                    console.log('err',err)
                } finally {
                    // 判断是否所以的请求都完成
                    count++
                    // if(count === urls.length){
                    if(count === urls.length){
                        resolve(results)
                        return
                    }
                    request()
                }
            }

            const times = Math.min(max,urls.length)
            let promiseList = []

            for(let i = 0; i < times; i++){
                promiseList.push(request())
            }

            Promise.race(promiseList).then(() => {
            }).catch((err) => {
                reject(err)
            })
        })
    }

yyshino大约 1 分钟FrontEndJS手写系列
Vue响应式实现

原理

Proxy与Object.defineProperty

  1. Proxy
    1. Proxy 将代理一个对象(被代理对象),得到一个新的对象(代理对象),同时拥有被代理对象中所有的属性。
    2. 当想要修改对象的指定属性时,我们应该使用代理对象进行修改
    3. 代理对象 的任何一个属性都可以触发 handler 的 getter 和 setter
  2. Object.defineProperty
    1. Object.defineProperty 为指定对象的指定属性设置属性描述符
    2. 当想要修改对象的指定属性时,可以使用原对象进行修改
    3. 通过属性描述符,只有 被监听 的指定属性,才可以触发 getter 和 setter

yyshino大约 2 分钟FrontEndJS
Vue源码分析

框架的基本概念

在本章中,我们对整个 vue 框架设计中的一些基本概念都做了一个了解。明确了如下基本概念:

  1. 命令式
  2. 声明式
  3. 心智负担
  4. 框架设计与取舍之间的关系
  5. 运行时
  6. 编译时
  7. 运行时 + 编译时
  8. 副作用
  9. reactivity、 runtime、compiler 三者之间的运行关系
  10. 扩展:良好的 ts 支持

当我们把这些基本概念了解清楚之后,那么下一章我们就可以准备开始构建我们的 vue 3 框架了。


yyshino大约 4 分钟FrontEndVue2