preface

This article is a library designed to improve my experience with ant-design-vue. Since I didn’t find a similar example in a component, nor did the properties provided by it achieve this effect, I implemented it myself. To be honest, ant-design-vue is still a little bit strange to use. After all, element-UI is pretty handy.

rendering



The first load status effect of the cascade selector is automatically loaded for the first time in the document. If the first load fails, you will not know what to do.

Use the sample

<my-select placeholder=" @loaddata ="loadData" :options="options" V-model :value="value"></my-select> placeholder=" @loaddata ="loadData" :options="options" V-model :value="value"> const value = ref([]) const options = ref<any[]>([]) let num = 0 function loadData(action: () => void, done: (isDone? : Boolean) => void) {action() num++ setTimeout(() => {if(num>=3){options.value = [{value: 1, label: "apple "}, {value: 2, label: "banana "},] done()}else done(false)}, 2000); }Copy the code

Component source code

Relatively simple, temporarily do not write parsing, directly paste code

<template> <div class="my-select"> <a-cascader @change="changeSite" :value="value" @update:value="(v:any)=>emit('update:value', v)" :options="options" :placeholder="placeholder" style="width: 220px" :popupVisible="showSitePopup" @click="click" @focus="curSitePopup = true" @blur="curSitePopup = false" @popupVisibleChange="popupVisibleChange" > <template #suffixIcon ><LoadingOutlined v-if="siteStatus == EStatus.Loading" /> <CloseCircleOutlined style="color: red" v-if="siteStatus == EStatus.Error" /></template> </a-cascader> </div> </template> <script lang="ts" setup> import {  ref } from "vue" import { LoadingOutlined, CloseCircleOutlined } from "@ant-design/icons-vue" enum EStatus { Normal, Loading, Error, } const props = withDefaults( defineProps<{ value? : number[] options? : any[] alwaysLoad? : boolean placeholder? : string }>(), { value: () => [], options: () => [], alwaysLoad: false, placeholder: ", "}, ) const siteStatus = ref<EStatus>(EStatus.Normal) const curSitePopup = ref(false) const showSitePopup = ref(false) function popupVisibleChange(isOpen: boolean) { if (! isOpen) { showSitePopup.value = false } } function done(isDone: boolean = true) { if (isDone) { siteStatus.value = EStatus.Normal showSitePopup.value = curSitePopup.value } else { siteStatus.value = EStatus.Error } } function action() { siteStatus.value = EStatus.Loading } const emit = defineEmits<{  (e: "loadData", action: () => void, done: (isDone? : boolean) => void): void (e: "change", value: number[]): void (e: "update:value", value: any): void }>() function click() { if (siteStatus.value == EStatus.Loading) return if (! props.alwaysLoad && siteStatus.value == EStatus.Normal && props.options.length) { done() return } emit("loadData", action, done) } function changeSite(value: number[]) { emit("change", value) } </script> <style lang="less" scoped> .my-select { display: inline-block; :deep(.ant-cascader-picker-clear) { margin-right: 15px; } } </style>Copy the code