wangzhibo
2026-07-16 b57020623cf0c946706573bf102e548c3a544423
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
import { CloseBold, Search } from "@element-plus/icons-vue";
import { h } from "vue";
import { useCrud } from "../../../hooks";
import { renderNode } from "../../../utils/vnode";
 
export function renderHeader(item: ClTable.Column, { scope, slots }: any) {
    const crud = useCrud();
 
    const slot = slots[`header-${item.prop}`];
 
    if (slot) {
        return slot({
            scope
        });
    }
 
    if (!item.search || !item.search.component) {
        return item.label;
    }
 
    // 显示输入框
    function show(e: MouseEvent) {
        item.search.isInput = true;
        e.stopPropagation();
    }
 
    // 隐藏输入框
    function hide() {
        if (item.search.value !== undefined) {
            item.search.value = undefined;
            refresh();
        }
 
        item.search.isInput = false;
    }
 
    // 刷新
    function refresh(params?: any) {
        const { value } = item.search;
 
        crud.value?.refresh({
            page: 1,
            [item.prop]: value === "" ? undefined : value,
            ...params
        });
    }
 
    // 文字
    const text = (
        <div class="cl-table-header__search-label" onClick={show}>
            <el-icon size={14}>{item.search.icon?.() ?? <Search />}</el-icon>
 
            {item.renderLabel ? item.renderLabel(scope) : item.label}
        </div>
    );
 
    // 输入框
    const input = h(renderNode(item.search.component, { prop: item.prop }), {
        clearable: true,
        modelValue: item.search.value,
        onVnodeMounted(vn) {
            // 默认聚焦
            vn.component?.exposed?.focus?.();
        },
        onInput(val: any) {
            item.search.value = val;
        },
        onChange(val: any) {
            item.search.value = val;
 
            // 更改时刷新列表
            if (item.search.refreshOnChange) {
                refresh();
            }
        }
    });
 
    return (
        <div class={["cl-table-header__search", { "is-input": item.search.isInput }]}>
            <div class="cl-table-header__search-inner">{item.search.isInput ? input : text}</div>
 
            {item.search.isInput && (
                <div class="cl-table-header__search-close" onClick={hide}>
                    <el-icon>
                        <CloseBold />
                    </el-icon>
                </div>
            )}
        </div>
    );
}