scroll组件
index.vue页面
<template> <div class="venus-card-wrapper"> <a-spin tip="Loading..." :spinning="localLoading"> <a-row :gutter="gutter" class="venus-card-row" v-show="localDataSource.length>0"> <a-col :xs="span.xs" :sm="span.sm" :md="span.md" :lg="span.lg" :xl="span.xl" :xxl="span.xxl" v-for="row in localDataSource" :key="row[rowKey]" class="venus-card"> <div class="card-box"> <div class="card-img-box" @click="(e)=> imgClick(row[icon], e)"> <img :src="getIcon(row[icon])" class="card-img" /> <div class="img-count" v-if="checkIconNum(row[icon])">{{ checkIconNum(row[icon]).length }}</div> </div> <div class="card-word"> <p class="card-title"> <slot name="title"></slot> {{ row[title] }} </p> <p class="card-desc"> <span class="indentation"></span> <slot name="description"></slot> {{ row[description] }} </p> </div> <div class="card-action"> <slot name="action" :row="row"></slot> </div> </div> </a-col> </a-row> <a-empty v-show="localDataSource.length<=0" :image="emptyImg" :image-style="{ height: '100px',}"> <span slot="description"> 暂无数据 <!-- <a href="#API">Description</a> --> </span> </a-empty> </a-spin> <a-row gutter="0" v-if="localDataSource.length>0"> <a-col span="24" class="footer-pagination"> <a-pagination :page-size="localPagination.pageSize || 8" :total="localPagination.total" v-model="localPagination.current" @change="loadData" /> </a-col> </a-row> <a-modal :visible="previewVisible" :footer="null" @cancel="previewVisible = false" class="venus-card-modal" width="50%" :bodyStyle="{ padding: 0 }"> <!-- <img alt="加载失败" style="width: 100%;border-radius: 3px" :src="imgData" />--> <a-carousel dots-class="slick-dots slick-thumb" class="venus-card-carousel" v-if="previewVisible"> <a slot="customPaging" slot-scope="props"> <img :src="imgData[props.i]" /> </a> <div v-for="(item, index) in imgData" :key="index"> <img :src="item" /> </div> </a-carousel> </a-modal> </div> </template> <script> import get from 'lodash.get' import original from '@/assets/portalClient/original.png' import prefix from '@/config/prefix' export default { name: 'VenusSCard', data () { return { localLoading: false, previewVisible: false, imgData: [], localDataSource: [], localPagination: Object.assign({}, this.pagination), emptyImg: original } }, props: Object.assign( {}, { rowKey: { type: [String, Function], default: 'key' }, pagination: { type: [Object, Boolean], default: false }, data: { type: Function, required: true }, pageNum: { type: Number, default: 1 }, pageSize: { type: Number, default: 8 }, showSizeChanger: { type: Boolean, default: true }, showQuickJumper: { type: Boolean, default: true }, size: { type: String, default: 'default' }, /** * alert: { * show: true, * clear: Function * } */ alert: { type: [Object, Boolean], default: null }, rowSelection: { type: Object, default: null }, /** @Deprecated */ showAlertInfo: { type: Boolean, default: false }, showPagination: { type: String | Boolean, default: 'false' }, /** * enable page URI mode * * e.g: * /users/1 * /users/2 * /users/3?queryParam=test * ... */ pageURI: { type: Boolean, default: false }, rangPicker: { type: Array, default: null }, title: { type: String, default: 'name' }, icon: { type: String, default: 'icon' }, description: { type: String, default: 'remark' }, iconPrefix: { type: String, default: undefined }, gutter: { type: Number, default: 0 }, span: { type: Object, default: () => { return { xs: 24, md: 8 } } } } ), watch: { 'localPagination.current' (val) { this.pageURI && this.$router.push({ ...this.$route, name: this.$route.name, params: Object.assign({}, this.$route.params, { pageNo: val }) }) }, pageNum (val) { Object.assign(this.localPagination, { current: val }) }, pageSize (val) { Object.assign(this.localPagination, { pageSize: val }) }, showSizeChanger (val) { Object.assign(this.localPagination, { showSizeChanger: val }) }, showQuickJumper (val) { Object.assign(this.localPagination, { showQuickJumper: val }) } }, created () { const { pageNo } = this.$route.params const localPageNum = (this.pageURI && pageNo && parseInt(pageNo)) || this.pageNum this.localPagination = (['auto', true].includes(this.showPagination) && Object.assign({}, this.localPagination, { current: localPageNum, pageSize: this.pageSize, showSizeChanger: this.showSizeChanger, showQuickJumper: this.showQuickJumper })) || false this.loadData() }, methods: { checkIconNum (icon) { const arr = icon ? icon.split(',') : [] if (arr.length > 1) { return arr } return false }, getIcon (icon) { const arr = this.checkIconNum(icon) if (arr) { return this.iconPrefix === undefined ? prefix.OPEN_URL_PREFIX + arr[0] : this.iconPrefix + arr[0] } else { return this.iconPrefix === undefined ? prefix.OPEN_URL_PREFIX + icon : this.iconPrefix + icon } }, imgClick (icon, e) { const arr = icon ? icon.split(',') : [] this.imgData = arr.map(item => { return this.iconPrefix === undefined ? prefix.OPEN_URL_PREFIX + icon : this.iconPrefix + icon }) this.$nextTick(() => { this.previewVisible = true }) }, /** * 卡片列表重新加载方法 * 如果参数为 true, 则强制刷新到第一页 * @param Boolean bool */ refresh (bool = false) { bool && (this.localPagination = Object.assign( {}, { current: 1, pageSize: this.pageSize } )) this.loadData() }, /** * 加载数据方法 * @param {Object} pagination 分页选项器 * @param {Object} filters 过滤条件 * @param {Object} sorter 排序条件 */ loadData (current, pageSize) { this.localLoading = true // console.log('rangPicker', this.rangPicker) const parameter = Object.assign( { pageNum: current || (this.showPagination && this.localPagination.current) || this.pageNum, pageSize: pageSize || (this.showPagination && this.localPagination.pageSize) || this.pageSize }, (this.rangPicker && this.rangPicker.length === 2 && { beginTime: this.rangPicker[0].format('YYYY-MM-DD'), endTime: this.rangPicker[1].format('YYYY-MM-DD') }) || {} ) const result = this.data(parameter) // 对接自己的通用数据接口需要修改下方代码中的 r.pageNo, r.totalCount, r.data // eslint-disable-next-line if ((typeof result === 'object' || typeof result === 'function') && typeof result.then === 'function') { const _this = this result.then(r => { _this.localPagination = (_this.showPagination && Object.assign({}, _this.localPagination, { current: r.pageNum, // 返回结果中的当前分页数 total: r.total, // 返回结果中的总记录数 showSizeChanger: _this.showSizeChanger, showQuickJumper: _this.showQuickJumper, showTotal: total => `共 ${r.total} 条数据`, pageSize: (_this.showPagination && pageSize) || _this.localPagination.pageSize || this.pageSize })) || false // 为防止删除数据后导致页面当前页面数据长度为 0 ,自动翻页到上一页 if (r.rows.length === 0 && _this.showPagination && _this.localPagination.current > 1) { _this.localPagination.current-- _this.loadData() return } // console.log('localPagination', this.localPagination) // 这里用于判断接口是否有返回 r.totalCount 且 this.showPagination = true 且 pageNo 和 pageSize 存在 且 totalCount 小于等于 pageNo * pageSize 的大小 // 当情况满足时,表示数据不满足分页大小,关闭 table 分页功能 try { if ( ['auto', true].includes(_this.showPagination) && r.total <= r.pageNum * _this.localPagination.pageSize ) { _this.localPagination.hideOnSinglePage = true } } catch (e) { _this.localPagination = false } _this.localDataSource = r.rows // 返回结果中的数组数据 _this.localLoading = false }) } this.pagination = false } } // render() { // const cardWrapper = this.localDataSource.map(row => { // const key = row[this.rowKey] // return <a-col span="6" key={key} class="venus-card"> // <img src={prefix.OPEN_URL_PREFIX + row.icon} class="card-img" /> // <div class="card-word"> // <p class="card-title">{row[this.title]}</p> // <p class="card-desc"><span class="indentation"></span>{row[this.description]}</p> // </div> // {Object.keys(this.$slots).map(name => (<slot name={name} row={row} class="card-action">{this.$slots[name]}</slot>))} // </a-col> // }) // const paginationRender = this.showPagination ? (<a-pagination // // show-size-changer={this.localPagination.showSizeChanger} // default-page-size={this.localPagination.pageSize || 8} // show-total={this.localPagination.showTotal} // current={this.localPagination.current} // show-quick-jumper={this.localPagination.showQuickJumper} // on={{ change: this.loadData, showSizeChange: this.loadData }} // />) : '' // } } </script> <style lang="less"> @import './index.less'; .venus-card-modal { .ant-modal-content { background: none; box-shadow: none; height: 0px; // .ant-modal-close { // display: none; // } } .ant-modal-close { right: calc(50% - 28px); } .ant-modal-body { padding-bottom: 48px !important; } .ant-modal-close-x { color: #333; transition: all 0.2s; &:hover { .ant-modal-close-icon { background: #fff; } } .ant-modal-close-icon { padding: 6px; background: rgba(255, 255, 255, 0.75); border-radius: 50%; } } } .venus-card-carousel { .slick-dots { height: auto; } } .venus-card-carousel { .slick-slide img { // border: 5px solid #fff; display: block; margin: auto; max-width: 100%; } } .venus-card-carousel { .slick-thumb { bottom: -53px; } } .venus-card-carousel { .slick-thumb li { width: 60px; height: 45px; } } .venus-card-carousel { .slick-thumb li img { width: 100%; height: 100%; transition: all 0.3s; filter: grayscale(100%); } } .venus-card-carousel { .slick-thumb li.slick-active img { filter: grayscale(0%); box-shadow: 0px 0px 2px 2px @primary-color; } } </style>
index.less
@import '../../index.less'; .venus-card-wrapper { .ant-empty { .ant-empty-image { margin-top: 40px; } height: 300px; border: 1px solid #eaeaea; margin: 0px; } .venus-card-row { border-top: 1px solid #eaeaea; border-left: 1px solid #eaeaea; } .venus-card { padding: 50px 36px; border: 1px solid #eaeaea; border-top: none; border-left: none; .card-box { transition: all 0.6s ease 0s; } &:hover { .card-img { transform: scale(1.2); -ms-transform: scale(1.2); -webkit-transform: scale(1.2); -moz-transform: scale(1.2); /* Firefox */ -o-transform: scale(1.2); /* Opera */ } .card-img-box { &::after { height: 100%; opacity: 1; } &::before { top: 50%; opacity: 1; } } .card-title { color: @primary-color !important; } } .card-img-box { width: 100%; height: 150px; overflow: hidden; cursor: pointer; position: relative; .img-count { position: absolute; bottom: 0px; right: 0px; height: 24px; width: 32px; font-size: 12px; color: rgb(221, 221, 221); background-color: rgba(0, 0, 0, 0.4); } &::before { content: ''; width: 26px; height: 26px; line-height: 26px; background: url(~@/assets/portalClient/special/hg.png) no-repeat; background-size: contain; margin-left: -23px; margin-top: -20px; display: inline-block; position: absolute; top: 0; left: 50%; z-index: 10; transition: all 0.6s cubic-bezier(0.215, 0.61, 0.355, 1) 0s; opacity: 0; } &::after { content: ""; width: 100%; height: 0; background-color: rgba(10, 36, 86, 0.4); position: absolute; top: 0px; left: 0; opacity: 0; -webkit-transition: all 0.3s ease 0s; transition: all 0.3s ease 0s; } .card-img { width: 100%; transition: all 0.5s; } } .card-word { padding: 40px 20px 30px; font-family: Arial, "微软雅黑"; .card-title { font-family: Arial, "微软雅黑"; font-size: 16px; font-weight: normal; font-stretch: normal; line-height: 30px; letter-spacing: 1px; color: #333333; } .card-desc { font-family: Arial, "微软雅黑"; font-size: 12px; font-weight: normal; font-stretch: normal; width: 100%; height: 40px; letter-spacing: 1px; color: #a4aac7; display: -webkit-box; line-height: 22px; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; text-overflow: ellipsis; margin-bottom: 0px; .indentation { padding-left: 2em; } } } .card-action { margin: 0 10px; button { margin: 0 auto; display: block; width: 82px; height: 32px; font-family: PingFangSC-Regular; font-size: 12px; font-weight: normal; font-stretch: normal; line-height: 22px; letter-spacing: 0px; border-radius: 2px; } } } } .footer-pagination { text-align: center; margin-top: 48px; } .more-btn { margin: 8px 4px; .ant-col { button { margin: 0 auto; display: block; margin: 0 8px; width: 72px; height: 32px; border-radius: 2px; } } }
请阅读后点赞,谢谢

浙公网安备 33010602011771号