💎一站式轻松地调用各大LLM模型接口,支持GPT4、智谱、星火、月之暗面及文生图 广告
# 失物招领页面 [TOC] 功能点: * [ ] Mock * [ ] 分页加载数据 * [ ] 上拉加载更多 * [ ] Tab * [ ] 搜索 项目完整代码: ``` https://gitee.com/zengqs/uni-app-course-2019/tree/master/lostAndFind ``` ## Mock数据 /common/api/lost.js ``` const Mock = require('mockjs') export default { getList(map = {}) { console.log(map); return new Promise((resolve, reject) => { //返回分页数据 let mockOption = { errno: 0, errmsg: '获取信息成功', data: { count: 28, totalPages: 3, pageSize: () => { return parseInt(map.pageSize || 5); }, currentPage: () => { return parseInt(map.page || 1); }, 'data|10': [{ 'id': '@increment()', // "title": "雨伞", //项目名称 title: () => { if (map.key) { return map.key } else { return "雨伞" } }, 'name': '@cname()', "address": "广州番禺职业技术学院6号楼6517", "telphone": /^1[345789]\d{9}$/, "images": ["@image('200x200')", "@image('200x200')", "@image('200x200')"], // "type|1": ["丢失", "捡到"], "type": () => { if (map.type == "" || map.type == '全部') { let list = ["丢失", "捡到"]; return list[Mock.Random.integer(0, list.length - 1)]; } else { return map.type } }, "date": "@date()" }] } } resolve(Mock.mock(mockOption)) }); }, getInfo(id, map = {}) { return new Promise((resolve, reject) => { let mockOption = { errno: 0, errmsg: '获取信息成功', 'data': { 'id': '@increment()', // "title": "雨伞", //项目名称 title: () => { if (map.key) { return map.key } else { return "雨伞" } }, 'name': '@cname()', "address": "广州番禺职业技术学院6号楼6517", "telphone": /^1[345789]\d{9}$/, "images": ["@image('200x200')", "@image('200x200')", "@image('200x200')"], // "type|1": ["丢失", "捡到"], "type": () => { if (map.type == "" || map.type == '全部') { let list = ["丢失", "捡到"]; return list[Mock.Random.integer(0, list.length - 1)]; } else { return map.type } }, "date": "@date()" } } resolve(Mock.mock(mockOption)) }) }, } ``` 文件:/common/api/index.js ``` import lost from './lost.js' export default { lost, } export { lost } ``` ## 查找页面 文件: `/pages/tabbar/lost/index.vue` ![](https://box.kancloud.cn/af40f632b3aa93dadb21af0f4b581627_417x739.png) ``` <template> <view class="ts-column ts-flex-item"> <swiper :indicator-dots="true" :autoplay="true" :interval="3000" :duration="1000"> <swiper-item> <view class="swiper-item"> <ts-banner class="ts-row ts-flex-item" image="http://dev.zengqs.com/resource/images/app/syb/banner-1.jpg" :height="350"></ts-banner> </view> </swiper-item> <swiper-item> <view class="swiper-item"> <ts-banner class="ts-row ts-flex-item" image="http://dev.zengqs.com/resource/images/app/syb/banner-2.jpg" :height="350"></ts-banner> </view> </swiper-item> <swiper-item> <view class="swiper-item"> <ts-banner class="ts-row ts-flex-item" image="http://dev.zengqs.com/resource/images/app/syb/banner-3.jpg" :height="350"></ts-banner> </view> </swiper-item> <swiper-item> <view class="swiper-item"> <ts-banner class="ts-row ts-flex-item" image="http://dev.zengqs.com/resource/images/app/syb/banner-4.jpg" :height="350"></ts-banner> </view> </swiper-item> <swiper-item> <view class="swiper-item"> <ts-banner class="ts-row ts-flex-item" image="http://dev.zengqs.com/resource/images/app/syb/banner-1.jpg" :height="350"></ts-banner> </view> </swiper-item> </swiper> <ts-search-bar :keywords="keywords" @search="doSearch"></ts-search-bar> <view class="ts-row ts-flex-item"> <ts-segmented-control :values="tabs" styleType="text" @clickItem="onClickItem"></ts-segmented-control> </view> <view class="ts-column" v-for="(item ,index) in searchResult" :key="index"> <view class="ts-row ts-padding" style="align-items:flex-start;"> <view class=""> <image src="http://dev.zengqs.com/resource/images/app/lost/female-350x420.jpg" style="width: 100upx; height: 100upx; border-radius: 75upx;"></image> </view> <view class="ts-section ts-padding-left"> <view class="ts-section-title"> <view class="ts-row"> <view class="ts-flex-item" style="align-items: flex-end;"> <text class="ts-h4">{{item.name}} </text> <text class="ts-h6 ts-padding-left">{{item.telphone}}</text> </view> <view> <ts-badge :text="item.type" type="success" size="small"></ts-badge> </view> </view> </view> <view class="ts-section-body"> <view class="ts-row ts-h4" style="justify-content: space-between;"> {{item.title}} </view> <view class="ts-row" style="justify-content: space-between;"> {{item.address}} </view> <view class="ts-row" style="flex-wrap: wrap;"> <view class="ts-row ts-padding-right ts-padding-bottom" v-for="(img,idx) in item.images" :key="idx" style="width: 150upx; height: 150upx;"> <image :src="img" style="width: 100%; height: 100%;"></image> </view> </view> </view> </view> </view> <ts-gap></ts-gap> </view> <ts-load-more :loadingType="loadingType"></ts-load-more> </view> </template> <script> import api from '@/common/api'; export default { data() { return { currentTab: 0, tabs: ['全部', '丢失', '捡到'], searchResult: [], type: '全部', keywords: '', page: 0, loadingType: 0, } }, async onReachBottom() { await this.loadMoreSearcheResult(); }, async onLoad() { await this.loadMoreSearcheResult(); }, methods: { async doSearch(keywords = "") { this.keywords = keywords; let types = ['全部', '丢失', '捡到']; this.type = types[this.currentTab]; this.searchResult = []; this.loadingType = 0; await this.loadMoreSearcheResult(); }, async loadMoreSearcheResult() { //上拉的状态:0-loading前;1-loading中;2-没有更多了 if (this.loadingType !== 0) { return; } this.loadingType = 1; this.page = this.page + 1; // api.lost.getList({ // page: this.page, // key: this.keywords, // type: this.type, // }).then(res => { // if (res.errno === 0) { // const data = res.data; // if (data && data.data) { // this.searchResult = this.searchResult.concat(data.data); // } // if (data.totalPages === data.currentPage) { // this.loadingType = 2; //2-没有更多了 // } else { // this.loadingType = 0; //开启新一轮加载 // } // } else { // console.log(res.errmsg); // } // }); let res = await api.lost.getList({ page: this.page, key: this.keywords, type: this.type, pageSize: 5, }); if (res.errno === 0) { const data = res.data; if (data && data.data) { console.log(data); this.searchResult = this.searchResult.concat(data.data); } if (data.totalPages === data.currentPage) { this.loadingType = 2; //2-没有更多了 } else { this.loadingType = 0; //开启新一轮加载 } } else { console.log(res.errmsg); } }, async onClickItem(index) { if (this.currentTab !== index) { this.currentTab = index; await this.doSearch(); } } } } </script> <style> </style> ``` ## 发布页面 ![](https://box.kancloud.cn/83f809c7504f3f7255df98e281be3e13_424x741.png) ``` <template> <view class="ts-column ts-padding"> <view class="ts-row"> <view class="ts-row ts-padding" style="flex:1;"> <ts-button :borderRadius="30" type="success" :inverted="type!='lost'" @click="switchType">丢失</ts-button> </view> <view class="ts-row ts-padding" style="flex:1;"> <ts-button :borderRadius="30" type="success" :inverted="type==='lost'" @click="switchType">捡到</ts-button> </view> </view> <view class="ts-row ts-padding"> </view> <view class="ts-row"> <view class="ts-row" style="flex:1;"> 我的名字 </view> <view class="ts-row" style="flex:3;"> <input type="text" placeholder="请填写您的姓名" /> </view> </view> <view class="ts-row"> <view class="ts-row" style="flex:1;"> 联系方式 </view> <view class="ts-row" style="flex:3;"> <input type="text" placeholder="请填写您的手机号码" /> </view> </view> <view class="ts-row"> <view class="ts-row" style="flex:1;"> {{typeMessage}}物品 </view> <view class="ts-row" style="flex:3;"> <input type="text" placeholder="请填写丢失物品的名称" /> </view> </view> <view class="ts-row"> <view class="ts-row" style="flex:1;"> {{typeMessage}}地点 </view> <view class="ts-row" style="flex:3;"> <input type="text" placeholder="请填写丢失物品的地点" /> </view> </view> <view class="ts-column"> <view class="ts-row ts-flex-item ts-h6"> 上传{{typeMessage}}物品的图片,方便找回,最多上传3张图片。 </view> <view class="ts-row ts-flex-item"> <ts-image-uploader :count="3"></ts-image-uploader> </view> </view> <view class="ts-column"> <view class="ts-row ts-flex-item"> <ts-button>发布</ts-button> </view> </view> </view> </template> <script> import tsImageUploader from "@/components/teaset/components/ts-image-uploader/ts-image-uploader.vue" export default { components: { tsImageUploader }, data() { return { type: "lost" } }, methods: { switchType() { this.type = this.type == "lost" ? "" : "lost"; } }, computed: { typeMessage() { return (this.type == "lost" ? "丢失" : "捡到"); } } } </script> <style> view { font-size: 32upx; line-height: 2.2em; } input { border-bottom: #C0C0C0 solid 1px; display: flex; flex: 3; } </style> ```