bklLiudl
2025-04-07 4e8f58cb41c7b6d570fd1979d80f74ab8a4d00c2
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
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
<template>
    <component :is="tagName" :class="classes" v-bind="tagProps" @click="handleClickLink">
        <div :class="headClasses" v-if="showHead"><slot name="title">
            <p v-if="title">
                <Icon v-if="icon" :type="icon"></Icon>
                <span>{{title}}</span>
            </p>
        </slot></div>
        <div :class="extraClasses" v-if="showExtra"><slot name="extra"></slot></div>
        <div :class="bodyClasses" :style="bodyStyles"><slot></slot></div>
    </component>
</template>
<script>
    const prefixCls = 'ivu-card';
    const defaultPadding = 16;
    import Icon from '../icon/icon.vue';
    import mixinsLink from '../../mixins/link';
 
    export default {
        name: 'Card',
        mixins: [ mixinsLink ],
        components: { Icon },
        props: {
            bordered: {
                type: Boolean,
                default: true
            },
            disHover: {
                type: Boolean,
                default: false
            },
            shadow: {
                type: Boolean,
                default: false
            },
            padding: {
                type: Number,
                default: defaultPadding
            },
            title: {
                type: String,
            },
            icon: {
                type: String,
            }
        },
        data () {
            return {
                showHead: true,
                showExtra: true
            };
        },
        computed: {
            classes () {
                return [
                    `${prefixCls}`,
                    {
                        [`${prefixCls}-bordered`]: this.bordered && !this.shadow,
                        [`${prefixCls}-dis-hover`]: this.disHover || this.shadow,
                        [`${prefixCls}-shadow`]: this.shadow
                    }
                ];
            },
            headClasses () {
                return `${prefixCls}-head`;
            },
            extraClasses () {
                return `${prefixCls}-extra`;
            },
            bodyClasses () {
                return `${prefixCls}-body`;
            },
            bodyStyles () {
                if (this.padding !== defaultPadding) {
                    return {
                        padding: `${this.padding}px`
                    };
                } else {
                    return '';
                }
            },
            // Point out if it should render as <a> tag
            isHrefPattern () {
                const { to } = this;
                return !!to;
            },
            tagName () {
                const { isHrefPattern } = this;
                return isHrefPattern ? 'a' : 'div';
            },
            tagProps () {
                const { isHrefPattern } = this;
                if (isHrefPattern) {
                    const { linkUrl,target } = this;
                    return { href: linkUrl, target };
                } else {
                    return {};
                }
            }
        },
        methods: {
            handleClickLink (event) {
                if (!this.isHrefPattern) return;
                const openInNewWindow = event.ctrlKey || event.metaKey;
                this.handleCheckClick(event, openInNewWindow);
            }
        },
        mounted () {
            this.showHead = this.title || this.$slots.title !== undefined;
            this.showExtra = this.$slots.extra !== undefined;
        }
    };
</script>