<template>
							 | 
						|
									<!-- #ifndef APP-NVUE -->
							 | 
						|
									<view
							 | 
						|
									    class="uv-grid-item"
							 | 
						|
									    hover-class="uv-grid-item--hover-class"
							 | 
						|
									    :hover-stay-time="200"
							 | 
						|
									    @tap="clickHandler"
							 | 
						|
									    :class="classes"
							 | 
						|
									    :style="[itemStyle]"
							 | 
						|
									>
							 | 
						|
										<slot />
							 | 
						|
									</view>
							 | 
						|
									<!-- #endif -->
							 | 
						|
									<!-- #ifdef APP-NVUE -->
							 | 
						|
									<view
							 | 
						|
									    class="uv-grid-item"
							 | 
						|
									    :hover-stay-time="200"
							 | 
						|
									    @tap="clickHandler"
							 | 
						|
									    :class="classes"
							 | 
						|
									    :style="[itemStyle]"
							 | 
						|
									>
							 | 
						|
										<slot />
							 | 
						|
									</view>
							 | 
						|
									<!-- #endif -->
							 | 
						|
								</template>
							 | 
						|
								
							 | 
						|
								<script>
							 | 
						|
									import mpMixin from '@/uni_modules/uv-ui-tools/libs/mixin/mpMixin.js'
							 | 
						|
									import mixin from '@/uni_modules/uv-ui-tools/libs/mixin/mixin.js'
							 | 
						|
									import props from './props.js';
							 | 
						|
									/**
							 | 
						|
									 * gridItem 提示
							 | 
						|
									 * @description 宫格组件一般用于同时展示多个同类项目的场景,可以给宫格的项目设置徽标组件(badge),或者图标等,也可以扩展为左右滑动的轮播形式。搭配uv-grid使用
							 | 
						|
									 * @tutorial https://www.uvui.cn/components/grid.html
							 | 
						|
									 * @property {String | Number}	name		宫格的name ( 默认 null )
							 | 
						|
									 * @property {String}			bgColor		宫格的背景颜色 (默认 'transparent' )
							 | 
						|
									 * @property {Object}			customStyle	自定义样式,对象形式
							 | 
						|
									 * @event {Function} click 点击宫格触发
							 | 
						|
									 * @example <uv-grid-item></uv-grid-item>
							 | 
						|
									 */
							 | 
						|
									export default {
							 | 
						|
										name: "uv-grid-item",
							 | 
						|
										mixins: [mpMixin, mixin, props],
							 | 
						|
										emits: ['$uvGridItem','click'],
							 | 
						|
										data() {
							 | 
						|
											return {
							 | 
						|
												parentData: {
							 | 
						|
													col: 3, // 父组件划分的宫格数
							 | 
						|
													border: true, // 是否显示边框,根据父组件决定
							 | 
						|
												},
							 | 
						|
												// #ifdef APP-NVUE
							 | 
						|
												width: 0, // nvue下才这么计算,vue下放到computed中,否则会因为延时造成闪烁
							 | 
						|
												// #endif
							 | 
						|
												classes: [], // 类名集合,用于判断是否显示右边和下边框
							 | 
						|
											};
							 | 
						|
										},
							 | 
						|
										created() {
							 | 
						|
											// 父组件的实例
							 | 
						|
											this.updateParentData()
							 | 
						|
										},
							 | 
						|
										mounted() {
							 | 
						|
											this.init()
							 | 
						|
										},
							 | 
						|
										computed: {
							 | 
						|
											// #ifndef APP-NVUE
							 | 
						|
											// vue下放到computed中,否则会因为延时造成闪烁
							 | 
						|
											width() {
							 | 
						|
												return 100 / Number(this.parentData.col) + '%'
							 | 
						|
											},
							 | 
						|
											// #endif
							 | 
						|
											itemStyle() {
							 | 
						|
												const style = {
							 | 
						|
													background: this.bgColor,
							 | 
						|
													width: this.width
							 | 
						|
												}
							 | 
						|
												return this.$uv.deepMerge(style, this.$uv.addStyle(this.customStyle))
							 | 
						|
											}
							 | 
						|
										},
							 | 
						|
										methods: {
							 | 
						|
											init() {
							 | 
						|
												// 用于在父组件uv-grid的children中被添加入子组件时,
							 | 
						|
												// 重新计算item的边框
							 | 
						|
												uni.$on('$uvGridItem', () => {
							 | 
						|
													this.gridItemClasses()
							 | 
						|
												})
							 | 
						|
												// #ifdef APP-NVUE
							 | 
						|
												// 获取元素该有的长度,nvue下要延时才准确
							 | 
						|
												this.$nextTick(function(){
							 | 
						|
													this.getItemWidth()
							 | 
						|
												})
							 | 
						|
												// #endif
							 | 
						|
												// 发出事件,通知所有的grid-item都重新计算自己的边框
							 | 
						|
												uni.$emit('$uvGridItem')
							 | 
						|
												this.gridItemClasses()
							 | 
						|
											},
							 | 
						|
											// 获取父组件的参数
							 | 
						|
											updateParentData() {
							 | 
						|
												// 此方法写在mixin中
							 | 
						|
												this.getParentData('uv-grid');
							 | 
						|
											},
							 | 
						|
											clickHandler() {
							 | 
						|
												let name = this.name
							 | 
						|
												// 如果没有设置name属性,历遍父组件的children数组,判断当前的元素是否和本实例this相等,找出当前组件的索引
							 | 
						|
												const children = this.parent?.children
							 | 
						|
												if(children && this.name === null) {
							 | 
						|
													name = children.findIndex(child => child === this)
							 | 
						|
												}
							 | 
						|
												// 调用父组件方法,发出事件
							 | 
						|
												this.parent && this.parent.childClick(name)
							 | 
						|
												this.$emit('click', name)
							 | 
						|
											},
							 | 
						|
											async getItemWidth() {
							 | 
						|
												// 如果是nvue,不能使用百分比,只能使用固定宽度
							 | 
						|
												let width = 0
							 | 
						|
												if(this.parent) {
							 | 
						|
													// 获取父组件宽度后,除以栅格数,得出每个item的宽度
							 | 
						|
													const parentWidth = await this.getParentWidth()
							 | 
						|
													width = parentWidth / Number(this.parentData.col) + 'px'
							 | 
						|
												}
							 | 
						|
												this.width = width
							 | 
						|
											},
							 | 
						|
											// 获取父元素的尺寸
							 | 
						|
											getParentWidth() {
							 | 
						|
												// #ifdef APP-NVUE
							 | 
						|
												// 返回一个promise,让调用者可以用await同步获取
							 | 
						|
												const dom = uni.requireNativePlugin('dom')
							 | 
						|
												return new Promise(resolve => {
							 | 
						|
													// 调用父组件的ref
							 | 
						|
													dom.getComponentRect(this.parent.$refs['uv-grid'], res => {
							 | 
						|
														resolve(res.size.width)
							 | 
						|
													})
							 | 
						|
												})
							 | 
						|
												// #endif
							 | 
						|
											},
							 | 
						|
											gridItemClasses() {
							 | 
						|
												if(this.parentData.border) {
							 | 
						|
													let classes = []
							 | 
						|
													this.parent.children.map((child, index) =>{
							 | 
						|
														if(this === child) {
							 | 
						|
															const len = this.parent.children.length
							 | 
						|
															// 贴近右边屏幕边沿的child,并且最后一个(比如只有横向2个的时候),无需右边框
							 | 
						|
															if((index + 1) % this.parentData.col !== 0 && index + 1 !== len) {
							 | 
						|
																classes.push('uv-border-right')
							 | 
						|
															}
							 | 
						|
															// 总的宫格数量对列数取余的值
							 | 
						|
															// 如果取余后,值为0,则意味着要将最后一排的宫格,都不需要下边框
							 | 
						|
															const lessNum = len % this.parentData.col === 0 ? this.parentData.col : len % this.parentData.col
							 | 
						|
															// 最下面的一排child,无需下边框
							 | 
						|
															if(index < len - lessNum) {
							 | 
						|
																classes.push('uv-border-bottom')
							 | 
						|
															}
							 | 
						|
														}
							 | 
						|
													})
							 | 
						|
													// 支付宝,头条小程序无法动态绑定一个数组类名,否则解析出来的结果会带有",",而导致失效
							 | 
						|
													// #ifdef MP-ALIPAY || MP-TOUTIAO
							 | 
						|
													classes = classes.join(' ')
							 | 
						|
													// #endif
							 | 
						|
													this.classes = classes
							 | 
						|
												}
							 | 
						|
											}
							 | 
						|
										},
							 | 
						|
										// #ifdef VUE2
							 | 
						|
										beforeDestroy() {
							 | 
						|
											// 移除事件监听,释放性能
							 | 
						|
											uni.$off('$uvGridItem')
							 | 
						|
										},
							 | 
						|
										// #endif
							 | 
						|
										// #ifdef VUE3
							 | 
						|
										unmounted() {
							 | 
						|
											// 移除事件监听,释放性能
							 | 
						|
											uni.$off('$uvGridItem')
							 | 
						|
										}
							 | 
						|
										// #endif
							 | 
						|
									};
							 | 
						|
								</script>
							 | 
						|
								
							 | 
						|
								<style lang="scss" scoped>
							 | 
						|
									$show-border: 1;
							 | 
						|
									$show-border-right: 1;
							 | 
						|
									$show-border-bottom: 1;
							 | 
						|
									@import '@/uni_modules/uv-ui-tools/libs/css/variable.scss';
							 | 
						|
									@import '@/uni_modules/uv-ui-tools/libs/css/components.scss';
							 | 
						|
									@import '@/uni_modules/uv-ui-tools/libs/css/color.scss';
							 | 
						|
									$uv-grid-item-hover-class-opcatiy:.5 !default;
							 | 
						|
									$uv-grid-item-margin-top:1rpx !default;
							 | 
						|
									$uv-grid-item-border-right-width:0.5px !default;
							 | 
						|
									$uv-grid-item-border-bottom-width:0.5px !default;
							 | 
						|
									$uv-grid-item-border-right-color:$uv-border-color !default;
							 | 
						|
									$uv-grid-item-border-bottom-color:$uv-border-color !default;
							 | 
						|
									.uv-grid-item {
							 | 
						|
										align-items: center;
							 | 
						|
										justify-content: center;
							 | 
						|
										position: relative;
							 | 
						|
										flex-direction: column;
							 | 
						|
										/* #ifndef APP-NVUE */
							 | 
						|
										box-sizing: border-box;
							 | 
						|
										display: flex;
							 | 
						|
										/* #endif */
							 | 
						|
								
							 | 
						|
										/* #ifdef MP */
							 | 
						|
										position: relative;
							 | 
						|
										float: left;
							 | 
						|
										/* #endif */
							 | 
						|
								
							 | 
						|
										/* #ifdef MP-WEIXIN */
							 | 
						|
										margin-top:$uv-grid-item-margin-top;
							 | 
						|
										/* #endif */
							 | 
						|
								
							 | 
						|
										&--hover-class {
							 | 
						|
											opacity:$uv-grid-item-hover-class-opcatiy;
							 | 
						|
										}
							 | 
						|
									}
							 | 
						|
								
							 | 
						|
									/* #ifdef APP-NVUE */
							 | 
						|
									// 由于nvue不支持组件内引入app.vue中再引入的样式,所以需要写在这里
							 | 
						|
									.uv-border-right {
							 | 
						|
										border-right-width:$uv-grid-item-border-right-width;
							 | 
						|
										border-color: $uv-grid-item-border-right-color;
							 | 
						|
									}
							 | 
						|
								
							 | 
						|
									.uv-border-bottom {
							 | 
						|
										border-bottom-width:$uv-grid-item-border-bottom-width;
							 | 
						|
										border-color:$uv-grid-item-border-bottom-color;
							 | 
						|
									}
							 | 
						|
									/* #endif */
							 | 
						|
								</style>
							 |