feat: 封装下拉框 hook (#40)
This commit is contained in:
parent
93a84b5fec
commit
9860c9a8e1
35
src/api/select.ts
Normal file
35
src/api/select.ts
Normal file
@ -0,0 +1,35 @@
|
||||
// import { request } from "@/utils/service"
|
||||
|
||||
/** 查 */
|
||||
export function getRemoteSelectData() {
|
||||
return new Promise<any>((resolve, reject) => {
|
||||
setTimeout(() => {
|
||||
// 模拟接口调用有概率出错
|
||||
if (Math.random() > 0.5) {
|
||||
resolve({
|
||||
code: 0,
|
||||
data: [
|
||||
{
|
||||
key: 1,
|
||||
label: "苹果",
|
||||
value: 1
|
||||
},
|
||||
{
|
||||
key: 2,
|
||||
label: "香蕉",
|
||||
value: 2
|
||||
},
|
||||
{
|
||||
key: 3,
|
||||
label: "橘子",
|
||||
value: 3
|
||||
}
|
||||
],
|
||||
message: "成功"
|
||||
})
|
||||
} else {
|
||||
reject(new Error("不小心出错了!"))
|
||||
}
|
||||
}, 3000)
|
||||
})
|
||||
}
|
60
src/hooks/useFetchSelect.ts
Normal file
60
src/hooks/useFetchSelect.ts
Normal file
@ -0,0 +1,60 @@
|
||||
import { onMounted, 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 selectedValue = ref("")
|
||||
|
||||
/* 调用接口请求数据 */
|
||||
const loadData = () => {
|
||||
loading.value = true
|
||||
options.value = []
|
||||
return apiFun().then(
|
||||
(res) => {
|
||||
loading.value = false
|
||||
options.value = res.data
|
||||
return res.data
|
||||
},
|
||||
(err) => {
|
||||
// 未知错误,可能是代码抛出的错误,或是网络错误
|
||||
loading.value = false
|
||||
options.value = [
|
||||
{
|
||||
value: "-1",
|
||||
label: err.message,
|
||||
disabled: true
|
||||
}
|
||||
]
|
||||
// 接着抛出错误
|
||||
return Promise.reject(err)
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
loadData()
|
||||
})
|
||||
|
||||
return {
|
||||
options,
|
||||
loading,
|
||||
selectedValue
|
||||
}
|
||||
}
|
1
src/icons/svg/component.svg
Normal file
1
src/icons/svg/component.svg
Normal file
@ -0,0 +1 @@
|
||||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1672728665955" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="3482" xmlns:xlink="http://www.w3.org/1999/xlink" width="16" height="16"><path d="M64 64h384v384H64V64z m0 512h384v384H64V576z m512 0h384v384H576V576z m192-128c106.039 0 192-85.961 192-192S874.039 64 768 64s-192 85.961-192 192 85.961 192 192 192z" p-id="3483"></path></svg>
|
After Width: | Height: | Size: 522 B |
@ -188,6 +188,21 @@ export const constantRoutes: RouteRecordRaw[] = [
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
path: "/select",
|
||||
component: Layout,
|
||||
children: [
|
||||
{
|
||||
path: "",
|
||||
component: () => import("@/views/select/index.vue"),
|
||||
name: "Select",
|
||||
meta: {
|
||||
title: "下拉框",
|
||||
svgIcon: "component"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
|
||||
|
16
src/views/select/index.vue
Normal file
16
src/views/select/index.vue
Normal file
@ -0,0 +1,16 @@
|
||||
<script setup name="Select" lang="ts">
|
||||
import { getRemoteSelectData } from "@/api/select"
|
||||
import { useFetchSelect } from "@/hooks/useFetchSelect"
|
||||
|
||||
const { loading, options, selectedValue } = useFetchSelect({
|
||||
apiFun: getRemoteSelectData
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="app-container">
|
||||
<el-select :loading="loading" v-model="selectedValue">
|
||||
<el-option v-for="(item, index) in options" v-bind="item" :key="index" />
|
||||
</el-select>
|
||||
</div>
|
||||
</template>
|
Loading…
x
Reference in New Issue
Block a user