提交
This commit is contained in:
parent
04ac094e12
commit
9f516fb205
@ -330,3 +330,84 @@ search搜索时,用户在不断输入值时,用防抖来节约请求资源
|
||||
鼠标不断点击触发,mousedown(单位时间内只触发一次)
|
||||
|
||||
监听滚动事件,比如是否滑到底部自动加载更多,用throttle来判断
|
||||
|
||||
# Map 键值对
|
||||
|
||||
## 遍历MAP
|
||||
|
||||
### keys() 方法
|
||||
|
||||
该方法返回一个新的迭代器对象,它包括`Map`对象中每个元素的键。
|
||||
|
||||
```js
|
||||
const map = new Map();
|
||||
map.set('name', 'Alice');
|
||||
map.set('age', 25);
|
||||
|
||||
for (const key of map.keys()) {
|
||||
console.log(key);
|
||||
}
|
||||
// 输出:'name' 'age'
|
||||
```
|
||||
|
||||
### values() 方法
|
||||
|
||||
该方法返回一个新的迭代器对象,它包括`Map`对象中每个元素的值。
|
||||
|
||||
```js
|
||||
const map = new Map();
|
||||
map.set('name', 'Alice');
|
||||
map.set('age', 25);
|
||||
|
||||
for (const value of map.values()) {
|
||||
console.log(value);
|
||||
}
|
||||
// 输出:'Alice' 25
|
||||
```
|
||||
|
||||
### entries() 方法
|
||||
|
||||
该方法返回一个新的迭代器对象,它包括`Map`对象中每个元素的键值对。
|
||||
|
||||
```js
|
||||
const map = new Map();
|
||||
map.set('name', 'Alice');
|
||||
map.set('age', 25);
|
||||
|
||||
for (const [key, value] of map.entries()) {
|
||||
console.log(key + ': ' + value);
|
||||
}
|
||||
// 输出:'name: Alice' 'age: 25'
|
||||
```
|
||||
|
||||
### forEach() 方法
|
||||
|
||||
此方法接受一个回调函数作为参数,`Map`对象中的每个元素都会调用一次这个回调函数。回调函数中的参数依次为:`value`、`key`、`mapObject`。
|
||||
|
||||
```js
|
||||
const map = new Map();
|
||||
map.set('name', 'Alice');
|
||||
map.set('age', 25);
|
||||
|
||||
map.forEach((value, key) => {
|
||||
console.log(key, value);
|
||||
});
|
||||
// 输出:'name' 'Alice' 'age' 25
|
||||
```
|
||||
|
||||
## 进阶用法
|
||||
|
||||
### Map 和 Array 的相互转化
|
||||
|
||||
有时我们需要在 `Map` 和 `Array` 之间相互转化,比如将数组转换为字典,或者从字典转换为数组时,我们就可以结合 `Array` 构造函数和扩展运算符来实现。
|
||||
|
||||
```js
|
||||
let kvArray = [['key1', 'value1'], ['key2', 'value2']];
|
||||
let myMap = new Map(kvArray);
|
||||
console.log(myMap); // Map(2) {"key1" => "value1", "key2" => "value2"}
|
||||
|
||||
let arrayFromMap = Array.from(myMap);
|
||||
console.log(arrayFromMap); // [["key1", "value1"], ["key2", "value2"]]
|
||||
```
|
||||
|
||||
### Map 的合并和复制
|
||||
@ -1227,3 +1227,88 @@ stderr_logfile=/var/log/ckadminnetcore/err.log
|
||||
stdout_logfile=/var/log/ckadminnetcore/out.log
|
||||
stopasgroup=true
|
||||
```
|
||||
|
||||
## 安装 FastGithub
|
||||
|
||||
```shell
|
||||
wget https://gitee.com/chcrazy/FastGithub/releases/download/2.1.4/fastgithub_linux-x64.zip
|
||||
dnf install -y libicu
|
||||
# 配置系统代理
|
||||
# 配置系统环境变量
|
||||
vim /etc/profile
|
||||
|
||||
# 尾行加上
|
||||
export http_proxy="http://127.0.0.1:38457"
|
||||
export https_proxy="http://127.0.0.1:38457"
|
||||
|
||||
# 生效
|
||||
source /etc/profile
|
||||
|
||||
unzip fastgithub_linux-x64.zip
|
||||
cd fastgithub_linux-x64
|
||||
./fastgithub
|
||||
```
|
||||
|
||||
## 安装 ohmyzsh
|
||||
|
||||
### 安装zsh
|
||||
|
||||
```shell
|
||||
dnf install -y zsh
|
||||
```
|
||||
|
||||
### 脚本安装
|
||||
|
||||
```shell
|
||||
sh -c "$(wget -O- https://install.ohmyz.sh/)"
|
||||
```
|
||||
|
||||
### 配置
|
||||
|
||||
```shell
|
||||
vim ~/.zshrc
|
||||
|
||||
# 修改主题
|
||||
# ZSH_THEME='robbyrussell'
|
||||
ZSH_THEME='agnoster'
|
||||
|
||||
source ~/.zshrc
|
||||
```
|
||||
|
||||
### 切换为默认shell
|
||||
|
||||
```shell
|
||||
dnf install util-linux-user -y
|
||||
chsh -s /bin/zsh
|
||||
|
||||
#查看默认Shell
|
||||
echo $SHELL
|
||||
```
|
||||
|
||||
### 主题
|
||||
|
||||
- Powerlevel10K
|
||||
|
||||
```shell
|
||||
```
|
||||
|
||||
|
||||
|
||||
## 安装 ElasticSearch
|
||||
|
||||
```shell
|
||||
cd /etc/yum.repos.d
|
||||
vim elasticsearch.repo
|
||||
|
||||
[elasticsearch]
|
||||
name=Elasticsearch repository for 8.x packages
|
||||
baseurl=https://artifacts.elastic.co/packages/8.x/yum
|
||||
gpgcheck=1
|
||||
gpgkey=https://artifacts.elastic.co/GPG-KEY-elasticsearch
|
||||
enabled=0
|
||||
autorefresh=1
|
||||
type=rpm-md
|
||||
|
||||
dnf install --enablerepo=elasticsearch elasticsearch -y
|
||||
```
|
||||
|
||||
|
||||
@ -384,6 +384,16 @@ select @@log_bin_trust_function_creators;
|
||||
set GLOBAL log_bin_trust_function_creators=1;
|
||||
```
|
||||
|
||||
# 信息数据库(information_schema)
|
||||
|
||||
## 查看某数据库中所有表的行数
|
||||
|
||||
```mysql
|
||||
select table_name,table_rows from information_schema.tables
|
||||
where TABLE_SCHEMA = 'qyqdb'
|
||||
order by table_rows desc;
|
||||
```
|
||||
|
||||
# 主从搭建
|
||||
|
||||
## 主节点配置
|
||||
|
||||
@ -325,3 +325,209 @@ handler:
|
||||
|
||||
一个通常以函数作为属性的对象,各属性中的函数分别定义了在执行各种操作时代理 p 的行为。
|
||||
|
||||
# 组合式函数(Hook)
|
||||
|
||||
## 概述
|
||||
|
||||
在 Vue 应用的概念中,“组合式函数”(Composables)是一个利用 Vue 的组合式 API 来封装和复用**有状态逻辑**的函数。
|
||||
|
||||
当构建前端应用时,我们常常需要复用公共任务的逻辑。例如为了在不同地方格式化时间,我们可能会抽取一个可复用的日期格式化函数。这个函数封装了**无状态的逻辑**:它在接受一些输入后立刻返回所期望的输出。复用无状态逻辑的库很多,比如你可能已经用过的lodash或是date-fns。
|
||||
|
||||
相比之下,有状态逻辑负责管理会随时间而变化的状态。一个简单的例子是跟踪当前鼠标在页面中的位置。在实际应用中,也可能是像触摸手势或与数据库的连接状态这样的更复杂的逻辑。
|
||||
|
||||
## 约定和最佳实践
|
||||
|
||||
### 命名
|
||||
|
||||
组合式函数约定用驼峰命名法命名,并以“use”作为开头。
|
||||
|
||||
### 输入参数
|
||||
|
||||
即便不依赖于 ref 或 getter 的响应性,组合式函数也可以接受它们作为参数。如果你正在编写一个可能被其他开发者使用的组合式函数,最好处理一下输入参数是 ref 或 getter 而非原始值的情况。可以利用`toValue()`工具函数来实现:
|
||||
|
||||
```js
|
||||
import { toValue } from 'vue'
|
||||
|
||||
function useFeature(maybeRefOrGetter) {
|
||||
// 如果 maybeRefOrGetter 是一个 ref 或 getter,
|
||||
// 将返回它的规范化值。
|
||||
// 否则原样返回。
|
||||
const value = toValue(maybeRefOrGetter)
|
||||
}
|
||||
```
|
||||
|
||||
如果你的组合式函数在输入参数是 ref 或 getter 的情况下创建了响应式 effect,为了让它能够被正确追踪,请确保要么使用`watch()`显式地监视 ref 或 getter,要么在`watchEffect()`中调用`toValue()`。
|
||||
|
||||
## 封装下拉框Hook
|
||||
|
||||
```ts
|
||||
import { onMounted, reactive, ref } from 'vue';
|
||||
// 定义下拉框接收的数据格式
|
||||
export interface SelectOption {
|
||||
value: string;
|
||||
label: string;
|
||||
disabled?: boolean;
|
||||
key?: string;
|
||||
}
|
||||
// 定义入参格式
|
||||
interface FetchSelectProps {
|
||||
apiFun: () => Promise<any[]>;
|
||||
}
|
||||
|
||||
export function useFetchSelect(props: FetchSelectProps) {
|
||||
const { apiFun } = props;
|
||||
|
||||
const options = ref<SelectOption[]>([]);
|
||||
|
||||
const loading = ref(false);
|
||||
|
||||
/* 调用接口请求数据 */
|
||||
const loadData = () => {
|
||||
loading.value = true;
|
||||
options.value = [];
|
||||
return apiFun().then(
|
||||
(data) => {
|
||||
loading.value = false;
|
||||
options.value = data;
|
||||
return data;
|
||||
},
|
||||
(err) => {
|
||||
// 未知错误,可能是代码抛出的错误,或是网络错误
|
||||
loading.value = false;
|
||||
options.value = [
|
||||
{
|
||||
value: '-1',
|
||||
label: err.message,
|
||||
disabled: true,
|
||||
},
|
||||
];
|
||||
// 接着抛出错误
|
||||
return Promise.reject(err);
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
// onMounted 中调用接口
|
||||
onMounted(() => {
|
||||
loadData();
|
||||
});
|
||||
|
||||
return reactive({
|
||||
options,
|
||||
loading,
|
||||
});
|
||||
}
|
||||
```
|
||||
|
||||
组件调用
|
||||
|
||||
```vue
|
||||
<script setup name="DDemo" lang="ts">
|
||||
import { useFetchSelect } from './hook';
|
||||
|
||||
// 模拟调用接口
|
||||
function getRemoteData() {
|
||||
return new Promise<any[]>((resolve, reject) => {
|
||||
setTimeout(() => {
|
||||
// 模拟接口调用有概率出错
|
||||
if (Math.random() > 0.5) {
|
||||
resolve([
|
||||
{
|
||||
key: 1,
|
||||
name: '苹果',
|
||||
value: 1,
|
||||
},
|
||||
{
|
||||
key: 2,
|
||||
name: '香蕉',
|
||||
value: 2,
|
||||
},
|
||||
{
|
||||
key: 3,
|
||||
name: '橘子',
|
||||
value: 3,
|
||||
},
|
||||
]);
|
||||
} else {
|
||||
reject(new Error('不小心出错了!'));
|
||||
}
|
||||
}, 3000);
|
||||
});
|
||||
}
|
||||
|
||||
// 将之前用的 options,loading,和调用接口的逻辑都抽离到hook中
|
||||
const selectBind = useFetchSelect({
|
||||
apiFun: getRemoteData,
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<!-- 将hook返回的接口,通过 v-bind 绑定给组件 -->
|
||||
<a-select v-bind="selectBind" />
|
||||
</div>
|
||||
</template>
|
||||
```
|
||||
|
||||
## Loading状态hook
|
||||
|
||||
```ts
|
||||
import { Ref, ref } from 'vue';
|
||||
|
||||
type TApiFun<TData, TParams extends Array<any>> = (...params: TParams) => Promise<TData>;
|
||||
|
||||
interface AutoRequestOptions {
|
||||
// 定义一下初始状态
|
||||
loading?: boolean;
|
||||
// 接口调用成功时的回调
|
||||
onSuccess?: (data: any) => void;
|
||||
}
|
||||
|
||||
type AutoRequestResult<TData, TParams extends Array<any>> = [Ref<boolean>, TApiFun<TData, TParams>];
|
||||
|
||||
/* 控制loading状态的自动切换hook */
|
||||
export function useAutoRequest<TData, TParams extends any[] = any[]>(fun: TApiFun<TData, TParams>, options?: AutoRequestOptions): AutoRequestResult<TData, TParams> {
|
||||
const { loading = false, onSuccess } = options || { loading: false };
|
||||
|
||||
const requestLoading = ref(loading);
|
||||
|
||||
const run: TApiFun<TData, TParams> = (...params) => {
|
||||
requestLoading.value = true;
|
||||
return fun(...params)
|
||||
.then((res) => {
|
||||
onSuccess && onSuccess(res);
|
||||
return res;
|
||||
})
|
||||
.finally(() => {
|
||||
requestLoading.value = false;
|
||||
});
|
||||
};
|
||||
|
||||
return [requestLoading, run];
|
||||
}
|
||||
```
|
||||
|
||||
组件调用
|
||||
|
||||
```vue
|
||||
<script setup name="Index" lang="ts">
|
||||
import { useAutoRequest } from "./hook";
|
||||
import { Button } from "ant-design-vue";
|
||||
import { submitApi } from "@/api";
|
||||
|
||||
const [loading, submit] = useAutoRequest(submitApi);
|
||||
|
||||
function onSubmit() {
|
||||
submit("aaa").then((res) => {
|
||||
console.log("res", res);
|
||||
});
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="col">
|
||||
<Button :loading="loading" @click="onSubmit">提交</Button>
|
||||
</div>
|
||||
</template>
|
||||
```
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user