[{"data":1,"prerenderedAt":500},["ShallowReactive",2],{"pages-list":3},[4,8,12,16,20,23,26,30,34,38,41,45,49,53,56,60,64,68,72,76,79,82,86,90,94,98,101,105,108,111,115,118,122,125,129,133,137,141,144,148,152,155,159,163,166,170,173,176,180,184,187,191,194,197,201,204,207,211,215,218,221,225,228,232,236,240,243,247,250,253,256,259,262,265,269,272,276,280,283,287,291,295,299,303,307,310,314,318,322,326,330,334,338,342,346,350,353,357,361,364,368,372,376,380,384,388,392,396,400,404,408,412,416,420,424,428,432,436,439,443,447,450,453,457,461,465,469,473,477,481,485,489,493,496],{"path":5,"title":6,"description":7},"\u002Fcpp\u002Fboost\u002Fcpp-boost","Cpp Boost","Boost C++ 库 是一组基于C++标准的现代库。 其源码按 Boost Software License 来发布，允许任何人自由地使用、修改和分发。 这些库是平台独立的，且支持大多数知名和不那么知名的编译器。",{"path":9,"title":10,"description":11},"\u002Fcpp\u002Fboost\u002Fcpp-google-test","Cpp Google Test","Google Test (gtest) 的核心思想是通过宏 来简化测试代码。要熟练使用 gtest，你需要掌握它的命名规则、核心断言、浮点数比较、字符串比较以及进阶的测试夹具。",{"path":13,"title":14,"description":15},"\u002Fcpp\u002Fboost\u002F编译python可调用的pyd-c模块","编译Python可调用的pyd C模块","",{"path":17,"title":18,"description":19},"\u002Fcpp\u002Fcom组件与windows编程入门","COM 组件与 Windows 编程（加长版）","面向：几乎没写过 Win32 \u002F C++ 原生，但听说过 COM、ActiveX、DLL 注册 的同学。本文尽量 拓宽视野：不只围绕某一个录屏工程，而是把 桌面右键菜单、Office 自动化、Shell、拖拽 等典型 COM 场景串起来；代码片段以 示意 + 可对照 MSDN 补全 为主。",{"path":21,"title":22,"description":15},"\u002Fcpp\u002Fcpp的学习笔记","Cpp的学习笔记",{"path":24,"title":25,"description":15},"\u002Fcpp\u002Fcpp编译器思考","Cpp编译器思考",{"path":27,"title":28,"description":29},"\u002Fcpp\u002Fc实现闭包","C实现闭包","C语言本身是没有闭包的因为C的函数栈是后进先出，函数已返回，栈帧就会销毁，局部变量就会随之消失，要实现闭包，就要手动模拟v8那套把逃逸的变量放在堆上。",{"path":31,"title":32,"description":33},"\u002Fcpp\u002Fegl和skia","EGL和Skia","OpenGL 是一种跨平台的图形 API，用于为 3D 图形处理硬件指定标准的软件接口。OpenGL ES 是 OpenGL 规范的子集，适用于嵌入式设备。而EGL 是渲染 API（如 OpenGL ES）和原生窗口系统之间的接口.通常来说，OpenGL 是一个操作 GPU 的 API，它通过驱动向 GPU 发送相关指令，控制图形渲染管线状态机的运行状态，但是当涉及到与本地窗口系统进行交互时，就需要这么一个中间层，且它最好是与平台无关的,",{"path":35,"title":36,"description":37},"\u002Fcpp\u002Ffeatures\u002Fcpp的符号表","CPP的符号表","对于从 C# .NET 转到 C++ 的开发者来说，理解符号表是理解“静态链接语言”与“托管语言”差异的关键。",{"path":39,"title":40,"description":15},"\u002Fcpp\u002Ffeatures\u002Fcpp类的讲解","Cpp类的讲解",{"path":42,"title":43,"description":44},"\u002Fcpp\u002Ffeatures\u002Fstring-和-algorithm","C++ string 和 algorithm","这两个库几乎是字符串题的默认搭档：",{"path":46,"title":47,"description":48},"\u002Fcpp\u002Ffeatures\u002Ftypedef和using","Typedef和using","typedef 是 C 语言中的“老常客”，也是 C 程序员为了让代码更具可读性而最常用的“救星”之一，但是随着C++对的发展，现在地位主键被更为强大的using关键字取代了。",{"path":50,"title":51,"description":52},"\u002Fcpp\u002Ffmt\u002F函数模板实现类型自定义处理","函数模板实现类型自定义处理","函数模板的基本工作方式：",{"path":54,"title":55,"description":15},"\u002Fcpp\u002Fglfw窗口","GLFW窗口",{"path":57,"title":58,"description":59},"\u002Fcpp\u002Fopengel\u002F三角形绘制","三角形绘制","在学习此节之前，建议将这三个单词先记下来：",{"path":61,"title":62,"description":63},"\u002Fcpp\u002Fopengel\u002F光源和投光物","平行光","当一个光源处于很远的地方时，来自光源的每条光线就会近似于互相平行。不论物体和\u002F或者观察者的位置，看起来好像所有的光都来自于同一个方向。当我们使用一个假设光源处于无限远处的模型时，它就被称为定向光，因为它的所有光线都有着相同的方向，它与光源的位置是没有关系的。",{"path":65,"title":66,"description":67},"\u002Fcpp\u002Fopengel\u002F光照","光照","​\t现实世界中有无数种颜色，每一个物体都有它们自己的颜色。我们需要使用（有限的）数值来模拟真实世界中（无限）的颜色，所以并不是所有现实世界中的颜色都可以用数值来表示的。然而我们仍能通过数值来表现出非常多的颜色，甚至你可能都不会注意到与现实的颜色有任何的差异。颜色可以数字化的由红色(Red)、绿色(Green)和蓝色(Blue)三个分量组成，它们通常被缩写为RGB。仅仅用这三个值就可以组合出任意一种颜色。例如，要获取一个**珊瑚红(Coral)**色的话，我们可以定义这样的一个颜色向量：",{"path":69,"title":70,"description":71},"\u002Fcpp\u002Fopengel\u002F光照贴图","光照贴图","上一节中的那个材质系统是肯定不够的，它只是一个最简单的模型，所以我们需要拓展之前的系统，引入漫反射和镜面光贴图(Map)。这允许我们对物体的漫反射分量（以及间接地对环境光分量，它们几乎总是一样的）和镜面光分量有着更精确的控制。",{"path":73,"title":74,"description":75},"\u002Fcpp\u002Fopengel\u002F坐标和变换","坐标和变换","​\t尽管我们现在已经知道了如何创建一个物体、着色、加入纹理，给它们一些细节的表现，但因为它们都还是静态的物体，仍是不够有趣。我们可以尝试着在每一帧改变物体的顶点并且重配置缓冲区从而使它们移动，但这太繁琐了，而且会消耗很多的处理时间。我们现在有一个更好的解决方案，使用（多个）矩阵(Matrix)对象可以更好的变换(Transform)一个物体。当然，这并不是说我们会去讨论武术和数字虚拟世界（译注：Matrix同样也是电影「黑客帝国」的英文名，电影中人类生活在数字虚拟世界，主角会武术）。",{"path":77,"title":78,"description":15},"\u002Fcpp\u002Fopengel\u002F基础","基础",{"path":80,"title":81,"description":15},"\u002Fcpp\u002Fopengel\u002F摄像机","摄像机",{"path":83,"title":84,"description":85},"\u002Fcpp\u002Fopengel\u002F材质","材质","材质也就是将我们之前使用的三个光照结合起来，增加一个反光度分量，差不多像这样：",{"path":87,"title":88,"description":89},"\u002Fcpp\u002Fopengel\u002F核心模式和立即渲染模式","核心模式和立即渲染模式","​\t早期的OpenGL使用立即渲染模式（Immediate mode，也就是固定渲染管线），这个模式下绘制图形很方便。OpenGL的大多数功能都被库隐藏起来，开发者很少有控制OpenGL如何进行计算的自由。而开发者迫切希望能有更多的灵活性。随着时间推移，规范越来越灵活，开发者对绘图细节有了更多的掌控。立即渲染模式确实容易使用和理解，但是效率太低。因此从OpenGL3.2开始，规范文档开始废弃立即渲染模式，并鼓励开发者在OpenGL的核心模式(Core-profile)下进行开发，这个分支的规范完全移除了旧的特性。",{"path":91,"title":92,"description":93},"\u002Fcpp\u002Fopengel\u002F着色器","着色器","​\t在[Hello Triangle](https:\u002F\u002Flearnopengl-cn.github.io\u002F01 Getting started\u002F04 Hello Triangle\u002F)教程中提到，着色器(Shader)是运行在GPU上的小程序。这些小程序为图形渲染管线的某个特定部分而运行。从基本意义上来说，着色器只是一种把输入转化为输出的程序。着色器也是一种非常独立的程序，因为它们之间不能相互通信；它们之间唯一的沟通只有通过输入和输出。",{"path":95,"title":96,"description":97},"\u002Fcpp\u002Fopengel\u002F纹理","纹理","​\t我们已经了解到，我们可以为每个顶点添加颜色来增加图形的细节，从而创建出有趣的图像。但是，如果想让图形看起来更真实，我们就必须有足够多的顶点，从而指定足够多的颜色。这将会产生很多额外开销，因为每个模型都会需求更多的顶点，每个顶点又需求一个颜色属性。",{"path":99,"title":100,"description":15},"\u002Fcpp\u002Fopengel\u002F绘制一个窗口","绘制一个窗口",{"path":102,"title":103,"description":104},"\u002Fcpp\u002Fopengel\u002F资产和模型加载","资产和模型加载","一个非常流行的模型导入库是Assimp，它是Open Asset Import Library（开放的资产导入库）的缩写。Assimp能够导入很多种不同的模型文件格式（并也能够导出部分的格式），它会将所有的模型数据加载至Assimp的通用数据结构中。当Assimp加载完模型之后，我们就能够从Assimp的数据结构中提取我们所需的所有数据了。由于Assimp的数据结构保持不变，不论导入的是什么种类的文件格式，它都能够将我们从这些不同的文件格式中抽象出来，用同一种方式访问我们需要的数据。",{"path":106,"title":107,"description":15},"\u002Fcpp\u002Fstring\u002Fbasic_ostream","BasicOstream",{"path":109,"title":110,"description":15},"\u002Fcpp\u002Fwgc捕获迁移到electron","WGC捕获迁移到Electron",{"path":112,"title":113,"description":114},"\u002Fcpp\u002Fwmf完成高性能的音频处理","WMF完成高性能的音频处理","在 Windows 平台上，Media Foundation（常口头叫 WMF\u002FMF） 是比 FFmpeg 更「原生」的一套管线：系统 DLL + 可选显卡驱动的 MFT（Media Foundation Transform）。你可以用 IMFSinkWriter 把视频轨、音频轨mux进 MP4。",{"path":116,"title":117,"description":15},"\u002Fcpp\u002F优雅和正确的使用cpp的注释","优雅和正确的使用Cpp的注释",{"path":119,"title":120,"description":121},"\u002Fcpp\u002F安全\u002Fopenssl","Openssl","OpenSSL 是一个功能强大但学习曲线陡峭的库，我们可以从一个简单的base64编码的代码入手来学习这个库，逐步扩展到 OpenSSL 的核心概念和常见用法。",{"path":123,"title":124,"description":15},"\u002Fcpp\u002F性能分析工具tracy","性能分析工具Tracy",{"path":126,"title":127,"description":128},"\u002Fcpp\u002F自绘组件库思考","自绘组件库思考","如果先不管窗口管理的具体逻辑，我们先聚焦于绘制这个任务上面来。",{"path":130,"title":131,"description":132},"\u002Fcsharp\u002Fappdomain","Appdomain","​\tAppDomain（应用程序域）是.NET框架中的一个重要概念，主要用于隔离、加载和执行托管代码。它提供了一种轻量级的进程内隔离机制，使得多个应用程序可以在同一个进程中运行而不互相干扰。以下是关于AppDomain的一些关键点：",{"path":134,"title":135,"description":136},"\u002Fcsharp\u002Favalonia\u002Favalonia的composition-api-动画","Avalonia的composition Api 动画","composition api 可以为我们在所绑定的属性的值发生变化的时候自动产生隐式动画，这个可以为我们节省很多的时间，并且Composition API 是在渲染线程上执行的，而不是UI线程上执行的。",{"path":138,"title":139,"description":140},"\u002Fcsharp\u002Favalonia\u002Favalonia的动画","Avalonia的动画：","我们最常使用到的是avalonia的属性动画，比如Transitions标签，我们经常在style标签里去定义Property去指定Transitions，然后在Transitions标签中去影响所有的过渡类型。",{"path":142,"title":143,"description":15},"\u002Fcsharp\u002Favalonia\u002Favalonia的控件依赖属性指南大全","Avalonia的控件依赖属性指南大全",{"path":145,"title":146,"description":147},"\u002Fcsharp\u002Favalonia\u002Favalonia的渲染系统","Avalonia的渲染系统","​\t在了解avalonia的渲染系统之前我们需要先了解一下avlaonia的组件系统，所有的组加都继承于一个叫做Control的基类，代码为：",{"path":149,"title":150,"description":151},"\u002Fcsharp\u002Favalonia\u002Favalonia的跨平台属性","Avalonia的跨平台属性","Avalonia现在不只是支持linux平台，还支持Android平台开发，对于次，avalonia提供了两种标记扩展来实现区分平台的操作。",{"path":153,"title":154,"description":15},"\u002Fcsharp\u002Favalonia\u002Favalonia的选择器","Avalonia的选择器",{"path":156,"title":157,"description":158},"\u002Fcsharp\u002Favalonia\u002Favalonia通过继承templatedcontrol完成跳转动画","Avalonia通过继承TemplatedControl完成跳转动画","我们知道一点，就是：",{"path":160,"title":161,"description":162},"\u002Fcsharp\u002Favalonia\u002F合成渲染器","合成渲染器","自从avalonia的11更新以来，动画可以分为显示动画和隐式动画：",{"path":164,"title":165,"description":15},"\u002Fcsharp\u002Favalonia\u002F控件的生命周期","控件的生命周期",{"path":167,"title":168,"description":169},"\u002Fcsharp\u002Favalonia\u002F源码解读\u002F开头","开头","我一开始是打算用skia和yoga配合c++来完成我自己的ui组件库，由于我本身是很熟悉C#的，因此我打算学习现在最流行的跨平台组件库Avalonia，来看看他们是怎么实现的组件绘制的。",{"path":171,"title":172,"description":15},"\u002Fcsharp\u002Fc的多线程","C#的多线程",{"path":174,"title":175,"description":15},"\u002Fcsharp\u002Fc的流传输文件和断点下载","C#的流传输文件和断点下载",{"path":177,"title":178,"description":179},"\u002Fcsharp\u002Flinq","Linq","语言集成查询（LINQ）是.Net 3.5和Visual Studio 2008引入的功能强大的查询语言。LINQ可与C＃或Visual Basic一起使用，以查询不同的数据源。",{"path":181,"title":182,"description":183},"\u002Fcsharp\u002Fmediatr的消息机制原理","MediatR的消息机制原理","MediatR 库是建立在 C# 接口和 .NET Core 依赖注入 (DI) 容器之上的。它利用 DI 容器的生命周期管理和类型解析能力，实现了清晰的请求路由机制，它是一个典型的中介者模式的实现。发送者和接受者都不需要直接引用彼此，消息完全是在进程内传递，无需外部依赖，所有的通信都在进程里完成。并且通过了IMediator接口来统一处理请求\u002F响应和流式请求。",{"path":185,"title":186,"description":15},"\u002Fcsharp\u002Fmodbus通信协议","Modbus通信协议",{"path":188,"title":189,"description":190},"\u002Fcsharp\u002Fwebview2技术","Webview2技术","​\twebview2是一中混合模式开发的解决方案，它可以用来与生态丰富的web技术栈接轨，做到不损失过多性能的同时，做到快速开发和组件封装等作用。 并且它可以和navtive原生应用更多的接轨，能够使用更多的底层提供的api（虽然浏览器内核也提供了）。并且呢，webview2可以有持久更新的开发和固定版本的开发，可以自行选择。",{"path":192,"title":193,"description":15},"\u002Fcsharp\u002Fwpf\u002Fcommunity.mvvm.toolkit","CommunityMvvmToolkit",{"path":195,"title":196,"description":15},"\u002Fcsharp\u002Fwpf\u002Fhandycontrol\u002Fthemes","Themes",{"path":198,"title":199,"description":200},"\u002Fcsharp\u002Fwpf\u002Fhandycontrol\u002F工具类\u002F扩展","扩展","Extension文件夹是专门用于存放扩展类的地方，本质上是把常用小操作做成 xxx.Extension，让控件代码更简洁、可复用。这个目录有 11 个扩展类，按作用大概分四类：",{"path":202,"title":203,"description":15},"\u002Fcsharp\u002Fwpf\u002Fhandycontrol\u002F工具类\u002F转换器","转换器",{"path":205,"title":168,"description":206},"\u002Fcsharp\u002Fwpf\u002Fhandycontrol\u002F开头","这组笔记是为了学习HandyControl组件库而创建的，通过这次学习，我们可以掌握一个WPF组件库该如何设计，以及一些高级的设计方式。",{"path":208,"title":209,"description":210},"\u002Fcsharp\u002Fwpf\u002Finfluxdb时序数据库","InfluxDB时序数据库","​\t我们使用influxDBv2，它自带了一个webui的网页，可以实现图形化操作，以及有数据分析工具，十分的方便。",{"path":212,"title":213,"description":214},"\u002Fcsharp\u002Fwpf\u002Fitemscontrol控制子组件的加载","ItemsControl控制子组件的加载","为了实现一个高性能的组件，我们就不能依赖Item的index索引，因为非虚拟化情况下，1000个元素就是1000个延迟加载。我们需要实现的是用户拖动到1000个元素的时候，10个元素使瞬间被渲染出来的。",{"path":216,"title":217,"description":15},"\u002Fcsharp\u002Fwpf\u002Fscrollviewer实现鼠标的平滑滚动","WPF ScrollViewer 实现鼠标的平滑滚动",{"path":219,"title":220,"description":15},"\u002Fcsharp\u002Fwpf\u002Fwpf-ui组件库使用","Wpf Ui组件库使用",{"path":222,"title":223,"description":224},"\u002Fcsharp\u002Fwpf\u002Fwpf与win32编程","Wpf与win32编程","​\tWPF 框架本身已经为我们封装好了 95% 以上常用功能，让我们不必关心底层的窗体句柄（HWND）、消息循环（Message Loop）等复杂细节。但是，总有一些特殊的、更底层的系统功能，WPF 没有直接提供 C# 的接口。这时，我们就需要“下到地基”，通过 P\u002FInvoke (Platform Invocation，平台调用) 技术，直接使用 Win32 API 提供的原生能力。",{"path":226,"title":227,"description":15},"\u002Fcsharp\u002Fwpf\u002Fwpf和dll扩展加载","WPF和DLL扩展加载",{"path":229,"title":230,"description":231},"\u002Fcsharp\u002Fwpf\u002Fwpf的mstest-sdk单yuan测试","Wpf的mstest Sdk单元测试","​\t我们一般使用MSTest 测试项目，其中在创建单元测试项目的时候会遇到两个选择，就是问我们需不需要 Test Runner 。Test Runner有VSTest和 MSTest两个选项。 以及选择覆盖工具：Microsoft.CodeCoverage。",{"path":233,"title":234,"description":235},"\u002Fcsharp\u002Fwpf\u002Fwpf逻辑树和可视化树","Wpf逻辑树和可视化树","​\t在了解了wpf的基本的消息逻辑和渲染逻辑之后，我们可以来看看wpf的视图层，也就是要理解逻辑树和可视化树。",{"path":237,"title":238,"description":239},"\u002Fcsharp\u002Fwpf\u002Fxaml.behaviors.wpf","XamlBehaviorsWpf","XAML Behaviors 提供了一种简单易用的方法，能以最少的代码为 Windows UWP\u002FWPF 应用程序添加常用和可重复使用的交互性。",{"path":241,"title":242,"description":15},"\u002Fcsharp\u002Fwpf\u002Fxaml基础","Xaml基础",{"path":244,"title":245,"description":246},"\u002Fcsharp\u002Fwpf\u002F依赖属性和附加属性","依赖属性和附加属性","依赖属性是扩展对象自身的属性功能，比如说是数据绑定、动画，属性是属于定义它的类的，最经典的场景是Button的background。依赖属性的主要作用是提供一种比普通的 .NET 属性更强大的内存管理和功能支持。",{"path":248,"title":249,"description":15},"\u002Fcsharp\u002Fwpf\u002F基于propertychangedtrigger-(属性变更触发器)驱动的显式动画","基于 PropertyChangedTrigger (属性变更触发器) 驱动的显式动画",{"path":251,"title":252,"description":15},"\u002Fcsharp\u002Fwpf\u002F基于资源字典实现主题切换","基于资源字典实现主题切换",{"path":254,"title":255,"description":15},"\u002Fcsharp\u002Fwpf\u002F导航栏的指示器平滑移动","导航栏的指示器平滑移动",{"path":257,"title":258,"description":15},"\u002Fcsharp\u002Fwpf\u002F平台调用gdi32实现屏幕捕获等任务","平台调用gdi32实现屏幕捕获等任务",{"path":260,"title":261,"description":15},"\u002Fcsharp\u002Fwpf\u002F程序集合并dll","程序集合并（Costura.Fody）详解",{"path":263,"title":264,"description":15},"\u002Fcsharp\u002Fwpf\u002F继承contentcontrol来管理内容的加载","继承ContentControl来管理内容的加载",{"path":266,"title":267,"description":268},"\u002Fcsharp\u002Fwpf\u002F解包","解包","编写WPF的时候，使用CallMethodAction去通过反射调用对应的方法的时候，遇到了一个问题，那就是，在TargetObject中是不能使用Binding去绑定对象的。",{"path":270,"title":271,"description":15},"\u002Finterview-notes","Interview Notes",{"path":273,"title":274,"description":275},"\u002Ftest\u002Fabout-copy","About Content Version 3","Back home",{"path":277,"title":278,"description":279},"\u002Ftest\u002Ffan-toc-demo","扇形锚点导航测试页","这一页专门用来试 TocFanNav：下面的每个 ## 都会出现在右侧的扇形容器里，点击即可跳转。\n（测试用文件，不需要了直接删掉即可。）",{"path":281,"title":282,"description":15},"\u002Fvue\u002Faxios","Axios",{"path":284,"title":285,"description":286},"\u002Fvue\u002Fcli和脚手架","Cli和脚手架","CLI（命令行接口）脚手架，是指通过命令行界面（Command Line Interface）提供的一种自动化工具，用于快速创建、构建和初始化项目的工具集合。简单来说，它是一个可以帮助开发者快速搭建项目框架、配置环境、生成代码等的工具。",{"path":288,"title":289,"description":290},"\u002Fvue\u002Fdata为何以函数形式返回","data为何以函数形式返回","在使用Vue构建组件化应用时，每个组件的data属性都是以函数形式返回的，这主要是在组件化实现的时候，每个实例可以维护一份被返回对象的独立的拷贝，而不是共享同一个对象的引用。",{"path":292,"title":293,"description":294},"\u002Fvue\u002Fdollarrouter和dollarroute的区别","$router和$route的区别","Vue Router是Vue.js的路由管理器，路由就是SPA单页应用的访问路径，在Vue实例内部，可以通过$router访问路由实例，即在路由定义文件中export default的new Router(\u002F*...*\u002F)路由实例，通过$route可以访问当前激活的路由的状态信息，包含了当前URL解析得到的信息，还有URL匹配到的路由记录，可以将$router理解为一个容器去管理了一组$route，而$route是进行了当前URL和组件的映射。",{"path":296,"title":297,"description":298},"\u002Fvue\u002Felementui","ElementUI","-引言",{"path":300,"title":301,"description":302},"\u002Fvue\u002Feslint","Eslint","ESLint 是一个广泛使用的 JavaScript 和 TypeScript 静态代码分析工具，它的主要功能是帮助开发者识别和修复代码中的问题，确保代码质量符合团队或项目的标准。它通过检查代码中的潜在错误、风格问题和不符合规范的写法，提供了自动化的代码检查功能。",{"path":304,"title":305,"description":306},"\u002Fvue\u002Fmvvm模式的理解","MVVM模式的理解","MVVM全称Model-View-ViewModel是基于MVC和MVP体系结构模式的改进，MVVM就是MVC模式中的View的状态和行为抽象化，将视图UI和业务逻辑分开，更清楚地将用户界面UI的开发与应用程序中业务逻辑和行为的开发区分开来。",{"path":308,"title":309,"description":15},"\u002Fvue\u002Fnuxt\u002Fnuxt4","Nuxt4",{"path":311,"title":312,"description":313},"\u002Fvue\u002Fnuxt\u002Fnuxt和vuetify","Nuxt和vuetify","Nuxt 项目和传统的约定优于配置的理念，大大简化了项目结构",{"path":315,"title":316,"description":317},"\u002Fvue\u002Fnuxt\u002F动态组件","动态组件","如果你想使用 Vue 的 \u003Ccomponent :is=\"someComputedComponent\"> 语法，你需要使用 Vue 提供的 resolveComponent 辅助函数，或者直接从 #components 导入组件并将其传递给 is 属性。",{"path":319,"title":320,"description":321},"\u002Fvue\u002Fpinia","Pinia","​\tPinia 是 Vue 3 官方推荐的状态管理库，它是 Vuex 的继任者，专门为 Vue 3 设计。Pinia 提供了一个更加简洁、直观、功能强大的方式来管理和共享应用中的状态（数据）。",{"path":323,"title":324,"description":325},"\u002Fvue\u002Fruntime-dom","Runtime Dom","runtime-dom 是 Vue 3 源码中的一个核心包，它提供了与浏览器 DOM 相关的运行时功能。",{"path":327,"title":328,"description":329},"\u002Fvue\u002Fspa单页应用的优缺点","SPA单页应用的优缺点","Single Page Web Application是一种特殊的Web应用，其所有的活动局限于一个Web页面中，仅在该Web页面初始化时加载相应的HTML、JavaScript、CSS文件，一旦页面加载完成，SPA不会进行页面的重新加载或跳转，而是利用JavaScript动态的变换HTML，默认Hash模式是采用锚点实现路由以及元素组件的显示与隐藏实现交互，简单来说SPA应用只有一个页面，通常多页面应用会有多个页面不断跳转，而单页面应用始终在一个页面中，默认Hash模式是通过锚点实现路由以及控制组件的显示与隐藏来实现类似于页面跳转的交互。",{"path":331,"title":332,"description":333},"\u002Fvue\u002Fv-html可能导致的问题","v-html可能导致的问题","Vue中的v-html指令用以更新元素的innerHTML，其内容按普通HTML插入，不会作为Vue模板进行编译，如果试图使用v-html组合模板，可以重新考虑是否通过使用组件来替代。",{"path":335,"title":336,"description":337},"\u002Fvue\u002Fv-if与v-show的区别","v-if与v-show的区别","v-if指令与v-show指令都可以根据值动态控制DOM元素显示隐藏，v-if和v-show属于Vue的内部常用的指令，指令的职责是当表达式的值改变时把某些特殊的行为应用到DOM上。",{"path":339,"title":340,"description":341},"\u002Fvue\u002Fv-model数据绑定分析","v-model数据绑定分析","v-model是Vue提供的指令，其主要作用是可以实现在表单\u003Cinput>、\u003Ctextarea>及\u003Cselect>等元素以及组件上创建双向数据绑定，其本质上就是一种语法糖，既可以直接定义在原生表单元素，也可以支持自定义组件。在组件的实现中，可以配置子组件接收的prop名称，以及派发的事件名称实现组件内的v-model双向绑定。",{"path":343,"title":344,"description":345},"\u002Fvue\u002Fvite","Vite","Vite 是一个现代化的前端构建工具，主要用于开发和构建 JavaScript、TypeScript、Vue、React 等前端应用程序。Vite 由 Evan You（Vue.js 的创始人）开发，它的目标是提供一个极快的开发体验，同时确保构建性能也很高效。",{"path":347,"title":348,"description":349},"\u002Fvue\u002Fvitest","Vitest","Vitest 是一个现代的 JavaScript\u002FTypeScript 测试框架，它是基于 Vite 构建的，专为现代前端开发而设计。Vitest 目标是提供快速、可靠的测试工具，特别适用于使用 Vite 构建的应用程序。Vitest 兼容 Jest 的大多数 API，并且集成了 Vite 的构建工具，因此具有非常快的启动和测试执行速度。",{"path":351,"title":352,"description":15},"\u002Fvue\u002Fvue-cli4笔记","Vue-Cli4与Vue-Cli2区别浅谈",{"path":354,"title":355,"description":356},"\u002Fvue\u002Fvue3","Vue3","​",{"path":358,"title":359,"description":360},"\u002Fvue\u002Fvue3.0新特性","Vue3.0新特性","Vue3.0的设计目标可以概括为体积更小、速度更快、加强TypeScript支持、加强API设计一致性、提高自身可维护性、开放更多底层功能。",{"path":362,"title":363,"description":15},"\u002Fvue\u002Fvue3快速上手","1. Vue3简介",{"path":365,"title":366,"description":367},"\u002Fvue\u002Fvuerouter导航守卫","VueRouter导航守卫","vue-router提供的导航守卫主要用来通过跳转或取消的方式守卫导航，简单来说导航守卫就是路由跳转过程中的一些钩子函数，路由跳转是一个大的过程，这个大的过程分为跳转前中后等等细小的过程，而在每一个过程中都有钩子函数，这些钩子函数能使我们在这些过程中进行一些操作，这就是导航守卫。",{"path":369,"title":370,"description":371},"\u002Fvue\u002Fvuex中的核心方法","Vuex中的核心方法","Vuex是一个专为Vue.js应用程序开发的状态管理模式，其采用集中式存储管理应用的所有组件的状态，并以相应的规则保证状态以一种可预测的方式发生变化。每一个Vuex应用的核心就是store仓库，store基本上就是一个容器，它包含着你的应用中大部分的状态state。",{"path":373,"title":374,"description":375},"\u002Fvue\u002Fvuex和普通全局对象","Vuex和普通全局对象","在构建应用时，组件化与模块化开发以及多人开发各自组件的时候，不难保证各个组件都是唯一性的，多个组件共享状态肯定是存在的，而对多个共享状态进行维护是非常麻烦的，共享状态是谁都可以进行操作和修改的，这样就会导致所有对共享状态的操作都是不可预料的，所以就需要一个统一的管理进行维护。",{"path":377,"title":378,"description":379},"\u002Fvue\u002Fvue中computed分析","Vue中computed分析","在Vue中computed是计算属性，其会根据所依赖的数据动态显示新的计算结果，虽然使用{{}}模板内的表达式非常便利，但是设计它们的初衷是用于简单运算的，在模板中放入太多的逻辑会让模板过重且难以维护，所以对于任何复杂逻辑，都应当使用计算属性。计算属性是基于数据的响应式依赖进行缓存的，只在相关响应式依赖发生改变时它们才会重新求值，也就是说只要计算属性依赖的数据还没有发生改变，多次访问计算属性会立即返回之前的计算结果，而不必再次执行函数，当然如果不希望使用缓存可以使用方法属性并返回值即可，computed计算属性非常适用于一个数据受多个数据影响以及需要对数据进行预处理的条件下使用。",{"path":381,"title":382,"description":383},"\u002Fvue\u002Fvue中diff算法的理解","Vue中diff算法的理解","diff算法用来计算出Virtual DOM中改变的部分，然后针对该部分进行DOM操作，而不用重新渲染整个页面，渲染整个DOM结构的过程中开销是很大的，需要浏览器对DOM结构进行重绘与回流，而diff算法能够使得操作过程中只更新修改的那部分DOM结构而不更新整个DOM，这样能够最小化操作DOM结构，能够最大程度上减少浏览器重绘与回流的规模。",{"path":385,"title":386,"description":387},"\u002Fvue\u002Fvue中dollarnexttick的理解","Vue中$nextTick的理解","Vue中$nextTick方法将回调延迟到下次DOM更新循环之后执行，也就是在下次DOM更新循环结束之后执行延迟回调，在修改数据之后立即使用这个方法，能够获取更新后的DOM。简单来说就是当数据更新时，在DOM中渲染完成后，执行回调函数。",{"path":389,"title":390,"description":391},"\u002Fvue\u002Fvue中dollarrefs的理解","Vue中$refs的理解","$refs是一个对象，持有注册过ref attribute的所有DOM元素和组件实例。",{"path":393,"title":394,"description":395},"\u002Fvue\u002Fvue中key的作用","Vue中key的作用","key的特殊attribute主要用在Vue的虚拟DOM算法，在新旧Nodes对比时辨识VNodes。如果不使用key，Vue会使用一种最大限度减少动态元素并且尽可能的尝试就地修改、复用相同类型元素的算法，而使用key时，它会基于key的变化重新排列元素顺序，并且会移除key不存在的元素。此外有相同父元素的子元素必须有独特的key，重复的key会造成渲染错误。",{"path":397,"title":398,"description":399},"\u002Fvue\u002Fvue中数组变动监听","Vue中数组变动监听","Vue的通过数据劫持的方式实现数据的双向绑定，即使用Object.defineProperty()来实现对属性的劫持，但是Object.defineProperty()中的setter是无法直接实现数组中值的改变的劫持行为的，想要实现对于数组下标直接访问的劫持需要使用索引对每一个值进行劫持，但是在Vue中考虑性能问题并未采用这种方式，所以需要特殊处理数组的变动。",{"path":401,"title":402,"description":403},"\u002Fvue\u002Fvue中的三种watcher","Vue中的三种Watcher","Vue可以说存在三种watcher，第一种是在定义data函数时定义数据的render watcher，这种形式最为常见。第二种是computed watcher，是computed函数在自身内部维护的一个watcher，配合其内部的属性dirty开关来决定computed的值是需要重新计算还是直接复用之前的值。第三种就是watcher api了，就是用户自定义的export导出对象的watch属性，当然实际上他们都是通过class Watcher类来实现的。",{"path":405,"title":406,"description":407},"\u002Fvue\u002Fvue中组件间通信的方式","Vue中组件间通信的方式","Vue中组件间通信包括父子组件、兄弟组件、跨级组件、非嵌套组件之间通信。",{"path":409,"title":410,"description":411},"\u002Fvue\u002Fvue中虚拟dom的理解","Vue中虚拟DOM的理解","Virtual DOM是一棵以JavaScript对象作为基础的树，每一个节点称为VNode，用对象属性来描述节点，实际上它是一层对真实DOM的抽象，最终可以通过渲染操作使这棵树映射到真实环境上，简单来说Virtual DOM就是一个Js对象，用以描述整个文档。",{"path":413,"title":414,"description":415},"\u002Fvue\u002Fvue为何采用异步渲染","Vue为何采用异步渲染","Vue在更新DOM时是异步执行的，只要侦听到数据变化，Vue将开启一个队列，并缓冲在同一事件循环中发生的所有数据变更，如果同一个watcher被多次触发，只会被推入到队列中一次，这种在缓冲时去除重复数据对于避免不必要的计算和DOM操作是非常重要的。然后，在下一个的事件循环tick中，Vue刷新队列并执行实际(已去重的)工作，Vue在内部对异步队列尝试使用原生的Promise.then、MutationObserver和setImmediate，如果执行环境不支持，则会采用setTimeout(fn, 0)代替。",{"path":417,"title":418,"description":419},"\u002Fvue\u002Fvue事件绑定原理","Vue事件绑定原理","Vue中通过v-on或其语法糖@指令来给元素绑定事件并且提供了事件修饰符，基本流程是进行模板编译生成AST，生成render函数后并执行得到VNode，VNode生成真实DOM节点或者组件时候使用addEventListener方法进行事件绑定。",{"path":421,"title":422,"description":423},"\u002Fvue\u002Fvue学习笔记","Vue学习笔记","@TOC",{"path":425,"title":426,"description":427},"\u002Fvue\u002Fvue常用性能优化","Vue常用性能优化","Vue常用的一些优化方式，主要是在构建项目过程需要注意的方面。",{"path":429,"title":430,"description":431},"\u002Fvue\u002Fvue数据双向绑定","Vue数据双向绑定","Vue是通过数据劫持的方式来实现数据双向数据绑定的，其中最核心的方法便是通过Object.defineProperty()来实现对属性的劫持，该方法允许精确地添加或修改对象的属性，对数据添加属性描述符中的getter与setter实现劫持。",{"path":433,"title":434,"description":435},"\u002Fvue\u002Fvue源码解读-通用工具函数","Vue源码解读 通用工具函数","尝试将给定的值宽松地转换为数字\u002F**",{"path":437,"title":438,"description":15},"\u002Fvue\u002Fvue源码解读笔记共享工具库","Vue源码解读笔记共享工具库",{"path":440,"title":441,"description":442},"\u002Fvue\u002Fvue父子组件生命周期","Vue父子组件生命周期","Vue实例需要经过创建、初始化数据、编译模板、挂载DOM、渲染、更新、渲染、卸载等一系列过程，这个过程就是Vue的生命周期，Vue中提供的钩子函数有beforeCreate、created、beforeMount、mounted、beforeUpdate、updated、beforeDestroy、destroyed，父子组件嵌套时，父组件和子组件各拥有各自独立的钩子函数。",{"path":444,"title":445,"description":446},"\u002Fvue\u002Fvue生命周期","Vue生命周期","Vue实例需要经过创建、初始化数据、编译模板、挂载DOM、渲染、更新、渲染、卸载等一系列过程，这个过程就是Vue的生命周期，在Vue的整个生命周期中提供很多钩子函数在生命周期的不同时刻调用，Vue中提供的钩子函数有beforeCreate、created、beforeMount、mounted、beforeUpdate、updated、beforeDestroy、destroyed。",{"path":448,"title":449,"description":15},"\u002Fvue\u002Fvue的tree-shaking算法","Vue的tree Shaking算法",{"path":451,"title":452,"description":15},"\u002Fvue\u002Fvue的插槽和原理","Vue的插槽和原理",{"path":454,"title":455,"description":456},"\u002Fvue\u002Fvue路由hash模式分析","Vue路由Hash模式分析","Vue-router是Vue的核心组件，主要是作为Vue的路由管理器，Vue-router默认hash模式，即使用URL的Hash来模拟一个完整的URL，当URL改变时页面不会重新加载。",{"path":458,"title":459,"description":460},"\u002Fvue\u002Fvue路由history模式分析","Vue路由History模式分析","Vue-router是Vue的核心组件，主要是作为Vue的路由管理器，Vue-router默认hash模式，通过引入Vue-router对象模块时配置mode属性可以启用history模式。",{"path":462,"title":463,"description":464},"\u002Fvue\u002Fvue路由懒加载","Vue路由懒加载","对于SPA单页应用，当打包构建时，JavaScript包会变得非常大，影响页面加载速度，将不同路由对应的组件分割成不同的代码块，然后当路由被访问的时候才加载对应组件，这就是路由的懒加载。",{"path":466,"title":467,"description":468},"\u002Fvue\u002Fvue首屏性能优化组件","Vue首屏性能优化组件","简单实现一个Vue首屏性能优化组件，现代化浏览器提供了很多新接口，在不考虑IE兼容性的情况下，这些接口可以很大程度上减少编写代码的工作量以及做一些性能优化方面的事情，当然为了考虑IE我们也可以在封装组件的时候为其兜底，本文的首屏性能优化组件主要是使用IntersectionObserver以及requestIdleCallback两个接口。",{"path":470,"title":471,"description":472},"\u002Fvue\u002F代理","网络代理类型","根据代理服务器的功能和工作方式，网络代理可以分为以下几类：",{"path":474,"title":475,"description":476},"\u002Fvue\u002F对keep-alive组件的理解","对keep-alive组件的理解","当在组件之间切换的时候，有时会想保持这些组件的状态，以避免反复重渲染导致的性能等问题，使用\u003Ckeep-alive>包裹动态组件时，会缓存不活动的组件实例，而不是销毁它们。",{"path":478,"title":479,"description":480},"\u002Fvue\u002F文件格式","文件格式","​\tTSX 文件通常是 React 项目中的一种文件格式，用于表示含有 JSX（JavaScript XML）语法的 TypeScript 文件。它允许你在 TypeScript 中书写组件的 JSX 代码，并且提供了 TypeScript 的类型检查和其他功能。",{"path":482,"title":483,"description":484},"\u002Fvue\u002F服务端渲染ssr的理解","服务端渲染SSR的理解","SSR服务端渲染Server Side Render就是当进行请求时，页面上的内容是通过服务端渲染生成的，浏览器直接显示服务端返回的HTML即可。",{"path":486,"title":487,"description":488},"\u002Fvue\u002F构造模式","构造模式","Vite 和 Webpack 是两种流行的前端构建工具，它们在构建模式、性能、开发体验等方面有显著差异。以下是它们的详细对比：",{"path":490,"title":491,"description":492},"\u002Fvue\u002F源码解读\u002F目录","目录","这里是源码解读的开头，开通这个笔记的原因是因为想要深入理解一下Vue3的原理，能够清晰地知道现代的前端框架的具体实现，一个优秀的框架是如何开发出来的。",{"path":494,"title":495,"description":15},"\u002Fvue\u002F源码解读\u002F追踪和触发","追踪和触发",{"path":497,"title":498,"description":499},"\u002Fvue\u002F端到端测试工具","端到端测试工具","​\t端到端测试（End-to-End Testing，简称 E2E）是指从用户的角度对应用程序进行全面测试，模拟用户操作，验证整个系统的工作流程是否符合预期。这类测试通常包括前端界面、后端服务以及它们之间的交互。端到端测试工具是为了帮助开发人员和测试人员自动化这个过程。",1791042460924]