diff --git "a/\351\273\204\351\233\252\350\212\263/20240708_Cookie&Session&Token$JWT.md" "b/\351\273\204\351\233\252\350\212\263/20240708_Cookie&Session&Token$JWT.md" new file mode 100644 index 0000000000000000000000000000000000000000..f57d02395fa689151fb224cd3748aca4437e1033 --- /dev/null +++ "b/\351\273\204\351\233\252\350\212\263/20240708_Cookie&Session&Token$JWT.md" @@ -0,0 +1,212 @@ +## 一、基础概念 +### 1.认证 +验证当前用户的身份,互联网中的认证有: +- 用名密码登录 +- 邮箱发送登录链接 +- 手机号接收验证码等等 + +### 2.授权 +1. 用户授予第三方应用访问该用户某些资源的权限 +2. 实现授权的方式有:cookie、session、token、OAuth + +### 3.凭证 +- 实现认证和授权的前提是需要一种媒介(证书)来标记访问者的身份 +- 一般网站(如掘金)会有两种模式,游客模式和登录模式。游客模式下,可以正常浏览网站上面的文章,一旦想要点赞/收藏/分享文章,就需要登录或者注册账号。当用户登录成功后,服务器会给该用户使用的浏览器颁发一个令牌(token),这个令牌用来表明你的身份,每次浏览器发送请求时会带上这个令牌,就可以使用游客模式下无法使用的功能 + +## 二、Cookie +### 1.了解 +#### 1.基本概念 +- 存储在客户端:cookie 是服务器发送到用户浏览器并保存在本地的一小块数据,它会在浏览器下次向同一服务器再发起请求时被携带并发送到服务器上。因此,服务端脚本就可以读、写存储在客户端的cookie的值 +- 不可跨站:每个 cookie 都绑定在特定的域名下(绑定域名下的子域都是有效的),无法在别的域名下获取使用,同域名不同端口也允许共享 + +*可以在浏览器控制台的 Application 面板查看Cookie* +*Cookie都是name=value的结构,具体格式如下:* +~~~js +Set-Cookie: "name=value;domain=.domain.com;path=/;expires=Sat, 11 Jun 2016 11:29:42 GMT;HttpOnly;secure" +~~~ + +#### 2.Cookie的数据流转 +1. 在首次访问网站时,浏览器发送请求中并未携带Cookie +2. 浏览器看到请求中未携带Cookie,在HTTP的响应头中加入Set-Cookie +3. 浏览器收到Set-Cookie后,会将Cookie保存下来 +4. 下次再访问该网站时,HTTP请求头就会携带Cookie + +### 2.检测cookie是否启用 +有些用户为了避免隐私泄露会在它们的浏览器中禁用cookie。因此,在js代码使用cookie前,首先要确保cookie是启用的。可以用navigator.cookieEnabled属性来判断,如果值为true,则当前cookie是启用的;反之则是禁用的 +~~~js + if (navigator.cookieEnabled) { + // 浏览器启用了 Cookie + console.log("Cookies are enabled in this browser."); + } else { + // 浏览器禁用了 Cookie + console.log("Cookies are not enabled in this browser."); + } +~~~ +==注意:== +1. navigator.cookieEnabled 只能告诉你浏览器的 Cookie 设置,但不能告诉你具体的 Cookie 是否被服务器接受 +2. 某些浏览器或浏览器插件可能会篡改 navigator.cookieEnabled 的值,所以在处理敏感信息时,最好仍然验证实际的 Cookie 是否按预期工作 + +### 3.Cookie属性 +#### 有效期和作用域 +- 默认的有效期很短暂,它只能维持在Web浏览器的会话期间,一旦用户关闭浏览器,cookie保存的数据就丢失了 +- ookie的作用域不是局限在浏览器的单个窗口中,它的有效期和整个浏览器进程而不是单个浏览器窗口的有效期一致。如果想要延长cookie的有效期,可以通过设置max-age属性 +#### 常见属性 +1. name=valu(键值对):设置 Cookie 的名称及相对应的值,都必须是字符串类型 +2. domain(生效的域名):即Cookie在哪个网站生效。默认当前访问域名 +3. path:希望Cookie仅仅在部分路径下生效,就可以使用Path进行限制。默认的path=/,即在所有路径下生效。 如果设置了path=/abc,则只在/abc路径下生效 +4. expires(过期时间):当浏览器端本地的当前时间超过这个时间时,Cookie便会失效,格式【Expires=Wed, 21 Oct 2015 07:28:00 GMT】 +5. Max-age(存活时间)如果为正数,则该 cookie 在 maxAge 秒后失效。如果为负数,该 cookie 为临时 cookie ,关闭浏览器即失效,浏览器也不会以任何形式保存该 cookie 。如果为 0,表示删除该 cookie 。默认为 -1。==优先级高于expire== +6. HttpOnly:设置了 httpOnly 属性,则无法通过js读写该 cookie 的信息,但还是能通过 Application 中手动修改 cookie +7. secure:该cookie 是否仅被使用安全协议传输,默认为false;当 secure 值为 true 时,cookie 在 HTTP 中是无效的 +8. SameSite:是否允许跨站请求时发送Cookie +9. Priority:当Cookie的数量超过限制时,路蓝旗会清除一部分Cookie,Priority属性用来定义Cookie的优先级,低优先级的Cookie会优先被清除。优先级有 Low, Medium, High + +*cookie集合中的每个cookie都拥有这些属性,而且每个cookie的这些属性都是独立分开的,各自控制各自的cookie* + +### 4.对Cookie的存取 +#### 1.读取Cookie +~~~js +document.cookie; +// "name1=value1; name2=value2" +~~~ +#### 2.设置Cookie +~~~js +document.cookie = `name=${encodeURIComponent(name)}; max-age=1000;`; +// name这个cookie会被添加到现有的cookie集合中。 +// 由于cookie的键/值中的值是不允许包含分号、逗号和空白符,因此,在存储前一般可以采用 encodeURIComponent() 函数对值进行编码 +// 读取cookie值的时候要用 decodeURIComponent() 函数解码 +~~~ +#### 3.更新Cookie +要改变cookie的值,需要使用相同的名字、路径和域,但是新的值重新设置cookie的值 +#### 4.删除Cookie +要删除一个cookie,需要使用相同的名字、路径和域,然后指定一个任意(非空)的值,并且将 max-age 属性指定为0,再次设置cookie + +*其他详细见:https://blog.csdn.net/huangpb123/article/details/109107461* + +## 三、Session +### 1.了解 +会话用于跟踪用户在多个页面请求期间的状态。它们通常存储在服务器端,并且与唯一的会话标识符(通常是会话ID)相关联,会话ID作为Cookie发送给客户端。会话允许服务器在用户访问期间记住有关用户的信息 +![Session-2024-7-910:11:38.jpeg](https://gitee.com/huangxuefang0929/xiu_img/raw/master/Session-2024-7-910:11:38.jpeg) +### 2.session认证流程 +1. 用户第一次请求服务器的时候,服务器根据用户提交的相关信息,创建对应的 Session +2. 请求返回时将此 Session 的唯一标识 SessionID 返回给浏览器 +3. 浏览器接收到服务器返回的 SessionID 后,会将此信息存入到 Cookie 中,同时 Cookie 记录此 SessionID 属于哪个域名 +4. 当用户第二次访问服务器的时候,请求会自动把此域名下的 Cookie 信息也发送给服务端,服务端会从 Cookie 中获取 SessionID,再根据 SessionID 查找对应的 Session 信息,如果没有找到说明用户没有登录或者登录失效,如果找到 Session 证明用户已经登录可执行后面操作 +### 3.Cookie 和 Session 的区别 +- 安全性: Session 比 Cookie 安全,Session 是存储在服务器端的,Cookie 是存储在客户端的 +- 存取值的类型不同:Cookie 只支持存字符串数据,Session 可以存任意数据类型 +- 有效期不同: Cookie 可设置为长时间保持,比如我们经常使用的默认登录功能,Session 一般失效时间较短,客户端关闭(默认情况下)或者 Session 超时都会失效 +- 存储大小不同:单个 Cookie 保存的数据不能超过 4K,Session 可存储数据远高于 Cookie,但是当访问量过多,会占用过多的服务器资源 + +## 四、Token +### 1.了解 +Token 是访问接口(API)时所需要的资源凭证 +### 2.简单的token组成 +1. uid:用户唯一的身份标识 +2. time:当前时间的时间戳 +3. sign:签名,token 的前几位以哈希算法压缩成的一定长度的十六进制字符串 +### 3.Access Token +AccessToken身份验证流程如下: +![AccessToken-2024-7-910:16:23.jpeg](https://gitee.com/huangxuefang0929/xiu_img/raw/master/AccessToken-2024-7-910:16:23.jpeg) + +1. 客户端使用用户名跟密码请求登录 +2. 服务端收到请求,去验证用户名与密码 +3. 验证成功后,服务端会签发一个 token 并把这个 token 发送给客户端 +4. 客户端收到 token 以后,会把它存储起来,比如放在 localStorage 里 +5. 户端每次发起请求的时候需要把 token 放到请求的 Header 里传给服务端 +6. 服务端收到请求,然后去验证客户端请求里面带着的 token ,如果验证成功,就向客户端返回请求的数据 + +### 4.Refresh Token +- 专用于刷新 access token 的 token。如果没有 refresh token,也可以刷新 access token,但每次刷新都要用户输入登录用户名与密码,会很麻烦。有了 refresh token,可以减少这个麻烦,客户端直接用 refresh token 去更新 access token,无需用户进行额外的操作。 +- Access Token 的有效期比较短,当 Acesss Token 由于过期而失效时,使用 Refresh Token 就可以获取到新的 Token,如果 Refresh Token 也失效了,用户就只能重新登录了。 +- Refresh Token 及过期时间是存储在服务器的数据库中,只有在申请新的 Acesss Token 时才会验证,不会对业务接口响应时间造成影响,也不需要向 Session 一样一直保持在内存中以应对大量的请求 + +### 5.Toke和Session的区别 +- Session 是一种记录服务器和客户端会话状态的机制,使服务端有状态化,可以记录会话信息。而 Token 是令牌,访问资源接口(API)时所需要的资源凭证。Token 使服务端无状态化,不会存储会话信息 +- Session 和 Token 并不矛盾,作为身份认证 Token 安全性比 Session 好,因为每一个请求都有签名还能防止监听以及重复攻击,而 Session 就必须依赖链路层来保障通讯安全了。如果你需要实现有状态的会话,仍然可以增加 Session 来在服务器端保存一些状态 +- 如果你的用户数据可能需要和第三方共享,或者允许第三方调用 API 接口,用 Token 。如果永远只是自己的网站,自己的 App,用什么就无所谓了 + + +## 五、JWT +### 1.了解 +- JSON Web Token(简称 JWT)是目前最流行的跨域认证解决方案 +- JWT 的声明一般被用来在身份提供者和服务提供者间传递被认证的用户身份信息,以便于从资源服务器获取资源。比如用在用户登录上 + +### 2.原理 +服务器认证以后,生成一个 JSON 对象,返回给用户,就像下面这样 +~~~js +{ + "姓名": "张三", + "角色": "管理员", + "到期时间": "2018年7月1日0点0分" +} +~~~ +服务器完全只靠这个对象认定用户身份。为了防止用户篡改数据,服务器在生成这个对象的时候,会加上签名 + +### 3.JWT认证流程 +![JWT-2024-7-910:25:30.jpeg](https://gitee.com/huangxuefang0929/xiu_img/raw/master/JWT-2024-7-910:25:30.jpeg) + +*当用户希望访问一个受保护的路由或者资源的时候,需要请求头的 Authorization 字段中使用Bearer 模式添加 JWT,其内容看起来是下面这样* +~~~js +Authorization: Bearer +~~~ +- 服务端的保护路由将会检查请求头 Authorization 中的 JWT 信息,如果合法,则允许用户的行为 +- 因为 JWT 是自包含的(内部包含了一些会话信息),因此减少了需要查询数据库的需要 +- 因为 JWT 并不使用 Cookie 的,所以你可以使用任何域名提供你的 API 服务而不因为用户的状态不再存储在服务端的内存中,所以这是一种无状态的认证机制需要担心跨域问题 + +### 4.数据结构 + +- Header头部信息: + - Json对象,描述JWT的元数据,通常是以下样子 + ~~~js + { + "alg": "HS256", // 签名的默认算法 + "typ": "JWT" // token的类型 + } + ~~~ +- Payload负载: + - Json对象,用来存放实际需要传递的数据 + - JWT 默认是不加密的,任何人都可以读到,所以不要把秘密信息放在这个部分 + - 七个官方字段如下: + ~~~js + iss(issuer):签发人 + exp(expiration time):过期时间 + aud (audience):受众 + nbf (Not Before):生效时间 + iat (Issued At):签发时间 + jti (JWT ID):编号 + + + { + "sub": "1234567890", + "name": "John Doe", + "admin": true + } + ~~~ +- Signature签名: + - 是对前两部分的签名,防止数据篡改 + - 可以按照下面的公式产生签名 + ~~~js + HMACSHA256( + base64UrlEncode(header) + "." + + base64UrlEncode(payload), + secret) + ~~~ + +### 5.Token和JWT的区别 +**相同:** +1. 都是访问资源的令牌 +2. 都可以记录用户的信息 +3. 都是使服务端无状态化 +4. 都是只有验证成功后,客户端才能访问服务端上受保护的资源 + +**区别:** +1. Token:服务端验证客户端发送过来的 Token 时,还需要查询数据库获取用户信息,然后验证 Token 是否有效 +2. JWT: 将 Token 和 Payload 加密后存储于客户端,服务端只需要使用密钥解密进行校验(校验也是 JWT 自己实现的)即可,不需要查询或者减少查询数据库,因为 JWT 自包含了用户信息和加密的数据 + + +## 六、四者的区别 +![cstj四者的区别-2024-7-914:00:32.png](https://gitee.com/huangxuefang0929/xiu_img/raw/master/cstj%E5%9B%9B%E8%80%85%E7%9A%84%E5%8C%BA%E5%88%AB-2024-7-914:00:32.png) + +## 七、四者的优缺点 +![cstj四者的优缺点-2024-7-914:00:22.png](https://gitee.com/huangxuefang0929/xiu_img/raw/master/cstj%E5%9B%9B%E8%80%85%E7%9A%84%E4%BC%98%E7%BC%BA%E7%82%B9-2024-7-914:00:22.png) \ No newline at end of file diff --git "a/\351\273\204\351\233\252\350\212\263/20240709_\351\233\252\350\212\261\347\256\227\346\263\225.md" "b/\351\273\204\351\233\252\350\212\263/20240709_\351\233\252\350\212\261\347\256\227\346\263\225.md" new file mode 100644 index 0000000000000000000000000000000000000000..c248af51700a28d9a6a85a6a437e71a040af6d81 --- /dev/null +++ "b/\351\273\204\351\233\252\350\212\263/20240709_\351\233\252\350\212\261\347\256\227\346\263\225.md" @@ -0,0 +1,30 @@ +## 一、生成id的几种方法 +### 1.UUID +- UUID由于是在本地生成,因此具有极高的性能,然而,它生成的ID长度较长,达到16字节128位,通常需要使用字符串类型进行存储 +- UUID是无序的,其无序性可能会导致数据位置频繁变动,从而严重影响性能 + +### 2.数据库自增ID方式 +- 每次获取ID都需要进行数据库IO操作,给数据库带来较大压力,且性能较低 +- 创建具有可预测性,可能导致信息泄露风险 +- 一旦分配的ID被删除,那么这个ID就无法被再次使用,即使后续有新的记录需要插入,这可能导致ID空间的浪费 +- 可能由于ID冲突,不利于数据迁移和合并,特别是当合并的两个系统中存在重复的ID + +### 3.雪花算法 +- 以时间戳、机器标识和递增序列为基础生成ID,呈趋势递增,且性能很高 +- 算法的实现相对简单,不依赖于数据库等外部存储 +- Snowflake算法适用于分布式系统,生成的ID不依赖于中心化的存储或管理,每个节点可以独立生成ID而不会发生冲突 +- 由于它强烈依赖于机器时钟,因此需要考虑时钟回拨问题。即当机器上的时间因校正而发生倒退时,可能会导致生成的ID重复 + + +## 二、雪花算法的定义 +组成图如下: +![雪花算法结构-2024-7-923:07:35.webp](https://gitee.com/huangxuefang0929/xiu_img/raw/master/%E9%9B%AA%E8%8A%B1%E7%AE%97%E6%B3%95%E7%BB%93%E6%9E%84-2024-7-923:07:35.webp) + +1. 41位时间戳:这部分能够表示的时间跨度为(1L<<41)/(1000L*3600*24*365),即大约69年 +2. 10位机器ID:可以唯一标识最多1024台机器,如果需要对互联网数据中心(IDC)进行划分,可以将这10位拆分为两部分,例如各5位,这样,系统就能够表示最多32个IDC,且每个IDC下可以容纳32台机器 +3. 2位自增序列号:用于在同一毫秒内生成多个ID,最多可以表示2^12个不同的ID,因此,理论上,Snowflake算法能够达到的每秒查询率(QPS)约为409.6万 + + +## 三、代码实现snowflake +具体见: +[雪花算法详解](https://blog.csdn.net/prjh_/article/details/134654579) \ No newline at end of file diff --git "a/\351\273\204\351\233\252\350\212\263/20240710_ABP.md" "b/\351\273\204\351\233\252\350\212\263/20240710_ABP.md" new file mode 100644 index 0000000000000000000000000000000000000000..b1e0a4d89e642b8a147b14b32263340e6e5334d0 --- /dev/null +++ "b/\351\273\204\351\233\252\350\212\263/20240710_ABP.md" @@ -0,0 +1,66 @@ +### 一、什么是ABP +- ABP(ASP .NET Boilerplate Project)是基于DDD的经典分层架构思想 +- 基于领域驱动的理念来构架整个架构,其中领域驱动包含的概念有: + - 域 + - 子域 + - 聚合 + - 聚合根 + - 领域模型 + - 值对象 + - 通用仓储接口(底层:贴近数据库) + - 领域模型仓储接口 + - 领域服务接口 + - 应用服务接口 + - API服务接口(高层:贴近用户) + - 领域事件 + - 大脑风暴 + - 事件风暴 + *领域模型:一些不涉及其他对象(不是指其他类型,是指对象实例)的业务操作,放在领域模型(即Domain)* +- 具体层分析 + 1. 通用仓储接口:通用的仓储接口,其实现放在基础设施层、单独的一层ORM工具层 + 2. 领域模型仓储接口:领域独有的一些业务,可以写成领域模型接口,其实现放在Domain + 3. 领域服务接口:涉及到多个领域实体的业务和操作,放在领域服务 + 4. 应用服务接口:应用服务其实就是对领域模型业务和领域服务业务进行编排的一个层,比较薄 + 5. API服务接口:接受参数,最多做一些数据验证工作 + 6. 单元测试层Tests:提供应用层对象的模拟测试,其中测试的数据库使用的是EntityFramework的内存数据库,不影响实际数据库内容 + +### 二、采用的技术 +#### 服务端 +- ASP.NET MVC5、Web API2、C# +- DDD领域驱动设计 +- Castle windsor(依赖注入容器) +- Entity Framework6\EntityFrameworkCore\NHibernate、数据迁移 +- Log4Net(日志记录) +- AutoMapper(实现DTO类与实体类的双向自动转换) + +#### 客户端 +- Bootstrap +- Less +- Angular +- Vue +- jQuery +- Modernizr +- 其他JS库 + + +### 三、ABP框架的特点 +1. 依赖注入:这个部分使用Castle来实现依赖注入 +2. Repository仓储模式 +3. 身份验证与授权管理 +4. 数据有效性验证 +5. 审计日志记录 +6. Unit Of Work工作单元模式 +7. 异常处理 +8. 日志记录 +9. 多语言/本地化支持 +10. AutoMapping自动映射:实现领域对象和DTo对象的属性映射 +11. 动态WebAPI层 +12. 多租户支持 +13. 软删除支持 +14. 系统设置存取管理(系统级、租户级、用户级,作用范围自动管理) +15. 领域事件 +16. 模块以及模块的依赖关系实现插件化的模块处理 + +### 四、ABP架构图 +![ABP 架构图-2024-7-1114:01:03.png](https://gitee.com/huangxuefang0929/xiu_img/raw/master/ABP%20%E6%9E%B6%E6%9E%84%E5%9B%BE-2024-7-1114:01:03.png) + diff --git "a/\351\273\204\351\233\252\350\212\263/20240711_\346\265\213\350\257\225.md" "b/\351\273\204\351\233\252\350\212\263/20240711_\346\265\213\350\257\225.md" new file mode 100644 index 0000000000000000000000000000000000000000..172da86e2512490311e6d281ec94647ac14f5107 --- /dev/null +++ "b/\351\273\204\351\233\252\350\212\263/20240711_\346\265\213\350\257\225.md" @@ -0,0 +1,75 @@ +## 一、什么是测试 +- 测试是软件生命周期中一个非常重要的阶段,在应用程序的开发过程中,为了确保它的功能与预期一致,必须对其进行测试 +- 帮助开发员改正系统中所存在的缺陷,提高软件的可靠性 +- 测试应该覆盖到软件的所有功能,全面、细致的测试会在很大程度上节省软件开发的成本 + +## 二、测试的类型 +根据不同的维度,可以把测试方法分为不同的类型 +- 从结构的透明性方式,分为白盒测试、黑盒测试和灰盒测试 + - 白盒测试(结构测试):在已知程序的内部逻辑前提下,对程序内部结构进行验证 + - 黑盒测试(功能测试):将软件视为“黑盒”,在对程序内部实现未知的前提下,按照需求和预期结果对程序的功能进行测试 + - 灰盒测试:介于二者之间,在已知程序内部逻辑的前提下,对软件进行功能测试 +- 从测试执行方式,分为手工测试和自动化测试 + - 手工测试:要求测试人员与最终使用软件的用户一样,对软件功能进行实际操作并验证 + - 自动化测试:通过专业的测试软件、测试脚本騞自动化测试用例对软件进行测试 +- 从测试所涉及的层次,分为单元测试、集成测试和系统测试 + - 单元测试:验证代码段(如方法或函数)功能的测试,通常由开发人员编写相应的测试方法,以验证代码执行后与预期结果是否一致 + - 集成测试:用于验证具有依赖关系的多个模块或组件是否能够正常工作 + - 系统测试:对整个系统进行全面测试 + - 三者之间的关系如下: + ![b83eeabc92b59cd52d69bd7e27758ee-2024-7-1116:15:16.png](https://gitee.com/huangxuefang0929/xiu_img/raw/master/b83eeabc92b59cd52d69bd7e27758ee-2024-7-1116:15:16.png) + +## 三、单元测试层 +### 1.概念 +- 是指对软件中的最小可测试单元进行检查和验证,有助于确保领域模型的各个部分在随着时间推移和代码更改时保持稳定和正确性 +- 遵循Arrange-Act-Assert模式: + - Arrange:为测试进行准备操作,如设置测试数据 + - Act:执行要测试的方法,如调用要测试的函数和方法 + - Assert:断言测试结果,验证被测试方法的输出是否与预期的结果一样 +### 2.怎么写 +步骤: +1. 选择合适的单元:确定要测试的领域模型单元,如实体、值对象、聚合根等等 +2. 测试覆盖:确保测试覆盖所有重要的业务逻辑和边界情况 +3. 独立性:确保测试是独立于外部依赖的,例如数据库、网络服务等 +4. 清晰的测试名称:使用清晰而描述性的名称来命名测试 +5. 测试数据的准备和清理:在测试运行之前准备必要的测试数据,并且在测试结束后进行数据清理,以保证测试的一致性和独立性 +6. 持续集成和自动化:将单元测试整合到持续集成过程中,并自动运行以确保在代码更改时及时发现问题 +~~~C# +// 示例:测试添加用户是否成功 +// 假设有一个名为UserService的服务类负责用户管理(增删改查) +public class UserService +{ + privite List users = new List(); + public void AddUser(User newUser) + { + user.Add(newUser); + } + public bool UserExists(string username) + { + retrun users.Any(x=>x.Username == username); + } +} +// 测试文件 +[TestFixture] +public class UserServiceTests +{ + [Test] + public void AddUser_ShouldAddNewUser() + { + // 准备测试数据 + UserService userService = new UserService(); + User newUser = new User("abc","admin"); + + // 执行添加用户操作 + userService.AddUser(newUser); + + // 验证用户是否成功添加 + Assert.IsTrue(userServer.UserExixsts("admin")); + } +} +~~~ + +## 四、集成测试 +### 1.概念 +- 能够确保应用程序的组件正常工作,包括应用程序支持的基础结构,如数据库和文件系统等 +- 需要安装Microsoft.AspNetCore.Mvc.Testing包 \ No newline at end of file diff --git "a/\351\273\204\351\233\252\350\212\263/20240712_Antdv\347\232\204\344\275\277\347\224\250.md" "b/\351\273\204\351\233\252\350\212\263/20240712_Antdv\347\232\204\344\275\277\347\224\250.md" new file mode 100644 index 0000000000000000000000000000000000000000..0674acafe125d54c0f922d008cbc0c031254d52c --- /dev/null +++ "b/\351\273\204\351\233\252\350\212\263/20240712_Antdv\347\232\204\344\275\277\347\224\250.md" @@ -0,0 +1,65 @@ +## 一、引入 ant-design-vue +### 1.新建项目 +### 2.使用组件 +#### 1. 安装 +~~~js +npm i --save ant-design-vue@4.x +~~~ +#### 2. 注册 +1. 全局完整注册 +~~~js + import { createApp } from 'vue'; + import App from './App'; + // 以下完整引入antdv + import Antd from 'ant-design-vue'; + import 'ant-design-vue/dist/reset.css'; + + let app = createApp(App); + + app.use(Antd).mount('#app'); + // 样式文件需要单独引入 +~~~ +2. 全局部分注册 +~~~js + import { createApp } from 'vue'; + import { Button, message } from 'ant-design-vue'; + import App from './App'; + + let app = createApp(App); + + /* 会自动注册 Button 下的子组件, 例如 Button.Group */ + app.use(Button).mount('#app'); + + app.config.globalProperties.$message = message; +~~~ +3. 局部组件 +需要分别注册组件子组件,如 Button、ButtonGroup,并且注册后仅在当前组件中有效 +~~~js + // 选项式写法 + + + // 组合式写法 + + + +~~~ + +## 二、按需加载 +ant-design-vue 默认支持基于 ES modules 的 tree shaking,直接引入 import { Button } from 'ant-design-vue'; 就会有按需加载的效果 \ No newline at end of file