前言
总有一些常用hook,很常见但是网上不一定有, 所以在此记录一些个人认为常用的
文件选择器
前端选择文件总是依赖input, 常常需要自定义
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
| import {
onMounted,
onUnmounted
} from 'vue'
export const useFileSelector = () => {
const selector: HTMLInputElement = document.createElement('input')
selector.style.display = 'none'
selector.type = 'file'
const chooseFile = () => {
return new Promise((resolve, reject) => {
const onChange = () => {
const file = selector.files?.[0] || null
resolve(file)
selector.removeEventListener('change', onChange)
}
selector.addEventListener('change', onChange)
selector.click()
}
)
}
const toURL = (file: File) => {
return URL.createObjectURL(new Blob([ file ]))
}
onMounted(() => document.body.append(selector))
onUnmounted(() => selector.remove())
return {
chooseFile,
toURL
}
}
|
使用如上代码, 暴露一个chooseFile函数,
调用chooseFile函数,
等待异步返回的结果就是用户选择的文件
这里需要注意,如果用户没有选择文件,
而是关闭的对话框,
会返回null,所以需要特判
UseCharts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
| import { onBeforeUnmount, onMounted, ref, Ref, watch } from "vue";
import { EChartsOption, type EChartsType, init } from "echarts";
import { useThemeStore } from "@/store";
import { useResizeObserver } from "@vueuse/core";
export const useCharts = (data: Ref, fn: (data: any) => EChartsOption) => {
const themeStore = useThemeStore()
const container = ref<HTMLElement>()
let chartType: EChartsType | null = null
const initChart = () => {
if (container.value) {
chartType = init(container.value, themeStore.isLight ? undefined : 'dark', { renderer: 'svg' })
}
}
onMounted(() => {
initChart()
render()
})
const destroy = () => {
if (chartType) {
chartType.clear()
chartType.dispose()
chartType = null
}
}
watch(themeStore, () => {
destroy()
initChart()
render()
})
const resize = () => {
chartType?.resize()
}
useResizeObserver(container, () => {
resize()
})
const render = () => {
if (!chartType || !fn || !data?.value) return
const options = fn(data.value)
if (!options) return;
options.backgroundColor = ''
chartType.setOption(options)
}
watch(data, () => {
render()
})
onBeforeUnmount(() => {
destroy()
})
return { container }
}
|
axios
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
| import type { AxiosRequestConfig } from "axios";
import axios from "axios";
import { getToken } from "@/utils/authorization";
import { useMessageBox } from "@/utils/message";
interface HTTPResponse<T = any> {
code: number,
data: T,
message: string
}
const createRequestInstance = (baseURL: string) => {
const instance = axios.create({
baseURL, // base url for proxy
timeout: 1000 * 5 // wait for 5 second
})
const request = async <T = any>(config: AxiosRequestConfig): Promise<HTTPResponse<T>> => {
const msg = useMessageBox()
// const tokenKey =
const token = getToken()
// console.log(token)
if (!config.headers) {
config.headers = {}
}
if (token) {
// console.log('set???')
config.headers.Authorization = `${ token }`
}
const resp = await instance(config)
if (resp.data.code == 200) {
return resp.data
} else {
if (resp.data.message) {
msg?.error(resp.data.message)
}
throw (new Error(resp.data.message || 'Unexpect error'))
}
}
return { request }
}
const { request: v1 } = createRequestInstance("/api/v1")
export {
v1
}
|