2025-04-12 23:21:56
摘要:一、实现DOM操作API
1. 构建环境
创建runtime-dom目录,存放dom操作api
创建runtime-core目录,存放允许时虚拟dom操作核心代码
在两个目录中分别构建环境
/packages/runtime-dom/package.json
{
name: @vue/runtime-dom,
module: dist/runtime-dom.esm-bundler.js,
unpkg: dist/runtime-dom.global.js,
buildOptions: {
name: VueRuntimeDOM,
formats: [
esm-bundler,
cjs,
global
]
}
}
/packages/runtime-core/package.json
{
name: @vue/runtime-core,
module: dist/runtime-core.esm-bundler.js,
unpkg: dist/runtime-core.global.js,
buildOptions: {
name: VueRuntimeCore,
formats: [
esm-bundler,
cjs,
global
]
}
}
2. 定义操作API
/packages/runtime-dom/src/nodeOps.ts
// dom操作 vue虚拟dom, 通过数据对象在内存中对比差异, 找到最小的改动点,使用dom操作完成更新。
// 原生dom操作api
export const nodeOps = {
// 插入, 追加
insert: (child, parent, anchor = null) = {
parent.insertBefore(child, anchor); // parent.appendChild(child)
},
// 删除子节点
remove: child = {
const parent = child.parentNode;
if (paren……
阅读全文
2025-04-05 18:21:43
摘要:Vue3响应式的实现跟Vue2最大的不同点是Vue3中的响应式是个独立模块,可以单独拿出来使用。
不仅仅响应式是模块化的,Vue3的设计理念也是基于模块化来设计的。而要使用Vue2的响应式,就必须加载整个Vue2的库。
一、rollup环境搭建
我们使用Vue3搭建上面的时候,经常会用到Vite,而Vite实际上是基于rollup实现的。
Rollup 是一个 JavaScript 模块打包工具,它可以将多个 JavaScript 文件(模块)打包成一个或多个优化后的文件。与 Webpack 类似,但 Rollup 更专注于 ES6 模块的打包,通常用于库/框架的开发。
除了rollup外,esbuild也是一个很不错的前端构建工具。
rollup
类库打包工具, 专注于模块的tree-shaking, 尽量减少模块打包的大小。
拥有庞大的插件生态系统,如代码拆分,语法转换等
常用于构建library, 特别是专注于es6模块
前端工程打包,一般使用webpack
esbuild
主要特点速度很快,用go编写,可以并行处理。
对ast语法树操作能力不太强, 老项目升级用esbuild
开发使用esbuild构建编译,生产打包使用成熟的rollup
接下来我们使用先使用rollup搭建一个本地环境
环境搭建
新建一个vue3的文件夹,然后安装rollup
yarn add rollup --dev
目录搭建
--packages # 因为Vue3是基于模块化来设计的,我们设计包文件的时候也分开构建,所以packages目录下都有会自己的项目文件
--reactivity # 响应式实现包
--dist
--node_modules
--src
index.ts
package.json
pnpm-lock.yaml
--shared # 公共库
--dist
--src
index.ts
package.json
--scripts
build.js
dev.js
.npmrc
package.json
pnpm-lock.yaml
rollup.config.js
tsconfig.json
基本配置
rollup.config.js
i……
阅读全文
2025-03-29 16:26:46
摘要:阅读vue(2.6)的源码,data响应式大概有如下4个过程:
数据代理:core/instance/state.js---vue函数---initMixin---initState---数据遍历---observer/index.js---Observer--- defineReactive---defineProperty
数据装载:$mount---装载template---compileToFunctions---mountComponet---创建【渲染Watcher】---Watcher.get()---Watcher.get()依赖收集---Dep.target就是当前的Watcher(data中的属性—dep-----watcher 形成双向引用)
数据相应式:需要修改data属性---触发setter回调执行---通知dep上的watcher更新dep.notify()---遍历所有的watcher并调用watcher的update方法---调用run方法---调用get()方法实现页面渲染
数据渲染:vm.__patch__---createPatchFunction---patchVnode---双方都有孩子节点updateChildrendiff代理
以下我们参考vue的源码,记录实现data响应式的全过程
一、数据劫持
收先我们混入一个方法,给Vue对象添加一个内部_init方法,我们在这个内部方法中去实现需要的功能
//index.js
import { initMixin } from ./init;
function Vue(options){ // vue2 配置项
console.log(my vue 6666)
this._init(options); // vue 内部约定 私有的方法或属性 一般是以 $ _ 开头
}
initMixin(Vue); // 一执行,Vue就有_init方法
export default Vue
//init.js 初始化
import { initState } from ./state;
// 混入 类似于 对象语言的继承
// 在不改变这个函数的前提下,给这个函数增加方法 增强功能
// 原理是在prototype上添加方……
阅读全文
2025-03-22 14:44:23
摘要:一、Vue3项目搭建
Node.js:是一个基于Chrome V8引擎的JavaScript运行环境,使用了一个事件驱动、非阻塞式I/O 模型,让JavaScript 运行在服务端的开发平台; 版本要求=12.0.0;
npm:Nodejs下的包管理器;版本要求 6.x yarn:包管理器;
yarn 包管理器是 npm 的一个替代方案,由Facebook于2016年10月发布。
Vite:是一个 web 开发构建工具,使用 Vite 可以快速构建 VUE 项目比webpack打包更加快速
快速的冷启动
即时的模块热更新
真正的按需编译
创建vite3项目:npm init vite,输入项目名称
安装依赖
cd vite-project 进入项目
依赖安装
npm install 或 cnmp i
运行vite项目:npm run dev
访问:http://localhost:5173
包管理工具Yarn的使用
yarn create vite:输入项目名称
cd vite-d2
安装依赖:yarn
项目启动:yarn dev
二、Vue3.2新特性
1. createApp
在 Vue 3 中,改变全局 Vue 行为的 API 现在被移动到了由新的 createApp 方法所创建的应用实例上。
import { createApp } from 'vue'
const app = createApp({})
该实例提供了一个应用上下文,由于 createApp 方法返回应用实例本身,因此可以在其后链式调用其它方法
import { createApp } from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'
const app = createApp(App);
app.use(store)
app.use(router)
app.mount('#app');
//合并之后的代码:
createApp(App).use(store).use(router).mount('#app')
2. setup函数
setup函数是vue3中专门为组件提供的新属性。
创建组件实例,然后初……
阅读全文
2025-03-08 15:14:23
摘要:一、let与const
let用来声明变量,它的用法类似于 var
不存在变量提升
同一个作用域内不能重复定义同一个名称
有着严格的作用域
const 声明一个只读的常量。一旦声明,常量的值就不能改变。
保持let的不存在变量提升,同一个作用域内不能重复定义同一个名称,有着严格的作用域
const 实际上保证的,并不是变量的值不得改动,而是变量指向的那个内存地址所保存的数据不得改动
window.onload = function () {
// let 和var的不同
// 1、不存在变量提升
// console.log(a);
// var a = 100;
// //解析过程
// //预解析
// var a;
// //逐行解析
// console.log(a);
// a = 100;
// //
// console.log(a); //Cannot access 'a' before initialization
// let a = 100;
//2、同一个作用域内不能重复定义同一个名称
// var a = 10;
// var a = 100;
// console.log(a); //100
// var a = 10;
// let a = 100;
// console.log(a); //Identifier 'a' has already been declared
// let a = 10;
// let a = 100;
// let a = 10;
// a = 100;
// console.log(a); //100
//3、有着严格的作用域
// function fn(){
// var a = 'a';
// if(true){ //块级作用域
// let a = 'b'
// };
// console.log(a) //'a'
// };
// fn();
……
阅读全文
2025-03-01 16:56:47
摘要:一、JS数据结构
js的数据定义与检查
var str = 'abc';
var num = 123;
var bool = true;
var und = undefined;
var n = null;
var arr=['x','y','z'];
var obj = {};
var fun = function() {};
console.log(typeof str); //string
console.log(typeof num); //number
console.log(typeof bool); //boolean
console.log(typeof und); //undefined
console.log(typeof n); //object
console.log(typeof arr); //object
console.log(typeof obj); //object
console.log(typeof fun); //function
1. 字符串
window.onload = function () {
// 字符串常用的属性和方法
// charAt() 方法可返回指定位置的字符。
// concat() 方法用于连接两个或多个字符串。
// indexOf() 方法可返回某个指定的字符串值在字符串中首次出现的位置。
// lastIndexOf() 方法可返回一个指定的字符串值最后出现的位置
// includes() 方法用于判断字符串是否包含指定的子字符串
// replace() 方法用于在字符串中用一些字符替换另一些字符,或替换一个与正则表达式匹配的子串
// split() 方法用于把一个字符串分割成字符串数组
// substr() 方法可在字符串中抽取从开始下标开始的指定数目的字符
// substring() 方法用于提取字符串中介于两个指定下标之间的字符
// slice(start, end) 方法可提取字符串的某个部分,并以新的字符串返回被提取的部分
// toLowerCase() 方法用于把字符串转换为小写
// toUpperCase() 方法用于把字……
阅读全文
2024-05-11 20:44:04
摘要:ABP框架并不重新发明轮子去实现认证,而是完美集成并简化了上述ASP.NET Core的认证流程。
模块化封装:当你使用ABP的启动模板时,认证的配置通常已经在模块中预先配置好,你只需要在appsettings.json中提供必要的参数(如JWT的签发者、密钥等)。
依赖注入集成:ABP通过ICurrentUser提供了对当前登录用户ID (UserId) 和租户ID (TenantId) 的便捷访问。这个接口的背后实现正是基于HttpContext.User及其声明(Claims)。
多租户支持:ABP的认证系统天然支持多租户,可以正确处理不同租户下的用户登录和会话管理。
ABP的主要价值在于整合与简化,它让你在使用强大的ASP.NET Core认证机制的同时,享受到ABP模块化和约定优先开发模式带来的便捷。
要学习好ABP的认证授权模块,我们来看一下ASP.NET Core的认证授权。
一、ASP.NET Core认证授权
1. 基本流程
UseAuthentication + AddAuthentication
UseAuthorization + AddAuthorization(.net源码内置)
[Authorize] [AllowAnonymous]
未登陆—访问—登陆—访问—退出
2. 理解认证
认证就是鉴别是张三----解读请求携带的用户信息
信息位置:怎么传递的凭证?Cookie,JWT,Other
信息格式:凭证是什么格式,加密问题
信息有效性:token过期了、签名不对
认证后信息保存:保存到context.User里面
特殊情况处理:没登陆、没权限、没xxx,这些就是认证需要知道的,需要干的活儿
登陆是怎么配合的?HttpContext.SignInAsync完成用户信息的写入(如:Cookie)
3. 理解授权
授权:就是检测下用户到底有没有权限访问某个方法
认证和授权的关系?
没有直接关系,认证获取用户信息保存到context.User,授权去使用
授权的时候,会用Scheme去认证一下,还有异常处理
检测凭据:
标记特性[Authorize] [AllowAnonymous]—就做授权检测
ASP.NET Core提供了灵活且强大的授权策略模型,主要包括:
基于角色的授权 ([Authorize(Roles =……
阅读全文
2024-05-04 21:43:26
摘要:前面重点介绍了ABP.vNext的模块化,以及模块化带来的核心价值动态API,今天我们开看一下ABP DI的扩展。
一、ABP DI功能介绍
1. 组件自动注册
SkipAutoServiceRegistration
AddAssemblyOf
AddAssembly
public class BlogModule : AbpModule
{
public override void PreConfigureServices(ServiceConfigurationContext context)
{
SkipAutoServiceRegistration = true;
}
public override void ConfigureServices(ServiceConfigurationContext context)
{
context.Services.AddAssemblyOfBlogModule();
}
}
2. 默认的注册
模块类注册为singleton
MVC控制器(继承Controller或AbpController)被注册为transient
MVC页面模型(继承PageModel或AbpPageModel)被注册为transient
MVC视图组件(继承ViewComponent或AbpViewComponent)被注册为transient
应用程序服务(实现IApplicationService接口或继承ApplicationService类)注册为transient
存储库(实现IRepository接口)注册为transient
域服务(实现IDomainService接口)注册为transient
3. 依赖接口
ITransientDependency 注册为transient生命周期
ISingletonDependency 注册为singleton生命周期
IScopedDependency 注册为scoped生命周期
4. 特性
DependencyAttribute:控制服务的注册行为和生命周期
ExposeServicesAttribute:控制服务以哪些类型注册到容器中
[ExposeServices(typeof(……
阅读全文
2024-04-27 16:12:33
摘要:前面我们介绍了Abp的模块化,号称能随意拆分,随意组装, 能各种复用,是真的超牛。
但是这样就可以了吗?虽然是可以任意组装了,比如A项目被拆分成A、B两个项目了。如何才能做的优雅,做的有意义?
ABP的答案是这样的: 最强CP——ADO(Auto API+Dynamic Client+Options)
模块化===能力复用
Auto API Controller:轻松组合到一个进程,也可以模块化独立部署,拆分分布式
Dynamic C# Client:服务之间的调用(跟本地调用一样),都不用改代码,就可以轻松替换成分布式调用
定制化需求:Options选项模式完成定制
一、Auto API Controllers
创建应用程序服务后, 通常需要创建API控制器以将此服务公开为 HTTP(REST)API端点
典型的API控制器除了将方法调用重定向到应用程序服务并使用[HttpGet],[HttpPost],[Route]等属性配置REST API之外什么都不做
瘦控制器:本身是可以不要的
ABP可以按照惯例自动将应用程序服务配置为API控制器
大多数时候不关心它的详细配置,但它可以完全被自定义,而且还可以做好复用
Auto-API-Controllers自动API控制器,可以不用写控制器Action了,就可以直接把应用服务暴露成WebAPI
1. 配置方法
服务标记成IRemoteService
配置AbpAspNetCoreMvcOptions
TypePredicate
ConventionalControllers.Create
以上就完成了Auto-API-Controller
2. 自定义HttpMethod
ABP在确定服务方法的HTTP Method时使用命名约定:
Get:如果方法名称以GetList,GetAll或Get开头
Put:如果方法名称以Put或Update开头
Delete:如果方法名称以Delete或Remove开头
Post:如果方法名称以Create,Add,Insert或Post开头
Patch:如果方法名称以Patch开头
其他情况,Post 为 默认方式
自定义HTTP Method,则可以使用标准ASP.NET Core的属性 ([HttpPost], [HttpGet], [HttpPut]..……
阅读全文
2024-04-20 12:05:23
摘要:在讲ABP的模块实现前,我们先来认识一下ABP。
一、初识ABP
1. ABP vNext是什么
ASP.NET Core的开源WEB应用程序框架——就是再封装一层,扩展了一系列的封装,完成了很多通用的。
ABP是用于创建现代Web应用程序的完整架构和强大的基础设施! 遵循最佳实践和约定,为你提供SOLID开发经验
https://www.abp.io/
https://github.com/abpframework/abp
2. 架构特点
应用程序模块化
领域驱动设计DDD
微服务架构
支持仓储,基于O/RM实现数据库无关性和MongoDB集成
可扩展及可替换
3. 基础设施
领域驱动设计
模块化设计
多租户
Dependency Injection
认证与授权
事件总线
数据访问
Auto API及动态代理
4. 其他组件
横切面关注
虚拟文件系统
数据过滤
本地化
异常处理
审计日志
二、开启ABP.vNext
1. 使用 ABP CLI 工具直接生成
超多内容,请自行查看。https://docs.abp.io/zh-Hans/abp/latest/CLI
也可以在 https://abp.io 直接生成
可以查看基础项目 BookStore,账号 admin,密码 1q2w3E*
自动化生成一次性生成了太多代码,不适合学习,接下来我们要研究一下手动集成
2. 手动集成控制台项目
手动创建一个.net core控制台项目,添加核心nuget包,Volo.Abp
创建一个HelloWorldService服务,使用瞬时生命周期
[Dependency(ServiceLifetime.Transient)]
public class HelloWorldService()
{
public void Run()
{
Console.WriteLine(Hello World);
}
}
ABP是模块化的,所以我们要创建一个模块类 AppModule
public class AppModule : AbpModule
{
public override void OnApplicationInitialization(ApplicationInitializationContext ……
阅读全文