This commit is contained in:
YUN-PC5\user 2023-09-08 15:14:45 +08:00
parent 7a24010250
commit 941bd1526f
11 changed files with 849 additions and 101 deletions

View File

@ -1,11 +1,11 @@
---
title: ASP.Net 6
title: ASP.Net
date: 2021-03-23 10:30:31
author: 文永达
top_img: https://gcore.jsdelivr.net/gh/volantis-x/cdn-wallpaper/abstract/67239FBB-E15D-4F4F-8EE8-0F1C9F3C4E7C.jpeg
---
# ASP.Net 6
# ASP.NET Core
## Web API 项目初始化搭建

View File

@ -1,11 +1,94 @@
---
title: C# DataTable
title: C#
date: 2021-03-23 10:30:31
author: 文永达
top_img: https://gcore.jsdelivr.net/gh/volantis-x/cdn-wallpaper/abstract/67239FBB-E15D-4F4F-8EE8-0F1C9F3C4E7C.jpeg
---
# C# DataTable
# 异步编程
## await
在C#中`await`关键字用于等待异步操作完成,并返回其结果。当遇到`await`关键字时C#编译器会暂停当前方法的执行并等待异步操作完成并返回结果。在等待异步操作的过程中C#编译器会继续执行其他代码例如设置变量的值。但是当异步操作完成后C#编译器会继续执行`await`关键字之后的代码。
下面是一个使用`await`关键字的示例,演示了如何等待异步操作完成:
```c#
using System;
using System.Net.Http;
using System.Threading.Tasks;
public class Example
{
public static async Task Main()
{
Console.WriteLine("Start");
var client = new HttpClient();
var response = await client.GetAsync("https://jsonplaceholder.typicode.com/todos/1");
var content = await response.Content.ReadAsStringAsync();
Console.WriteLine(content);
Console.WriteLine("End");
}
}
```
在这个示例中,我们使用`HttpClient`类来发送HTTP请求并使用`await`关键字等待响应。在`Main`方法中,我们首先打印"Start",然后使用`HttpClient`类发送GET请求并使用`await`关键字等待响应。在等待的过程中C#编译器会继续执行其他代码但是当响应返回后C#编译器会继续执行`await`关键字之后的代码,即读取响应内容并打印它。最后,我们打印"End"。
总之,当遇到`await`关键字时C#编译器会暂停当前方法的执行并等待异步操作完成并返回结果。在等待异步操作的过程中C#编译器会继续执行其他代码但是当异步操作完成后C#编译器会继续执行`await`关键字之后的代码。
# 枚举
在C#中我们可以使用枚举类型来定义一组相关的常量。枚举类型可以包含一个或多个枚举成员每个枚举成员都有一个名称和一个关联的值。在C# 8.0及以上版本中,我们可以使用`enum`关键字来定义字符串枚举类型。
下面是一个使用字符串枚举的示例:
```c#
enum Color {
Red,
Green,
Blue
}
enum Size {
Small,
Medium,
Large
}
enum Fruit {
Apple = 1,
Banana = 2,
Orange = 3
}
enum Animal {
[Description("狗")]
Dog,
[Description("猫")]
Cat,
[Description("鸟")]
Bird
}
enum ErrorCode {
[EnumMember(Value = "1001")]
InvalidInput,
[EnumMember(Value = "1002")]
Unauthorized,
[EnumMember(Value = "1003")]
NotFound
}
```
在这个示例中,我们定义了四个枚举类型`Color``Size``Fruit``Animal``Color``Size`是普通的枚举类型它们的枚举成员的值默认从0开始递增。`Fruit`是一个带有关联值的枚举类型,它的枚举成员的关联值可以是任何整数类型。`Animal`是一个带有描述信息的枚举类型,它的枚举成员使用了`Description`特性来指定描述信息。`ErrorCode`是一个带有序列化信息的枚举类型,它的枚举成员使用了`EnumMember`特性来指定序列化信息。
在使用枚举类型时,我们可以通过枚举成员的名称来访问枚举成员,例如`Color.Red``Size.Small``Fruit.Banana`等。我们也可以将枚举成员的值转换为字符串,例如`Color.Red.ToString()`会返回字符串`"Red"`
总之C#中的枚举类型可以用于定义一组相关的常量。在C# 8.0及以上版本中,我们可以使用`enum`关键字来定义字符串枚举类型。在使用枚举类型时,我们可以通过枚举成员的名称来访问枚举成员,也可以将枚举成员的值转换为字符串。
# DataTable
## 基础概念

View File

@ -1,14 +0,0 @@
---
---
# C# 反射
## Property
### Property.Name == 'PropName'
### Property.GetValue(from, null).Equals("NAME")

View File

@ -35,6 +35,30 @@ pom.xml引入依赖
# JetBrains Rider
## 快捷键
### CREATE AND EDIT(创建和编辑)
#### Show Context Actions(显示上下文操作)
Alt+Enter
#### Basic Code Completion(基本代码补全)
Ctrl+Space
#### Smart Code Completion(智能代码补全)
Ctrl+Shift+Space
#### Type Name Completion(类型名称补全)
Ctrl+Alt+Space
#### Complete Statement(完成语句)
Ctrl+Shift+Ent
## 安装CodeGlance Pro后关闭原有的在滚动条悬停时显示代码
CodeGlancePro是一款用于在编辑器旁边显示代码缩略图的插件。
@ -45,3 +69,18 @@ CodeGlancePro是一款用于在编辑器旁边显示代码缩略图的插件。
2. 在“Editor”中找到“General”选项卡。在这个选项卡中找到“Appearance”其中有一个“Show code lens on scrollbar hover”复选框。取消选中该复选框可隐藏在滚动条悬停时显示代码。
![image-20230322155611836](https://markdownhexo.oss-cn-hangzhou.aliyuncs.com/img/image-20230322155611836.png)
# IdeaVim
## 普通模式: `ESC`
### 基本移动命令:
- `h` 将光标向左移动一个字符。
- `l` 将光标向右移动一个字符。
- `k` 将光标向上移动一行。
- `j` 将光标向下移动一行。
- `w` 向前跳一个单词。
- `b` 向后跳一个单词。
- `0` 跳到行首。
- `$` 跳到行尾。

230
source/_posts/JavaScript.md Normal file
View File

@ -0,0 +1,230 @@
# 异步编程
## await
在JavaScript中`await`关键字用于等待一个异步操作完成,并返回异步操作的结果。当遇到`await`关键字时JavaScript引擎会暂停当前函数的执行直到异步操作完成并返回结果。在等待异步操作的过程中JavaScript引擎会继续执行其他代码。
因此,`await`关键字的执行顺序是从上到下的,即在遇到`await`关键字之前的代码会先执行,然后等待异步操作完成后,再执行`await`关键字之后的代码。如果在`await`关键字之前的代码中抛出了异常,那么`await`关键字之后的代码将不会执行。
在你提供的代码片段中,当遇到`await`关键字时JavaScript引擎会等待`addCoCertification``updateCoCertification`函数完成并返回它们的结果。在等待这些函数的过程中JavaScript引擎会继续执行其他代码例如设置`isAddedFile.value``dialogVisible.value`的值。当异步操作完成后JavaScript引擎会继续执行`await`关键字之后的代码,例如显示成功消息。
总之,`await`关键字的执行顺序是从上到下的,即在遇到`await`关键字之前的代码会先执行,然后等待异步操作完成后,再执行`await`关键字之后的代码。
下面是一个简单的示例,演示了`await`关键字的执行顺序:
```javascript
function sleep(ms) {
return new Promise(resolve => setTimeout(resolve, ms))
}
async function example() {
console.log('Start')
await sleep(1000)
console.log('After 1 second')
await sleep(2000)
console.log('After 2 more seconds')
console.log('End')
}
example()
```
在这个示例中,我们定义了一个`sleep`函数它返回一个Promise对象并在指定的时间后将其状态设置为resolved。然后我们定义了一个名为`example`的异步函数,它使用`await`关键字等待`sleep`函数完成,并在控制台中打印一些消息。在`example`函数中,我们使用`await`关键字等待`sleep(1000)`函数完成并在1秒后打印"After 1 second"。然后,我们再次使用`await`关键字等待`sleep(2000)`函数完成并在2秒后打印"After 2 more seconds"。最后,我们在控制台中打印"End"。
当我们调用`example`函数时JavaScript引擎会执行`console.log('Start')`语句,然后等待`sleep(1000)`函数完成。在等待的过程中JavaScript引擎会继续执行其他代码但是当`sleep(1000)`函数完成后JavaScript引擎会继续执行`await`关键字之后的代码,即打印"After 1 second"。然后JavaScript引擎会等待`sleep(2000)`函数完成并在2秒后打印"After 2 more seconds"。最后JavaScript引擎会打印"End"。
---
在同步方法中使用`await`关键字是不合法的,因为`await`只能在异步函数中使用。如果你在同步函数中使用`await`关键字,它会被视为普通的表达式,不会暂停当前函数的执行。
如果你需要在同步函数中等待一个异步操作完成,你可以使用`Promise`对象和`then`方法来实现。例如,你可以将异步操作封装在一个`Promise`对象中,并在`then`方法中处理结果。下面是一个示例:
```javascript
function sleep(ms) {
return new Promise(resolve => setTimeout(resolve, ms))
}
function example() {
console.log('Start')
sleep(1000).then(() => {
console.log('After 1 second')
return sleep(2000)
}).then(() => {
console.log('After 2 more seconds')
console.log('End')
})
}
example()
```
在这个示例中,我们定义了一个`sleep`函数它返回一个Promise对象并在指定的时间后将其状态设置为resolved。然后我们定义了一个名为`example`的同步函数,它使用`Promise`对象和`then`方法等待`sleep`函数完成,并在控制台中打印一些消息。在`example`函数中,我们使用`sleep(1000).then()`方法等待`sleep(1000)`函数完成并在1秒后打印"After 1 second"。然后,我们再次使用`then`方法等待`sleep(2000)`函数完成并在2秒后打印"After 2 more seconds"和"End"。
当我们调用`example`函数时JavaScript引擎会执行`console.log('Start')`语句,然后等待`sleep(1000)`函数完成。在等待的过程中JavaScript引擎会继续执行其他代码但是当`sleep(1000)`函数完成后JavaScript引擎会执行`then`方法中的代码,即打印"After 1 second"。然后JavaScript引擎会等待`sleep(2000)`函数完成并在2秒后打印"After 2 more seconds"和"End"。
# 数组
## map
`map`方法会对数组中的每个元素都执行一个回调函数,并返回一个新的数组,新数组中的元素是回调函数的返回值。`map`方法不会改变原始数组,而是返回一个新的数组。下面是一个使用`map`方法的示例:
```javascript
const numbers = [1, 2, 3, 4, 5];
const doubledNumbers = numbers.map((number) => number * 2);
console.log(doubledNumbers); // [2, 4, 6, 8, 10]
```
在这个示例中,我们使用`map`方法将数组中的每个元素都乘以2并返回一个新的数组`doubledNumbers`
## filter
`filter`方法会对数组中的每个元素都执行一个回调函数,并返回一个新的数组,新数组中的元素是回调函数返回`true`的元素。`filter`方法不会改变原始数组,而是返回一个新的数组。下面是一个使用`filter`方法的示例:
```javascript
const numbers = [1, 2, 3, 4, 5];
const evenNumbers = numbers.filter((number) => number % 2 === 0);
console.log(evenNumbers); // [2, 4]
```
在这个示例中,我们使用`filter`方法筛选出数组中的偶数,并返回一个新的数组`evenNumbers`
总之,`map``filter`都是JavaScript中常用的数组方法它们可以用于对数组进行转换和筛选。`map`方法会对数组中的每个元素都执行一个回调函数,并返回一个新的数组,新数组中的元素是回调函数的返回值。`filter`方法会对数组中的每个元素都执行一个回调函数,并返回一个新的数组,新数组中的元素是回调函数返回`true`的元素。
## reduce
`reduce()` 函数是 JavaScript 中的一个高阶函数,它可以将一个数组中的所有元素通过一个函数进行累加,最终返回一个累加结果。`reduce()` 函数接收两个参数:一个**回调函数**和一个**初始值**。回调函数接收四个参数:**累加器**、**当前元素**、**当前索引**和**原始数组**。在每次迭代中,回调函数都会将累加器和当前元素作为参数,并返回一个新的累加器值。最终,`reduce()` 函数返回最后一次调用回调函数时的累加器值。
```javascript
const numbers = [65, 44, 12, 4]
// total为 累加器 item为当前元素
// 0 为初始值,也就是 从什么值开始累加
const totalNumber = () => {
return numbers.reduce((total, item) => {
return total + item
}, 0)
}
```
# 循环
## for...in
`for...in`语句用于遍历对象的可枚举属性,包括对象自身的属性和继承的属性。在遍历时,`for...in`会将属性名作为变量传递给循环体,因此我们可以通过属性名来访问属性的值。下面是一个使用`for...in`语句遍历对象的示例:
```javascript
const obj = { a: 1, b: 2, c: 3 };
for (const key in obj) {
console.log(key, obj[key]);
}
// Output:
// a 1
// b 2
// c 3
```
在这个示例中,我们使用`for...in`语句遍历对象`obj`的属性,并将属性名作为变量`key`传递给循环体。在循环体中,我们可以通过`obj[key]`来访问属性的值。
## for...of
`for...of`语句用于遍历可迭代对象包括数组、字符串、Map、Set等。在遍历时`for...of`会将元素的值作为变量传递给循环体,因此我们可以直接访问元素的值。下面是一个使用`for...of`语句遍历数组的示例:
```javascript
const arr = [1, 2, 3];
for (const item of arr) {
console.log(item);
}
// Output:
// 1
// 2
// 3
```
在这个示例中,我们使用`for...of`语句遍历数组`arr`的元素,并将元素的值作为变量`item`传递给循环体。在循环体中,我们可以直接访问元素的值。
总之,`for...in``for...of`都是JavaScript中用于遍历数据结构的循环语句但它们的作用和用法有所不同。`for...in`语句用于遍历对象的可枚举属性,而`for...of`语句用于遍历可迭代对象的元素。
# 下载文件
## Url转Blob
```javascript
// xhr
function urlToBlob(url, callback) {
var xhr = new XMLHttpRequest();
xhr.open('GET', url, true);
xhr.responseType = 'blob';
xhr.onload = function() {
if (xhr.status === 200) {
var blob = xhr.response;
callback(null, blob);
} else {
callback(new Error('Unable to fetch blob'));
}
};
xhr.onerror = function() {
callback(new Error('Network error'));
};
xhr.send();
}
// fetch
function urlToBlob(url) {
return fetch(url)
.then(response => {
if (!response.ok) {
throw new Error('Unable to fetch blob');
}
return response.blob();
});
}
```
# 匿名函数和箭头函数
## 区别
匿名函数和箭头函数都是JavaScript中的函数形式它们之间有一些重要的区别。
1. 语法结构:匿名函数使用`function`关键字来定义,后面跟随函数名称(可选),参数列表和函数体。例如:
```javascript
var anonymousFunc = function(arg1, arg2) {
// 函数体
};
```
而箭头函数使用箭头操作符(`=>`)来定义,后面跟随参数列表和箭头函数体。没有显式的函数名称。例如:
```javascript
var arrowFunc = (arg1, arg2) => {
// 函数体
};
```
2. `this` 的指向:在匿名函数中,`this` 的指向是动态的,根据函数的调用方式而定。而在箭头函数中,`this` 的指向是词法作用域的,它继承自外围作用域。箭头函数没有自己的 `this` 值,它会使用外围作用域的 `this` 值。这使得箭头函数在处理函数上下文时更加方便。
3. `arguments` 对象:匿名函数中可以使用 `arguments` 对象访问函数的参数列表。而箭头函数没有自己的 `arguments` 对象,它会继承外围作用域中的 `arguments` 对象。
4. 构造函数:匿名函数可以用作构造函数来创建新对象。而箭头函数没有原型对象,因此不能用作构造函数,尝试使用 `new` 关键字调用箭头函数会抛出错误。
5. 箭头函数的简洁语法:箭头函数提供了更简洁的语法,尤其是在处理简单的函数体时。当函数体只有一条表达式时,可以省略花括号和 `return` 关键字,并将表达式的结果隐式返回。
这些是匿名函数和箭头函数之间的一些主要区别。选择使用哪种函数形式取决于具体的使用场景和需求。匿名函数适用于更传统的函数定义和需要动态 `this` 指向的情况,而箭头函数则提供了更简洁的语法和更方便的函数上下文处理。
# 运算符
## ~
在 JavaScript 中,`~` 符号是按位取反运算符。它将操作数的每个二进制位取反,即将 0 变为 1将 1 变为 0。然后返回这个值的负数加一。
例如,对于十进制数 10它的二进制表示为 1010按位取反后变为 0101即 5。因此`~10` 的结果为 -11。

View File

@ -430,6 +430,20 @@ source /etc/profile
firewall-cmd --add-port=6379/tcp --permanent
```
移除放行端口
```shell
firewall-cmd --permanent --remove-port=8080/tcp
```
查询端口是否开放
```shell
firewall-cmd --query-port=8080/tcp
```
任何修改操作配置完成后需要重新加载firewall
重新加载防火墙
```shell

View File

@ -0,0 +1,30 @@
# Maven
## Maven to Gradle
`pom.xml`文件所在的目录下执行:
```shell
gradle init # 根据pom.xml内容生成对应的gradle配置
gradle build # 开启gradle构建
```
# Gradle
## Gradle to Maven
`Gradle`项目转`Maven`项目需要借助一个Gradle插件在项目的`module``build.gradle`文件中加入以下配置即可
```shell
apply plugin: 'maven'
```
执行命令
``` shell
gradle install
```
完成之后将会在当前Module项目的build目录下的poms文件夹下生成pom-default.xml将其拷贝到项目的根目录下即可。

View File

@ -152,3 +152,8 @@ alter table [%QUALIFIER%]%TABLE% comment %.60qA:COMMENT%
单击确定就可以生成相应的代码,代码中就会出现上面的注释了。
![image-20230311001246849](https://markdownhexo.oss-cn-hangzhou.aliyuncs.com/img/image-20230311001246849.png)
## 在修改name的时候code的值将跟着变动
PowerDesign中的选项菜单里修改在[Tool]-->[General Options]->[Dialog]->[Operating modes]->[Name to Code mirroring],这里默认是让名称和代码同步,将前面的复选框去掉就行了。

View File

@ -45,88 +45,6 @@ export default defineConfig({
```
## npm包管理器
```shell
# 淘宝镜像
# 永久生效
npm config set registry http://registry.npm.taobao.org/
# 查看镜像
npm config get registry
# 暂时生效
npm install --registry http://registry.npm.taobao.org/
```
### CentOS7安装node js
```shell
# 首先下载nodejs安装包
# 解压 注意这不是gz压缩
tar -xvf node-v14.18.1-linux-x64.tar.xz
mv node-v14.18.1-linux-x64.tar.xz /usr/node
vim /etc/profile
# node
export NODE_HOME=/usr/node
export PATH=$PATH:$NODE_HOME/bin
source /etc/profile
# 查看node 版本
node -v
npm -v
# 安装yarn
npm install -g yarn
# 软连接,防止找不到环境
ln -s "/usr/node/bin/node" "/usr/local/bin/node"
ln -s "/usr/node/bin/npm" "/usr/local/bin/npm"
ln -s "/usr/node/bin/yarn" "/usr/local/bin/yarn"
```
## yarn包管理器
```shell
# PowerShell yarn : 无法加载文件 C:\Users\Admin\AppData\Roaming\npm\yarn.ps1,因为在此系统因为在此系统上禁止运行脚本。
# 以管理员方式运行powershell
set-ExecutionPolicy RemoteSigned
# 查看当前镜像
yarn config get registry
# https://registry.yarnpkg.com
# 更换镜像
yarn config set registry https://registry.yarnpkg.com
# 查看镜像是否成功
yarn config get registry
# 全局安装PTE脚手架
yarn global add generator-pte-cli
# 安装依赖
yarn
# 运行项目
yarn dev # yarn run dev
# 部署
# 具体看 package.json
yarn deploy
yarn build
# 移除依赖
yarn remove pte-ui
# 安装依赖
yarn add pte-ui@2.1.54
```
### 安装node-sass
```shell
# 安装gyp
npm install -g node-gyp
npm config set python python2.7
npm config set msvs_version 2017
yarn
```
## Vue CLI
### 安装
@ -1846,3 +1764,116 @@ export default ({ request }) => ({
# 包管理器
## npm包管理器
```shell
# 淘宝镜像
# 永久生效
npm config set registry http://registry.npm.taobao.org/
# 查看镜像
npm config get registry
# 暂时生效
npm install --registry http://registry.npm.taobao.org/
```
### CentOS7安装node js
```shell
# 首先下载nodejs安装包
# 解压 注意这不是gz压缩
tar -xvf node-v14.18.1-linux-x64.tar.xz
mv node-v14.18.1-linux-x64.tar.xz /usr/node
vim /etc/profile
# node
export NODE_HOME=/usr/node
export PATH=$PATH:$NODE_HOME/bin
source /etc/profile
# 查看node 版本
node -v
npm -v
# 安装yarn
npm install -g yarn
# 软连接,防止找不到环境
ln -s "/usr/node/bin/node" "/usr/local/bin/node"
ln -s "/usr/node/bin/npm" "/usr/local/bin/npm"
ln -s "/usr/node/bin/yarn" "/usr/local/bin/yarn"
```
## yarn包管理器
```shell
# PowerShell yarn : 无法加载文件 C:\Users\Admin\AppData\Roaming\npm\yarn.ps1,因为在此系统因为在此系统上禁止运行脚本。
# 以管理员方式运行powershell
set-ExecutionPolicy RemoteSigned
# 查看当前镜像
yarn config get registry
# https://registry.yarnpkg.com
# 更换镜像
yarn config set registry https://registry.yarnpkg.com
# 查看镜像是否成功
yarn config get registry
# 全局安装PTE脚手架
yarn global add generator-pte-cli
# 安装依赖
yarn
# 运行项目
yarn dev # yarn run dev
# 部署
# 具体看 package.json
yarn deploy
yarn build
# 移除依赖
yarn remove pte-ui
# 安装依赖
yarn add pte-ui@2.1.54
```
### 安装node-sass
```shell
# 安装gyp
npm install -g node-gyp
npm config set python python2.7
npm config set msvs_version 2017
yarn
```
### yarn和npm命令对比
| npm | yarn | 注释 |
| ------------------------------- | ---------------------------- | --------------------------------- |
| npm init | yarn init | 初始化项目 |
| npm install | yarn | 安装全部依赖 |
| npm install react --save | yarn add react | 安装某个依赖保存到dependencies |
| npm uninstall react --save | yarn remove react | 移除某个依赖 |
| npm install react --save-dev | yarn add react --dev | 安装某依赖保存到devDependencies |
| npm update react --save | yarn upgrade react | 更新某个依赖包 |
| npm install react --global | yarn global add react | 全局安装某个依赖 |
| npm install --save react axios | yarn add react axios | 同时安装多个依赖包 |
| npm install [package]@[version] | yarn add [package]@[version] | 安装指定版本的包 |
| npm rebuild | yarn install --force | 重新下载所有包 |
# 加密解密
## jsencrypt
### 安装
```shel
npm install jsencrypt --save-dev
```
引入
```javascript
import jsencrypt from 'jsencrypt'
```

327
source/_posts/Vue3.md Normal file
View File

@ -0,0 +1,327 @@
# 响应式
在Vue 3中响应式是通过`reactive`函数和`ref`函数实现的。`reactive`函数用于创建一个响应式对象,而`ref`函数用于创建一个包装对象,将基本类型的值转换为响应式对象。
具体来说,`reactive`函数接收一个普通对象作为参数,并返回一个响应式对象,如下所示:
```ts
import { reactive } from 'vue';
const state = reactive({
count: 0
});
```
在这个例子中,我们使用`reactive`函数创建了一个响应式对象`state`,它包含一个属性`count`初始值为0。
在组件中,你可以使用`setup`函数来访问响应式对象,如下所示:
```vue
<template>
<div>
<p>Count: {{ state.count }}</p>
<button @click="increment">Increment</button>
</div>
</template>
<script>
import { reactive } from 'vue';
export default {
setup() {
const state = reactive({
count: 0
});
const increment = () => {
state.count++;
};
return {
state,
increment
};
}
}
</script>
```
在这个例子中,我们在`setup`函数中访问了响应式对象`state`,并将它绑定到模板中。当点击按钮时,我们调用`increment`函数来增加`state.count`的值。由于`state`是响应式对象,当`state.count`的值发生变化时,模板中的内容也会自动更新。
除了`reactive`函数外Vue 3还提供了`ref`函数,用于将基本类型的值转换为响应式对象。例如,你可以使用`ref`函数来创建一个响应式的计数器,如下所示:
```ts
import { ref } from 'vue';
const count = ref(0);
```
在这个例子中,我们使用`ref`函数创建了一个响应式对象`count`它的初始值为0。
在组件中,你可以使用`setup`函数来访问响应式对象,如下所示:
```vue
<template>
<div>
<p>Count: {{ count }}</p>
<button @click="increment">Increment</button>
</div>
</template>
<script>
import { ref } from 'vue';
export default {
setup() {
const count = ref(0);
const increment = () => {
count.value++;
};
return {
count,
increment
};
}
}
</script>
```
在这个例子中,我们在`setup`函数中访问了响应式对象`count`,并将它绑定到模板中。当点击按钮时,我们调用`increment`函数来增加`count.value`的值。由于`count`是响应式对象,当`count.value`的值发生变化时,模板中的内容也会自动更新。
总之Vue 3中的响应式是通过`reactive`函数和`ref`函数实现的。`reactive`函数用于创建一个响应式对象,而`ref`函数用于将基本类型的值转换为响应式对象。你可以在`setup`函数中访问响应式对象,并将它们绑定到模板中。
# 依赖注入
Vue 3中的依赖注入是通过provide和inject实现的。provide和inject是一对API用于在父组件和子组件之间共享数据。具体来说provide用于在父组件中提供数据而inject用于在子组件中注入数据。
在父组件中你可以使用provide来提供数据如下所示
```vue
<script>
import { provide } from 'vue';
export default {
setup() {
const data = 'Hello, World!';
provide('data', data);
}
}
</script>
```
在子组件中你可以使用inject来注入数据如下所示
```vue
<script>
import { inject } from 'vue';
export default {
setup() {
const data = inject('data');
console.log(data); // 输出Hello, World!
}
}
</script>
```
在这个例子中,父组件提供了一个名为'data'的数据子组件通过inject来注入这个数据。注意子组件中的inject必须在setup函数中使用而且必须在模板中使用才能生效。
总之Vue 3中的依赖注入是通过provide和inject实现的它可以帮助你在父组件和子组件之间共享数据。
# 插槽
## 默认插槽
Vue 3中的插槽是通过`<slot>`元素实现的。插槽允许你在组件中定义一些占位符,然后在使用组件时填充这些占位符。具体来说,你可以在组件中使用`<slot>`元素来定义插槽,如下所示:
```vue
<template>
<div>
<h2>{{ title }}</h2>
<slot></slot>
</div>
</template>
```
在这个例子中,我们定义了一个名为`title`的属性和一个插槽。插槽使用了`<slot>`元素,它表示这里是一个插槽占位符,可以在使用组件时填充内容。
在使用组件时,你可以在组件标签中填充内容,如下所示:
```vue
<template>
<div>
<my-component title="Hello, World!">
<p>This is the content of the slot.</p>
</my-component>
</div>
</template>
```
在这个例子中,我们使用了`<my-component>`组件,并在组件标签中填充了一个`<p>`元素。这个`<p>`元素就是填充了组件中定义的插槽。
除了默认插槽外Vue 3还支持具名插槽和作用域插槽。具名插槽允许你定义多个插槽并在使用组件时指定要填充哪个插槽。作用域插槽允许你将数据传递给插槽内容以便在插槽中使用。
总之Vue 3中的插槽是通过`<slot>`元素实现的它允许你在组件中定义占位符并在使用组件时填充内容。除了默认插槽外Vue 3还支持具名插槽和作用域插槽。
## 具名插槽
在Vue 3中具名插槽允许你定义多个插槽并在使用组件时指定要填充哪个插槽。具名插槽可以通过在`<slot>`元素上添加`name`属性来定义,如下所示:
```vue
<template>
<div>
<slot name="header"></slot>
<slot></slot>
<slot name="footer"></slot>
</div>
</template>
```
在这个例子中,我们定义了三个插槽,其中第一个和第三个是具名插槽,分别使用了`name`属性来定义。第二个插槽没有使用`name`属性,它是默认插槽。
在使用组件时,你可以使用`v-slot`指令来指定要填充哪个插槽,如下所示:
```vue
<template>
<div>
<my-component>
<template v-slot:header>
<h1>This is the header slot.</h1>
</template>
<p>This is the default slot.</p>
<template v-slot:footer>
<p>This is the footer slot.</p>
</template>
</my-component>
</div>
</template>
```
在这个例子中,我们使用了`<my-component>`组件,并在组件标签中填充了三个插槽。使用`v-slot`指令来指定要填充哪个插槽,语法为`v-slot:name`,其中`name`是插槽的名称。
除了`v-slot`指令外Vue 3还支持另一种简写语法`#`,如下所示:
```vue
<template>
<div>
<my-component>
<template #header>
<h1>This is the header slot.</h1>
</template>
<p>This is the default slot.</p>
<template #footer>
<p>This is the footer slot.</p>
</template>
</my-component>
</div>
</template>
```
在这个例子中,我们使用了`#`来代替`v-slot`指令,语法更加简洁。
总之Vue 3中的具名插槽允许你定义多个插槽并在使用组件时指定要填充哪个插槽。你可以使用`v-slot`指令或`#`来指定要填充哪个插槽。
## 作用域插槽
在Vue 3中作用域插槽允许你将数据传递给插槽内容以便在插槽中使用。作用域插槽可以通过在`<slot>`元素上添加`v-bind`指令来定义,如下所示:
```vue
<template>
<div>
<slot v-bind:user="user"></slot>
</div>
</template>
```
在这个例子中,我们定义了一个作用域插槽,并使用了`v-bind`指令来将`user`数据传递给插槽内容。
在使用组件时,你可以在插槽标签中使用`v-slot`指令来定义插槽,并在插槽内容中使用传递的数据,如下所示:
```vue
<template>
<div>
<my-component>
<template v-slot:default="slotProps">
<p>{{ slotProps.user.name }}</p>
<p>{{ slotProps.user.age }}</p>
</template>
</my-component>
</div>
</template>
```
在这个例子中,我们使用了`<my-component>`组件,并在组件标签中填充了一个作用域插槽。使用`v-slot`指令来定义插槽,并使用`default`作为插槽的名称。在插槽内容中,我们可以通过`slotProps`来访问传递的数据。
除了`v-slot`指令外Vue 3还支持另一种简写语法`#`,如下所示:
```vue
<template>
<div>
<my-component>
<template #default="slotProps">
<p>{{ slotProps.user.name }}</p>
<p>{{ slotProps.user.age }}</p>
</template>
</my-component>
</div>
</template>
```
在这个例子中,我们使用了`#`来代替`v-slot`指令,语法更加简洁。
总之Vue 3中的作用域插槽允许你将数据传递给插槽内容以便在插槽中使用。你可以在`<slot>`元素上使用`v-bind`指令来定义作用域插槽,并在插槽标签中使用`v-slot`指令或`#`来定义插槽,并在插槽内容中使用传递的数据。
# 比较重要的知识点总结
## 对vue.js的响应式数据的理解
### Vue 2.x
**对象类型**:通过`object.defineProperty()`对属性的读取、修改进行拦截(数据劫持)
**数组类型**:通过重写更新数组的一系列方法来实现拦截(对数组的变更方法进行了包裹)
![图片](https://mmbiz.qpic.cn/sz_mmbiz_png/BOlSgLkrCDYqyTILUJ6mZmQ4qviaPgxpAaxTicvl4Ac1015TlUpn1HtF31qOwxu9AwqwTepicgyrFYoKIhMh3RObg/640?wx_fmt=png&wxfrom=5&wx_lazy=1&wx_co=1)
- 当你把一个普通的JavaScript对象传入Vue实例作为**data**选项Vue将遍历此对象所有的property并使用**Object.defineProperty**把这些property全部转为**getter/setter**。
- **Object.defineProperty**是ES5中一个无法shim的特性这也就是Vue不支持IE8以及更低版本浏览器的原因。
- 当使用这些数据属性是会进行依赖收集收集到当前组件的watcher
- 每个组件都对应一个watcher实例它会在组件渲染的过程中把“接触”过的数据记录为依赖之后当依赖项的setter触发时会通知watcher从而使它关联的组件重新渲染
**存在问题**
- 新增属性、删除属性,界面不会更新
- 直接通过下标修改数组,界面不会自动更新
### Vue 3.x
**通过Proxy代理**:拦截对象中任意属性的变化,包括:属性值的读写,属性的增加,属性的删除等。
**通过Reffect反射**:对源对象的属性进行操作
`Proxy`是 ECMAScript 6 中新增的属性。
Proxy对象用于创建一个对象的代理从而实现基本操作的拦截和自定义如属性查找、赋值、枚举、函数调用等
被Proxy代理虚拟化的对象。它常被作为代理得存储后端。根据目标验证关于对象不可扩展性或不可配置属性的不变量保持不变的语义
语法:
```javascript
const p = new Proxy(target, handler)
```
参数:
target
要使用 Proxy 包装的目标对象(可以是任何类型的对象,包括原生数组,函数,甚至另一个代理)。
handler
一个通常以函数作为属性的对象,各属性中的函数分别定义了在执行各种操作时代理 p 的行为。

View File

@ -189,3 +189,6 @@ message Person {
| `ulong?` | `google.protobuf.UInt64Value` |
| `string` | `google.protobuf.StringValue` |
| `ByteString` | `google.protobuf.BytesValue` |
## Dubbo 3