提交
This commit is contained in:
parent
04ac094e12
commit
9f516fb205
@ -330,3 +330,84 @@ search搜索时,用户在不断输入值时,用防抖来节约请求资源
|
|||||||
鼠标不断点击触发,mousedown(单位时间内只触发一次)
|
鼠标不断点击触发,mousedown(单位时间内只触发一次)
|
||||||
|
|
||||||
监听滚动事件,比如是否滑到底部自动加载更多,用throttle来判断
|
监听滚动事件,比如是否滑到底部自动加载更多,用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
|
stdout_logfile=/var/log/ckadminnetcore/out.log
|
||||||
stopasgroup=true
|
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;
|
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 的行为。
|
一个通常以函数作为属性的对象,各属性中的函数分别定义了在执行各种操作时代理 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