@vrx-arco/pro-components
Version:
<p align="center"> <img src="https://vrx-arco.github.io/arco-design-pro/favicon.svg" width="200" height="250"> </p>
127 lines (126 loc) • 3.92 kB
JavaScript
import { style } from "../style/var.js";
import { provideSearchBar } from "./context.js";
import { createTextVNode, createVNode, defineComponent, onMounted, ref, toRaw, toRef } from "vue";
import { Button, Form, Row, Space } from "@arco-design/web-vue";
import { useGrid } from "@vrx-arco/use";
import { klona } from "klona/lite";
import { useAsyncLoading } from "@vrx/core";
import IconRefresh from "@vrx-arco/icons-vue/IconRefresh";
import IconSearch from "@vrx-arco/icons-vue/IconSearch";
const SearchBar = /* @__PURE__ */ defineComponent({
name: "vrx-arco-search-bar",
props: {
model: {
type: Object,
default: () => ({})
},
labelColProps: Object,
wrapperColProps: Object,
disabled: Boolean,
rules: [Object, Array],
resetOnButtonClick: {
type: Boolean,
default: false
},
validOnButtonClick: {
type: Boolean,
default: false
},
onSearch: Function,
onReset: Function,
column: {
type: [Number, Object],
default: () => ({
xs: 1,
sm: 2,
md: 2,
lg: 3,
xl: 3,
xxl: 4
})
},
autoUpdate: {
type: Boolean,
default: false
},
hideReset: {
type: Boolean,
default: false
},
hideAction: {
type: Boolean,
default: false
}
},
emits: ["search", "reset"],
setup: (props, { slots }) => {
const { bemClass } = style("search-bar");
const model = toRef(props, "model");
const column = toRef(props, "column");
const autoUpdate = toRef(props, "autoUpdate");
const { gridProps } = useGrid(true, column);
provideSearchBar({
gridProps,
model,
autoUpdate
});
const formRef = ref();
const resetModel = ref();
const { loading: searchLoading, run: searchRun } = useAsyncLoading();
const handleSearch = () => {
if (!props.validOnButtonClick) {
searchRun(Promise.resolve().then(() => props.onSearch?.(toRaw(model.value))));
return;
}
searchRun(formRef.value.validate().then((error) => error ? Promise.reject(error) : Promise.resolve()).then(() => props.onSearch?.(toRaw(model.value))));
};
const { loading: resetLoading, run: resetRun } = useAsyncLoading();
const handleReset = () => {
if (props.resetOnButtonClick) Object.keys(model.value).forEach((key) => {
model.value[key] = klona(resetModel.value[key]);
});
resetRun(Promise.resolve().then(() => props.onReset?.(toRaw(model.value))));
};
onMounted(() => {
resetModel.value = klona(model.value);
});
return () => {
const { labelColProps, wrapperColProps, disabled, hideAction, hideReset } = props;
const renderAction = () => {
if (hideAction) return;
return createVNode("div", { "class": bemClass("__button-box") }, [createVNode(Space, { "direction": "vertical" }, { default: () => [createVNode(Button, {
"type": "primary",
"onClick": handleSearch,
"loading": searchLoading.value,
"disabled": disabled || resetLoading.value,
"htmlType": "submit"
}, {
default: () => [createTextVNode("搜索")],
icon: () => createVNode(IconSearch, { "class": "arco-icon" }, null)
}), !hideReset && createVNode(Button, {
"onClick": handleReset,
"loading": resetLoading.value,
"disabled": disabled || searchLoading.value
}, {
default: () => [createTextVNode("重置")],
icon: () => createVNode(IconRefresh, { "class": "arco-icon" }, null)
})] })]);
};
return createVNode(Form, {
"ref": formRef,
"layout": "horizontal",
"labelAlign": "left",
"autoLabelWidth": true,
"model": model.value,
"wrapperColProps": wrapperColProps,
"labelColProps": labelColProps,
"disabled": disabled || resetLoading.value || searchLoading.value
}, { default: () => [createVNode("div", { "class": bemClass() }, [createVNode(Row, {
"align": "center",
"class": bemClass("__form-row"),
"gutter": [24, 8]
}, { default: () => [slots.default?.()] }), renderAction()])] });
};
}
});
export { SearchBar };