123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249 |
- <template>
- <waterflow :id="id" class="grid" :bounces="false" :scroll-y="true" :custom-nested-scroll="true"
- main-axis-gap="8px" cross-axis-gap="8px" cross-axis-count=2
- @scrolltolower="loadData(null)" associative-container="nested-scroll-view">
- <flow-item class="flow-item" v-for="(item, _) in datagrid" :key="item.plugin_id" type=1>
- <view class="flow-item-icon">
- <image class="flow-item-icon-image" :src="item.plugin_img_link" mode="aspectFit"></image>
- </view>
- <view class="flow-item-fill">
- <view class="flex-row">
- <text class="title">{{item.plugin_name}}</text>
- </view>
- <view>
- <text class="description-text">{{item.plugin_intro}}</text>
- </view>
- <text class="icon-star">{{convertToStarUnicode(item.score)}}</text>
- <view class="tag-grid">
- <text class="tag-item" v-for="(item2, index2) in item.tags.slice(0,1)" :key="index2">{{item2}}</text>
- </view>
- <view class="flex-row update-date">
- <text class="author">{{item.author_name}}</text>
- </view>
- <view class="flex-row update-date">
- <text class="update-date-text">更新日期</text>
- <text class="update-date-value">{{item.update_date}}</text>
- </view>
- </view>
- </flow-item type="20">
- <flow-item slot="load-more" class="loading" type=6>
- <uni-loading :loading="loading" color="#999" :text="loadingText"></uni-loading>
- </flow-item>
- </waterflow>
- </template>
- <script>
- const SERVER_URL = "https://unidemo.dcloud.net.cn/plugin/uniappx-plugin-list"
- const PAGE_SIZE = 10; // 最大值 10
- type flowItem = {
- plugin_id : number,
- plugin_img_link : string,
- plugin_name : string,
- plugin_intro : string,
- score : number,
- tags : Array<string>,
- update_date : string,
- author_name : string,
- }
- type ResponseDataType = {
- code : number,
- data : flowItem[]
- }
- export default {
- props: {
- type: {
- type: String,
- default: ''
- },
- preload: {
- type: Boolean,
- default: false
- },
- id: {
- type: String,
- default: ''
- }
- },
- data() {
- return {
- loading: false,
- datagrid: [] as flowItem[],
- isEnded: false,
- loadingError: '',
- currentPage: 1
- }
- },
- computed: {
- loadingText() : string {
- if (this.loading) {
- return "加载中..."
- } else if (this.isEnded) {
- return "没有更多了"
- } else if (this.loadingError.length > 0) {
- return this.loadingError
- } else {
- return ""
- }
- }
- },
- created() {
- if (this.preload) {
- this.loadData(null)
- }
- },
- methods: {
- refreshData(loadComplete : (() => void) | null) {
- this.datagrid.length = 0
- this.currentPage = 1
- this.loadData(loadComplete)
- },
- loadData(loadComplete : (() => void) | null) {
- if (this.loading || this.isEnded) {
- return
- }
- this.loading = true
- uni.request<ResponseDataType>({
- url: SERVER_URL,
- data: {
- type: this.type,
- page: this.currentPage,
- page_size: PAGE_SIZE
- },
- success: (res) => {
- const responseData = res.data
- if (responseData == null) {
- return
- }
- this.datagrid.push(...responseData.data)
- if (responseData.data.length == 0) {
- this.isEnded = true
- } else {
- this.currentPage++
- }
- },
- fail: (err) => {
- this.loadingError = err.errMsg
- },
- complete: () => {
- this.loading = false
- if (loadComplete != null) {
- loadComplete()
- }
- }
- })
- },
- // score 0 ~ 50
- convertToStarUnicode(score : number) : string {
- const fill_code = '\ue879'
- const half_code = '\ue87a'
- const null_code = '\ue87b'
- const fillStarCount = parseInt(score / 10 % 10 + '')
- const halfStarCount = score % 10 >= 5 ? 1 : 0
- const nullStarCount = 5 - fillStarCount - halfStarCount
- let result = ''
- if (fillStarCount > 0) { result += fill_code.repeat(fillStarCount) }
- if (halfStarCount > 0) { result += half_code.repeat(halfStarCount) }
- if (nullStarCount > 0) { result += null_code.repeat(nullStarCount) }
- return result
- }
- }
- }
- </script>
- <style>
- @font-face {
- font-family: "UtsStarIcons";
- src: url('@/static/fonts/icon-star.ttf');
- }
- .grid {
- flex: 1;
- background-color: #f7f7f7;
- }
- .flow-item {
- flex-direction: column;
- border-radius: 5px;
- background-color: #ffffff;
- }
- .flow-item-icon {
- position: relative;
- }
- .flow-item-icon-image {
- width: 100%;
- }
- .flow-item-fill {
- flex: 1;
- padding: 5px;
- }
- .description-text {
- font-size: 13px;
- color: #666;
- line-height: 19px;
- }
- .icon-star {
- font-family: "UtsStarIcons";
- font-size: 16px;
- font-style: normal;
- color: #ffca3e;
- letter-spacing: 3px;
- }
- .tag-grid {
- flex-direction: row;
- margin-top: 5px;
- }
- .tag-item {
- font-size: 12px;
- background-color: #EFF9F0;
- color: #639069;
- border-radius: 20px;
- margin-right: 5px;
- padding: 2px 5px;
- }
- .update-date {
- margin-top: 10px;
- }
- .update-date-text {
- font-size: 12px;
- color: #888888;
- }
- .update-date-value {
- font-size: 12px;
- color: #777777;
- margin-left: 5px;
- }
- .author {
- font-size: 12px;
- color: #008000;
- }
- .loading {
- padding: 30px;
- align-items: center;
- height: 80px;
- }
- .flex-row {
- flex-direction: row;
- }
- </style>
|