@arco-vue-pro-components/pro-components
Version:
基于@arco-design/web-vue组件的高级组件,包括pro-table
274 lines (273 loc) • 7.28 kB
JavaScript
import { defineComponent, toRefs, ref, toRef, computed, watch, createVNode, mergeProps, isVNode } from "vue";
import { debounce } from "lodash";
import { Select, Option, Space } from "@arco-design/web-vue";
import { useSWR } from "swr-vue";
import { omit } from "../_utils/omit.js";
import { isUndefined, isNull, isNumber } from "../_utils/is.js";
import { usePureProp } from "../_hooks/use-pure-prop.js";
function _isSlot(s) {
return typeof s === "function" || Object.prototype.toString.call(s) === "[object Object]" && !isVNode(s);
}
let testId = 0;
var _ProSelect = defineComponent({
name: "ProSelect",
props: {
cacheForSwr: {
type: Boolean,
default: false
},
columnKey: {
type: String,
default: ""
},
requestSearch: {
type: Boolean,
default: false
},
mode: {
type: String,
default: void 0
},
multiple: {
type: Boolean,
default: void 0
},
modelValue: {
type: [String, Number, Object, Array]
},
fallbackOption: {
type: [Boolean],
default: false
},
defaultValue: {
type: [String, Number, Object, Array],
default: (props) => isUndefined(props.multiple) ? "" : []
},
placeholder: String,
bordered: {
type: Boolean,
default: true
},
disabled: {
type: Boolean,
default: false
},
error: {
type: Boolean,
default: false
},
options: {
type: Array,
default: () => []
},
valueKey: {
type: String,
default: "value"
},
size: {
type: String
},
searchDelay: {
type: Number,
default: 500
},
labelKey: {
type: String,
default: "label"
},
allowClear: {
type: Boolean,
default: true
},
allowSearch: {
type: Boolean,
default: true
},
request: {
type: Function
},
maxTagCount: {
type: Number,
default: 0
},
valueOption: {
type: Boolean,
default: false
}
},
emits: {
"update:modelValue": (value) => true,
"change": (value, option) => true
},
setup(props, {
attrs,
slots,
emit
}) {
var _a;
const {
valueKey,
labelKey,
multiple,
valueOption,
cacheForSwr
} = toRefs(props);
const selectRef = ref();
const options = usePureProp(props, "options");
const modelValue = toRef(props, "modelValue");
const keyword = ref("");
const loading = ref(false);
const cacheKey = computed(() => {
if (props.columnKey) {
return props.columnKey.toString();
}
if (props.request) {
testId += 1;
return testId.toString();
}
return "";
});
const fetchData = async () => {
if (!props.request) {
return [];
}
loading.value = true;
const res = await props.request(keyword.value);
loading.value = false;
return res || [];
};
const {
data
} = useSWR(() => {
if (!props.request) {
return null;
}
return `${cacheKey.value}_${props.requestSearch ? keyword.value : ""}`;
}, fetchData, {
revalidateIfStale: !cacheForSwr.value,
revalidateOnReconnect: cacheForSwr.value,
revalidateOnFocus: false
});
const optionsEnum = computed(() => {
var _a2, _b;
if (!props.request || !(props.mode === "read")) {
return {};
}
return ((_a2 = options.value) == null ? void 0 : _a2.length) ? (_b = options.value) == null ? void 0 : _b.reduce((pre, cur) => ({
...pre,
[cur[valueKey.value]]: cur[labelKey.value]
}), {}) : {};
});
const getFormatValue = (value2) => {
return isNumber(value2) ? `${value2}` : value2;
};
const getModelValue = (value2) => {
if (multiple.value && Array.isArray(value2) && value2.length) {
return value2.map((item) => getFormatValue(item));
}
return getFormatValue(value2);
};
const getSelectedOption = (modelValue2) => {
var _a2, _b;
if (multiple.value && Array.isArray(modelValue2) && modelValue2.length) {
if (options.value && options.value.length) {
const arr = modelValue2.map((mItem) => getSelectedOption(mItem));
return arr;
}
return [];
}
if (isUndefined(modelValue2) || isNull(modelValue2)) {
return void 0;
}
return (_b = (_a2 = options.value) == null ? void 0 : _a2.filter((item) => getFormatValue(item[valueKey.value]) === modelValue2)) == null ? void 0 : _b[0];
};
const _value = ref(getModelValue((_a = props.modelValue) != null ? _a : props.defaultValue));
watch(data, (data2) => {
if (props.request) {
options.value = data2 || [];
}
}, {
deep: true,
immediate: true
});
watch(modelValue, (value2) => {
if (isUndefined(value2) || isNull(value2)) {
_value.value = multiple.value ? [] : void 0;
} else {
_value.value = getModelValue(value2);
}
});
const value = computed({
get: () => {
return _value.value;
},
set: (val) => {
_value.value = val;
let option = void 0;
if (valueOption.value) {
option = getSelectedOption(val);
}
emit("update:modelValue", val);
emit("change", val, option);
}
});
const handleSearch = (value2) => {
keyword.value = value2;
};
const debounceSetKeyword = debounce((value2) => {
keyword.value = value2;
}, props.searchDelay || 500);
const handleClear = () => {
debounceSetKeyword("");
};
const handleInputValueChange = (value2) => {
if (!value2) {
debounceSetKeyword("");
}
};
const parsingText = (text) => {
if (Array.isArray(text)) {
let _slot;
return createVNode(Space, {
"size": 16
}, _isSlot(_slot = text.map((item) => createVNode("span", {
"key": item
}, [optionsEnum.value[item]]))) ? _slot : {
default: () => [_slot]
});
}
return optionsEnum.value[text];
};
const restProps = computed(() => omit(props, ["options"]));
return () => {
if (props.mode === "read") {
return parsingText(value.value);
}
return createVNode("div", {
"style": "width: 100%"
}, [createVNode(Select, mergeProps(restProps.value, attrs, {
"modelValue": value.value,
"onUpdate:modelValue": ($event) => value.value = $event,
"loading": loading.value,
"ref": selectRef,
"onSearch": handleSearch,
"onClear": handleClear,
"onInputValueChange": handleInputValueChange
}), {
default: () => {
return options.value.map((item) => createVNode(Option, {
"key": item[valueKey.value],
"value": getFormatValue(item[valueKey.value]),
"label": item[labelKey.value],
"title": item[labelKey.value],
"disabled": item.disabled
}, {
default: () => [item[labelKey.value]]
}));
},
...slots
})]);
};
}
});
export { _ProSelect as default };