123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177 |
- import { defineComponent, h, inject, mergeProps, nextTick, PropType, reactive, ref } from "vue";
- import { Close } from "@element-plus/icons-vue";
- import { useBrowser, useConfig, useCore } from "../../hooks";
- import { renderNode } from "../../utils/vnode";
- import { useApi } from "../form/helper";
- export default defineComponent({
- name: "cl-adv-search",
- components: {
- Close
- },
- props: {
- // 表单项
- items: {
- type: Array as PropType<ClForm.Item[]>,
- default: () => []
- },
- // 标题
- title: String,
- // 窗体大小
- size: {
- type: [Number, String],
- default: "30%"
- },
- // 操作按钮
- op: {
- type: Array,
- default: () => ["clear", "reset", "close", "search"]
- },
- // 搜索钩子
- onSearch: Function
- },
- emits: ["reset", "clear"],
- setup(props, { emit, slots, expose }) {
- const { crud, mitt } = useCore();
- const { style } = useConfig();
- const browser = useBrowser();
- // 配置
- const config = reactive<ClAdvSearch.Config>(
- mergeProps(props, inject("useAdvSearch__options") || {})
- );
- // cl-form
- const Form = ref<ClForm.Ref>();
- // el-drawer
- const Drawer = ref();
- // 是否可见
- const visible = ref(false);
- // 打开
- function open() {
- visible.value = true;
- nextTick(function () {
- Form.value?.open({
- items: config.items || [],
- op: {
- hidden: true
- },
- isReset: false
- });
- });
- }
- // 关闭
- function close() {
- Drawer.value.handleClose();
- }
- // 重置数据
- function reset() {
- Form.value?.reset();
- emit("reset");
- search();
- }
- // 清空数据
- function clear() {
- Form.value?.clear();
- emit("clear");
- }
- // 搜素请求
- function search() {
- Form.value?.submit((data) => {
- function next(params: any) {
- Form.value?.done();
- close();
- return crud.refresh({
- ...params,
- page: 1
- });
- }
- if (config.onSearch) {
- config.onSearch(data, { next, close });
- } else {
- next(data);
- }
- });
- }
- // 消息事件
- mitt.on("crud.openAdvSearch", open);
- // 渲染表单
- function renderForm() {
- return h(<cl-form ref={Form} inner enable-plugin={false} />, {}, slots);
- }
- // 渲染底部
- function renderFooter() {
- const fns = { search, reset, clear, close };
- return config.op?.map((e: string) => {
- switch (e) {
- case "search":
- case "reset":
- case "clear":
- case "close":
- return h(
- <el-button />,
- {
- type: e == "search" ? "primary" : null,
- size: style.size,
- onClick: fns[e]
- },
- { default: () => crud.dict.label[e] }
- );
- default:
- return renderNode(e, {
- scope: Form.value?.getForm(),
- slots
- });
- }
- });
- }
- expose({
- open,
- close,
- clear,
- ...useApi({ Form }),
- reset
- });
- return () => {
- return (
- <el-drawer
- ref={Drawer}
- modal-class="cl-adv-search"
- v-model={visible.value}
- direction="rtl"
- with-header={false}
- size={browser.isMini ? "100%" : config.size}>
- <div class="cl-adv-search__header">
- <span class="text">{config.title || crud.dict.label.advSearch}</span>
- <el-icon size={20} onClick={close}>
- <Close />
- </el-icon>
- </div>
- <div class="cl-adv-search__container">{renderForm()}</div>
- <div class="cl-adv-search__footer">{renderFooter()}</div>
- </el-drawer>
- );
- };
- }
- });
|