| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211 | 
							- <template>
 
-   <!-- #ifndef APP-NVUE -->
 
-   <view
 
-       class="u-grid-item"
 
-       hover-class="u-grid-item--hover-class"
 
-       :hover-stay-time="200"
 
-       @tap="clickHandler"
 
-       :class="classes"
 
-       :style="[itemStyle]"
 
-   >
 
-     <slot/>
 
-   </view>
 
-   <!-- #endif -->
 
-   <!-- #ifdef APP-NVUE -->
 
-   <view
 
-       class="u-grid-item"
 
-       :hover-stay-time="200"
 
-       @tap="clickHandler"
 
-       :class="classes"
 
-       :style="[itemStyle]"
 
-   >
 
-     <slot/>
 
-   </view>
 
-   <!-- #endif -->
 
- </template>
 
- <script>
 
- import props from './props.js';
 
- /**
 
-  * gridItem 提示
 
-  * @description 宫格组件一般用于同时展示多个同类项目的场景,可以给宫格的项目设置徽标组件(badge),或者图标等,也可以扩展为左右滑动的轮播形式。搭配u-grid使用
 
-  * @tutorial https://www.uviewui.com/components/grid.html
 
-  * @property {String | Number}  name    宫格的name ( 默认 null )
 
-  * @property {String}      bgColor    宫格的背景颜色 (默认 'transparent' )
 
-  * @property {Object}      customStyle  自定义样式,对象形式
 
-  * @event {Function} click 点击宫格触发
 
-  * @example <u-grid-item></u-grid-item>
 
-  */
 
- export default {
 
-   name: "u-grid-item",
 
-   mixins: [uni.$u.mpMixin, uni.$u.mixin, props],
 
-   data() {
 
-     return {
 
-       parentData: {
 
-         col: 3, // 父组件划分的宫格数
 
-         border: true, // 是否显示边框,根据父组件决定
 
-       },
 
-       // #ifdef APP-NVUE
 
-       width: 0, // nvue下才这么计算,vue下放到computed中,否则会因为延时造成闪烁
 
-       // #endif
 
-       classes: [], // 类名集合,用于判断是否显示右边和下边框
 
-     };
 
-   },
 
-   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 uni.$u.deepMerge(style, uni.$u.addStyle(this.customStyle))
 
-     }
 
-   },
 
-   methods: {
 
-     init() {
 
-       // 用于在父组件u-grid的children中被添加入子组件时,
 
-       // 重新计算item的边框
 
-       uni.$on('$uGridItem', () => {
 
-         this.gridItemClasses()
 
-       })
 
-       // 父组件的实例
 
-       this.updateParentData()
 
-       // #ifdef APP-NVUE
 
-       // 获取元素该有的长度,nvue下要延时才准确
 
-       this.$nextTick(function () {
 
-         this.getItemWidth()
 
-       })
 
-       // #endif
 
-       // 发出事件,通知所有的grid-item都重新计算自己的边框
 
-       uni.$emit('$uGridItem')
 
-       this.gridItemClasses()
 
-     },
 
-     // 获取父组件的参数
 
-     updateParentData() {
 
-       // 此方法写在mixin中
 
-       this.getParentData('u-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['u-grid'], res => {
 
-           resolve(res.size.width)
 
-         })
 
-       })
 
-       // #endif
 
-     },
 
-     gridItemClasses() {
 
-       if (this.parentData.border) {
 
-         const 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('u-border-right')
 
-             }
 
-             // 总的宫格数量对列数取余的值
 
-             // 如果取余后,值为0,则意味着要将最后一排的宫格,都不需要下边框
 
-             const lessNum = len % this.parentData.col === 0 ? this.parentData.col : len % this.parentData.col
 
-             // 最下面的一排child,无需下边框
 
-             if (index < len - lessNum) {
 
-               classes.push('u-border-bottom')
 
-             }
 
-           }
 
-         })
 
-         // 支付宝,头条小程序无法动态绑定一个数组类名,否则解析出来的结果会带有",",而导致失效
 
-         // #ifdef MP-ALIPAY || MP-TOUTIAO
 
-         classes = classes.join(' ')
 
-         // #endif
 
-         this.classes = classes
 
-       }
 
-     }
 
-   },
 
-   beforeDestroy() {
 
-     // 移除事件监听,释放性能
 
-     uni.$off('$uGridItem')
 
-   }
 
- };
 
- </script>
 
- <style lang="scss" scoped>
 
- @import "../../libs/css/components.scss";
 
- $u-grid-item-hover-class-opcatiy: .5 !default;
 
- $u-grid-item-margin-top: 1 rpx !default;
 
- $u-grid-item-border-right-width: 0.5px !default;
 
- $u-grid-item-border-bottom-width: 0.5px !default;
 
- $u-grid-item-border-right-color: $u-border-color !default;
 
- $u-grid-item-border-bottom-color: $u-border-color !default;
 
- .u-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: $u-grid-item-margin-top;
 
-   /* #endif */
 
-   &--hover-class {
 
-     opacity: $u-grid-item-hover-class-opcatiy;
 
-   }
 
- }
 
- /* #ifdef APP-NVUE */
 
- // 由于nvue不支持组件内引入app.vue中再引入的样式,所以需要写在这里
 
- .u-border-right {
 
-   border-right-width: $u-grid-item-border-right-width;
 
-   border-color: $u-grid-item-border-right-color;
 
- }
 
- .u-border-bottom {
 
-   border-bottom-width: $u-grid-item-border-bottom-width;
 
-   border-color: $u-grid-item-border-bottom-color;
 
- }
 
- /* #endif */
 
- </style>
 
 
  |