代码示例
<template>
<div class="template-page"
v-loading="loading"
ref="scrollDiv">
<section class="poster-header">
<!-- 分类 -->
<section class="category-filter">
<div class="label-name">分类:</div>
<div class="category-content">
<ul class="category-group"
:style="isFold ? 'max-height: 32px;' : ''">
<li class="category-tag"
:class="{ active: !categoryIds[0] }"
@click="selectCategory()"> 全部 </li>
<li class="category-tag"
v-for="(categoryInfo, i) in categoryList"
:key="`category${i}`"
:class="{ active : categoryIds[0] === categoryInfo._id }"
@click="selectCategory(categoryInfo)">{{categoryInfo.name}}</li>
</ul>
<div class="category-more"
:class="{
up: !isFold,
down: isFold
}"
@click="isFold = !isFold">
<span class="text">更多</span>
<span class="icon-fold"></span>
</div>
</div>
</section>
<!-- 搜索 -->
<section class="filter-box">
<div class="fiter-left">
<search-input
:defaultValue='searchValue'
maxWidth='200px'
height="32px"
placeholder='请输入海报名称'
@change='handleSearch'>
</search-input>
</div>
<div class="filter-right"></div>
</section>
</section>
<section class="poster-wrapper">
<ul class="poster-list"
v-if="templateList.length">
<li class="poster-item"
v-for="(tempInfo, i) in templateList"
:key="`poster${i}`"
@click.stop="editPoster(tempInfo, i)">
<div class="item-header">
<p class="name">{{tempInfo.name}}</p>
<el-dropdown
@command='handleCommand($event, tempInfo)'
class='qa-bottom-dropdown'
trigger="hover">
<p class="icon"></p>
<el-dropdown-menu slot="dropdown" class='handle-menu-card'>
<el-dropdown-item command="editor">编辑海报</el-dropdown-item>
<el-dropdown-item command="popularize">推广海报</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
</div>
<div class="item-cont"
:style="{height: `${(256 / tempInfo.content.width) * tempInfo.content.height}px` }">
<img :src="tempInfo.content.thumb" alt=""/>
</div>
<div class="item-footer">{{formatDate(tempInfo.updatedAt)}}</div>
</li>
</ul>
<!-- 加载中 -->
<div class="loading-box"
v-show="loading">加载中...</div>
<!-- 加载完成 -->
<div class="load-end"
v-show="isEnd">已加载完毕</div>
<div class="default-cont"
v-show='!templateList.length'>暂无数据</div>
</section>
</div>
</template>
<script>
import axios from 'axios'
import ZhihuiEditor from 'zhihui-editor-sdk'
import searchInput from 'public/search-input'
export default {
name: 'matTemplateList',
components: {
searchInput
},
props: {
/**
* 调用腾讯云智绘API所需token
*/
accessToken: {
type: String,
default: ''
},
/**
* 初始化智绘编辑器即iframe时所需token
*/
editorToken: {
type: String,
default: ''
},
/**
* 初始化智绘编辑器即iframe时所需的其他参数
*/
editorAppInfo: {
type: Object,
default () {
return {
appid: '',
appKey: '',
channel: '',
stamp: 'testUserId',
timestamp: '',
scope: 'all'
}
}
}
},
data () {
return {
loading: false,
categoryList: [], // 分类列表
isFold: true, // 是否折叠分类
// 获取模板的参数
searchValue: '',
currPage: 1,
pageSize: 20,
count: 0,
categoryIds: [], // 选中的分类id
templateList: [], // 模板列表
// 模板列表是否加载完毕,默认为false
isEnd: false,
// 添加编辑海报相关
zhihuiEditor: null,
currTemplateInfo: null,
currTemplateIndex: -1,
// 流媒体
waterFallOptions: {
containerSelector: '.poster-list',
cardSelector: '.poster-item',
paddingLeft: 0,
paddingRight: 0,
paddingTop: 0,
paddingBottom: 20,
distanceX: 20,
distanceY: 20,
cardWidth: 256,
animation: true
}
}
},
methods: {
handleCommand (command, info) {
console.log('command', command)
console.log('info', info)
},
// 编辑模板
editPoster (info, index) {
this.currTemplateInfo = info
this.currTemplateIndex = index
this.initEditor()
},
initEditor () {
if (!this.editorToken) {
return this.showErrMsg('token获取失败,请刷新页面')
}
let templateId = this.currTemplateInfo && this.currTemplateInfo._id ? this.currTemplateInfo._id : '6254db7bccc34b01db8666ec'
let option = {
appid: this.editorAppInfo.appid,
channel: this.editorAppInfo.channel,
stamp: this.editorAppInfo.stamp,
timestamp: this.editorAppInfo.timestamp,
scope: this.editorAppInfo.scope, // 注意此处的scope是按照字符串传入
templateId: templateId,
from: 'material',
token: this.editorToken,
/**
* loading配置,修改加载时logo的显示
*/
loadingConfig: {
logoUrl: 'https://medchat.yuemia.com/storage/b55c/e68c/png/facea3c43fa3dc95a464e83d6f30ad71.png'
},
/**
* 头部配置
*/
headConfig: {
logoUrl: 'https://medchat.yuemia.com/storage/b55c/e68c/png/facea3c43fa3dc95a464e83d6f30ad71.png', // 头部的logo
downloadName: '完成', // 下载按钮的名称
// 用户点击下载按钮callback
onClickDownload: res => {
console.log('res', res)
this.zhihuiEditor.closeIframe()
},
isDownloadImg: false // 点击下载按钮后是否下载图片
}
}
// console.log('option', option)
this.zhihuiEditor = new ZhihuiEditor(option)
this.zhihuiEditor.openIframe()
},
// 选择分类
selectCategory (info) {
if ((this.categoryIds && info && this.categoryIds[0] === info._id) || (!this.categoryIds[0] && !info)) {
return
}
if (info) {
this.categoryIds = [info._id]
} else {
this.categoryIds = []
}
this.isEnd = false
this.currPage = 1
this.templateList = []
this.fetchTemplateList()
},
// 名称搜索
handleSearch (val) {
this.searchValue = val
this.isEnd = false
this.currPage = 1
this.templateList = []
// 如果选中的是我的,则调用自己服务的接口或者当前用户的记录接口
this.fetchTemplateList()
},
// 获取分类
fetchCategoryList () {
if (!this.accessToken) {
return this.showErrMsg('token获取失败,请刷新页面')
}
let url = `获取分类的接口`
axios.get(url, {
headers: {
'Authorization': 'Bearer ' + this.accessToken
}
}).then(res => {
let data = res.data.data
if (data) {
this.categoryList = data
}
}).catch(err => {
this.handleError(err)
})
},
// 获取模板列表
fetchTemplateList () {
if (!this.accessToken) {
return this.showErrMsg('token获取失败,请刷新页面')
}
let url = `获取模板的接口`
let params = {
filter: {state: 'success', type: 'image'}, // 不需要更改
filterTermArr: this.categoryIds, // 根据检索的分类id进行修改
hideObjects: true, // 不需要更改
keyword: this.searchValue || null, // 不需要更改
pageNumber: this.currPage, // 当前页码
pageSize: this.pageSize, // 每页数量
sort: {id: 'desc'} // 排序
}
if (this.loading) {
return
}
this.loading = true
axios.post(url, params, {
headers: {
'Authorization': 'Bearer ' + this.accessToken
}
}).then(res => {
this.loading = false
let data = res.data.data
if (data) {
this.count = data.info.total
let templateList = data.items
this.templateList = this.templateList.concat(templateList)
this.$nextTick(() => {
this.handleWaterFall()
})
}
}).catch(err => {
this.loading = false
this.handleError(err)
})
},
// --------------无限加载----------------
handleScroll (e) {
// 加定时器进行节流
setTimeout(() => {
// 元素内容高度,包括由于溢出导致的视图中不可见内容。
let boxCcrollHeight = e.target.scrollHeight
// 滚动距离
let boxScrollTop = e.target.scrollTop
// 网页可见区域高度
let boxClientHeight = e.target.clientHeight
// 距离底部距离长度
let bottomLen = boxCcrollHeight - boxScrollTop - boxClientHeight
if (this.count > this.templateList.length && bottomLen < 80 && !this.loading) {
// 加载数据
this.currPage += 1
this.fetchTemplateList()
console.log('分页')
} else if (this.count === this.templateList.length) {
this.isEnd = true
}
}, 500)
}
},
created () {
this.handleWaterFall = this.waterFall.bind(this, this.waterFallOptions)
window.addEventListener('resize', this.handleWaterFall)
this.fetchCategoryList()
this.fetchTemplateList()
},
mounted () {
this.$refs.scrollDiv.addEventListener('scroll', this.handleScroll, true)
},
beforeDestroy () {
window.removeEventListener('resize', this.handleWaterFall)
this.$refs.scrollDiv.removeEventListener('scroll', this.handleScroll)
}
}
</script>
<style lang="stylus" scoped>
.template-page
width 100%
height 100%
scroll()
scroll-bar()
background #fff
border-radius 10px
.poster-header
width 100%
padded_box(border-box, 20px)
.category-filter
display flex
background #F2F5FA
padded_box(border-box,15px 20px)
border-radius: 6px
.label-name
margin-right: 16px;
width: 42px;
height: 32px;
line-height: 32px;
padding: 0;
color: #303544;
margin-right: 16px;
.category-content
width calc(100% - 58px)
position relative
.category-group
display: flex;
flex-wrap: wrap;
align-items: center;
padding-right: 126px;
transition: max-height .3s;
overflow: hidden;
.category-tag
display: flex;
align-items: center;
line-height: 20px;
background: #fff
font-size: 14px;
color: #444950;
border: 1px solid #E9E9EB;
border-radius: 4px;
padded_box(border-box,5px 12px)
margin 0 8px 8px 8px
cursor: pointer;
&.active
color: #2254f4;
background: #E2ECFF;
border-color #2254f4
.category-more
display inline-block
width 52px
height 28px
line-height 20px
padded_box(border-box, 4px 0)
cursor pointer
position absolute
right 20px
top 0
&.up
.icon-fold
transform rotate(180deg)
.text
font-size 12px
color #888B9C
vertical-align middle
margin-right 4px
.icon-fold
display inline-block
width 14px
height 14px
background url('~assets/img/icon_fold_down@2x.png') no-repeat center/100%
vertical-align middle
.filter-box
width 100%
display: flex
justify-content: space-between
align-items: center
margin-top 20px
.fiter-left, .fiter-right
display flex
align-items: center
>>> .search-input-box
line-height: 32px
.poster-wrapper
padded_box(border-box, 0 0 20px 20px)
.poster-list
width 100%
display flex
flex-wrap wrap
// .poster-item
// width: 252px;
// max-height: 448px;
// margin:0 30px 30px 0;
// cursor: pointer;
// display: flex;
// justify-content: center;
// align-items: center;
// img
// // width 100%
// // height 100%
// width 100%
// max-height 100%
// border none
// vertical-align middle
.poster-item
width: 256px;
// max-height: 500px;
background: #FFFFFF;
border: 1px solid #D0D0D1;
border-radius: 4px;
margin 0 20px 20px 0
position relative
.item-header
display: flex
justify-content: space-between
align-items: center
width 100%
height 44px
line-height 20px
font-size 14px
padded_box(border-box,12px)
.name
width calc(100% - 24px)
margin-right 8px
.icon
width 20px
height 20px
background url('~assets/img/icon_more@2x.png') no-repeat center/16px
cursor pointer
.item-cont
width 100%
img
width 100%
// max-height 454px
height 100%
.item-footer
width 100%
height: 44px;
line-height 20px
font-size 14px
color #fff
padded_box(border-box, 12px)
background-image: linear-gradient(180deg, rgba(0,0,0,0.00) 0%, rgba(0,0,0,0.50) 100%);
position absolute
left 0
right 0
bottom 0
.loading-box
width 100%
height 20px
line-height 20px
text-align center
color #909399
margin-top 10px
.load-end
width 100%
height 20px
line-height 20px
text-align center
color #909399
margin-top 10px
.default-cont
width 100%
height 60px
text-align center
line-height 20px
// font-size 12px
color #909399
padded_box(border-box, 20px 0)
</style>
···
网友评论