陶杰
2024-08-22 4aa0bd47801606b4d0e0a6a2ed8fe92a7e5f2444
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
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
<template>
    <view class="uni-grid-wrap">
        <view :id="elId" ref="uni-grid" class="uni-grid" :class="{ 'uni-grid--border': showBorder }" :style="{ 'border-left-color':borderColor}">
            <slot />
        </view>
    </view>
</template>
 
<script>
    // #ifdef APP-NVUE
    const dom = uni.requireNativePlugin('dom');
    // #endif
 
    /**
     * Grid 宫格
     * @description 宫格组件
     * @tutorial https://ext.dcloud.net.cn/plugin?id=27
     * @property {Number} column 每列显示个数
     * @property {String} borderColor 边框颜色
     * @property {Boolean} showBorder 是否显示边框
     * @property {Boolean} square 是否方形显示
     * @property {Boolean} Boolean 点击背景是否高亮
     * @event {Function} change 点击 grid 触发,e={detail:{index:0}},index 为当前点击 gird 下标
     */
    export default {
        name: 'UniGrid',
        emits:['change'],
        props: {
            // 每列显示个数
            column: {
                type: Number,
                default: 3
            },
            // 是否显示边框
            showBorder: {
                type: Boolean,
                default: true
            },
            // 边框颜色
            borderColor: {
                type: String,
                default: '#D2D2D2'
            },
            // 是否正方形显示,默认为 true
            square: {
                type: Boolean,
                default: true
            },
            highlight: {
                type: Boolean,
                default: true
            }
        },
        provide() {
            return {
                grid: this
            }
        },
        data() {
            const elId = `Uni_${Math.ceil(Math.random() * 10e5).toString(36)}`
            return {
                elId,
                width: 0
            }
        },
        created() {
            this.children = []
        },
        mounted() {
            this.$nextTick(()=>{
                this.init()
            })
        },
        methods: {
            init() {
                setTimeout(() => {
                    this._getSize((width) => {
                        this.children.forEach((item, index) => {
                            item.width = width
                        })
                    })
                }, 50)
            },
            change(e) {
                this.$emit('change', e)
            },
            _getSize(fn) {
                // #ifndef APP-NVUE
                uni.createSelectorQuery()
                    .in(this)
                    .select(`#${this.elId}`)
                    .boundingClientRect()
                    .exec(ret => {
                        this.width = parseInt((ret[0].width - 1) / this.column) + 'px'
                        fn(this.width)
                    })
                // #endif
                // #ifdef APP-NVUE
                dom.getComponentRect(this.$refs['uni-grid'], (ret) => {
                    this.width = parseInt((ret.size.width - 1) / this.column) + 'px'
                    fn(this.width)
                })
                // #endif
            }
        }
    }
</script>
 
<style lang="scss" >
    .uni-grid-wrap {
        /* #ifndef APP-NVUE */
        display: flex;
        /* #endif */
        flex: 1;
        flex-direction: column;
        /* #ifdef H5 */
        width: 100%;
        /* #endif */
    }
 
    .uni-grid {
        /* #ifndef APP-NVUE */
        display: flex;
        /* #endif */
        // flex: 1;
        flex-direction: row;
        flex-wrap: wrap;
    }
 
    .uni-grid--border {
        position: relative;
        /* #ifdef APP-NVUE */
        border-left-color: #D2D2D2;
        border-left-style: solid;
        border-left-width: 0.5px;
        /* #endif */
        /* #ifndef APP-NVUE */
        z-index: 1;
        border-left: 1px #D2D2D2 solid;
        /* #endif */
    }
</style>