<script setup> /** * 搜索 */ import { ref, reactive, getCurrentInstance, computed, } from 'vue'; import { onLoad, onReady, onPullDownRefresh, onReachBottom } from '@dcloudio/uni-app' // 工具库 import util from '@/common/js/util'; // api import api from '@/api/index.js' // 顶部状态栏 import statusBar from '@/components/header/statusBar.vue' const { proxy } = getCurrentInstance() // 搜索状态 const searchState = ref(false) // 搜索记录 const searchLog = reactive([]) // 热点视频 const hotVideoList = reactive([]) // 分类列表 const tabList = reactive([{ name: '视频', getList: () => getVideoList(), getMoreList: () => getMoreVideoList(), refreshList: () => refreshVideoList() }, { name: '用户', getList: () => getFriendList(), getMoreList: () => getMoreFriendList(), refreshList: () => refreshFriendList() }, ]) // 分类下标 const tabIndex = ref(0) // 搜索关键字 const keyword = ref('') // 视频列表 const videoList = reactive({ data: [], pageNum: 1, pageSize: 10, total: 0, }) // 用户列表 const userList = reactive({ data: [], pageNum: 1, pageSize: 10, total: 0, }) onLoad(() => { // 获取用户搜索记录 getSearchLog() // 获取热点视频 getHotVideo() }) onReachBottom(() => { // 获取更多列表 if (searchState.value) tabList[tabIndex.value].getMoreList() }) onPullDownRefresh(() => { if (!searchState.value) { uni.stopPullDownRefresh() return } // 刷新 tabList[tabIndex.value].refreshList() }) // 获取用户搜索记录 function getSearchLog() { // api.video.videoSearchLog().then(rs => { if (rs.code == 200) { searchLog.push(...rs.data) return } util.alert({ content: rs.msg, showCancel: false, }) }) } // 获取热点视频 function getHotVideo() { // 热点视频 api.video.hotVideos().then(rs => { if (rs.code == 200) { hotVideoList.push(...rs.data) return } util.alert({ contuent: rs.msg, showCancel: false, }) }) } // tab下标 function handleTabIndex(index) { if (tabIndex.value === index) return tabIndex.value = index // 重载 tabList[tabIndex.value].refreshList() } /** * 查看用户主页 * @param {Object} item */ function handleUser(item) { uni.navigateTo({ url: util.setUrl('/pages/index/videoHome', { userId: item.userId }) }) } // 搜索 function handleSearch() { if (!keyword.value) { searchState.value = false return } else searchState.value = true // 获取列表 tabList[tabIndex.value].getList() } // 重载视频列表 function refreshVideoList() { videoList.pageNum = 1 videoList.total = 0 getVideoList() } // 获取更多视频列表 function getMoreVideoList() { if (videoList.data.length >= videoList.total) return videoList.pageNum++ getVideoList() } // 获取视频列表 function getVideoList() { api.video.videoSearch({ query: { // 搜索 search: keyword.value, pageNum: videoList.pageNum, pageSize: videoList.pageSize, } }).then(rs => { console.log('videoSearch', rs) if (rs.code == 200) { if (videoList.pageNum) videoList.data.length = 0 // 追加视频列表 videoList.data.push(...rs.rows.map(item => { item.format_videoUrl = util.format_url(item.videoUrl, 'video') item.format_header = util.format_url(item.header, 'img') item.format_imageUrl = util.format_url(item.imageUrl, 'img') return item })) // 视频列表 videoList.total = rs.total console.log('videoList', videoList.data) return } util.alert({ content: rs.msg, showCancel: false, }) }).finally(() => { uni.stopPullDownRefresh() }) } // 重载朋友列表 function refreshFriendList() { userList.pageNum = 1 userList.total = 0 getFriendList() } // 获取更多朋友列表 function getMoreFriendList() { if (userList.data.length >= userList.total) return userList.pageNum++ getFriendList() } // 获取朋友列表 function getFriendList() { api.video.searchFriendByName({ path: [keyword.value], query: { pageNum: userList.pageNum, pageSize: userList.pageSize, } }).then(rs => { console.log(rs) if (rs.code == 200) { if (userList.pageNum) userList.data.length = 0 // 追加朋友列表 userList.data.push(...rs.rows.map(item => { item.format_userPortrait = util.format_url(item.userPortrait, 'img') return item })) // 视频列表 userList.total = rs.total return } util.alert({ content: rs.msg, showCancel: false, }) }).finally(() => { uni.stopPullDownRefresh() }) } /** * 点击当前元素搜索 * @param {Object} item 被点击的元素 * @param {String} key 键 */ function handleItemSearch(item, key) { keyword.value = item[key] // 搜索 handleSearch() } // 跳转视频 function handleVideo(item) { console.log('handleVideo', item) // uni.navigateTo({ url: util.setUrl('/pages/index/videoDetail', { videoId: item.videoId }) }) } </script> <template> <view class="appbw"> <view class="ghost"> <statusBar /> <view class="head"></view> </view> <view class="apex"> <statusBar /> <!-- 头部 --> <view class="header head df aic plr30"> <navigator open-type="navigateBack" class="back b"> <uni-icons type="left" size="48rpx" color="#333" /> </navigator> <view class="search df aic ml20 f1 ptb5 plr15 bar"> <uni-icons type="search" size="32rpx" color="#aaa" /> <input class="ml20 f32" v-model="keyword" placeholder="请输入关键字" /> <view class="btn bar sm colourful w120" @click="handleSearch">搜索</view> </view> </view> </view> <!-- 搜索状态 --> <template v-if="!searchState"> <!-- 历史记录 --> <view class="searchList mtb30 mlr30"> <view class="rows"> <view class="title c333 f28 b">历史记录</view> </view> <view class="list mt20 c333 f24"> <view class="item dib mtb10 mlr10 ptb10 plr20 bar" v-for="(item,index) in searchLog" :key="index" @click="handleItemSearch(item,'search')">{{item.search}}</view> <view class="nomore mtb20" v-if="!searchLog[0]">暂无搜索记录</view> </view> </view> <!-- 搜索发现 --> <view class="searchList mtb30 mlr30" v-if="0"> <view class="rows"> <view class="title c333 f28 b">搜索发现</view> </view> <view class="list mt20 c333 f24"> <view class="item dib mtb10 mlr10 ptb10 plr20 bar" v-for="(item,index) in 15" :key="index">电商</view> </view> </view> <!-- 热门搜索 --> <view class="hotList mtb30 mlr30 c333"> <view class="title f28 b">热门搜索</view> <view class="list"> <view class="item df aic jcsb ptb20" v-for="(item,index) in hotVideoList" :key="index" @click="handleItemSearch(item,'title')"> <view class="rank c666 f32 b">{{index + 1}}</view> <view class="content df aic f1 mlr15 f24"> <text>{{item.title}}</text> <template v-if="0"> <view class="label hot" v-if="index % 2 == 0">热</view> <view class="label new" v-if="index % 2 == 1">新</view> </template> <view class="f1"></view> </view> <view class="number f22">热度{{item.play}}</view> <view class="change wh40" v-if="0"> <image src="/static/hotSearchUp.png" mode="aspectFit" v-if="1" /> <image src="/static/hotSearchDefault.png" mode="aspectFit" v-else-if="1" /> <image src="/static/hotSearchDown.png" mode="aspectFit" v-else /> </view> </view> </view> </view> </template> <!-- 搜索结果 --> <template v-else> <!-- tab --> <view class="tabList df plr15"> <view class="item df fdc aic plr20" v-for="(item,index) in tabList" :key="index" :class="{'active': index === tabIndex}" @click="handleTabIndex(index)"> <view class="txt">{{item.name}}</view> <view class="line"></view> </view> </view> <!-- 列表容器 --> <view class="listBox ptb15 plr15"> <!-- 视频列表 --> <view class="videoList" v-if="tabIndex === 0"> <view class="item oh mb25 plr30 c333 bfff br20" v-for="(item,index) in videoList.data" :key="index" @click="handleVideo(item)"> <!-- 用户 --> <view class="userinfo df aic mtb25"> <view class="avatar" @click.stop="handleUser(item)"> <image class="wh70 cir" :src="item.format_header" mode="aspectFill" /> </view> <view class="user ml15 f1"> <view class="nickname f32">{{item.userName}}</view> <view class="date mt10 c999 f24">{{item.createTime}}</view> </view> </view> <!-- 简介 --> <view class="desc mtb20 f28">{{item.title}}</view> <!-- 封面图 --> <view class="coverImg mtb20"> <image :src="item.format_imageUrl" mode="aspectFill" class="br25" /> </view> <!-- 菜单 --> <view class="menu df mtb20 c333 f28"> <!-- 点赞数量 --> <view class="option f1 fmid"> <image class="wh30" src="/static/indexLike.png" mode="aspectFit" v-if="item.isLike == 0" /> <image class="wh30" src="/static/indexLike1.png" mode="aspectFit" v-else /> <view class="number ml10">{{item.likes}}</view> </view> <!-- 评论数量 --> <view class="option f1 fmid"> <image class="wh30" src="/static/indexMsg.png" mode="aspectFit" /> <view class="number ml10">{{item.comment}}</view> </view> <!-- 收藏数量 --> <view class="option f1 fmid"> <image class="wh30" src="/static/indexCollect.png" mode="aspectFit" /> <view class="number ml10">{{item.collect}}</view> </view> <!-- 转发数量 --> <view class="option f1 fmid" v-if="0"> <image class="wh30" src="/static/indexShare.png" mode="aspectFit" /> <view class="number ml10">666.6w</view> </view> </view> <!-- 用户热评 --> <view class="userMsg df aic mtb25" v-if="0"> <view class="avatar"> <image class="wh70 cir" src="/static/openPage.png" mode="aspectFill" /> </view> <view class="user ml15 f1"> <view class="nickname c666 f28">超级果农大王</view> <view class="txt thd f24">真是美味呀 ,多买点儿!!!</view> </view> <view class="option fmid"> <image class="wh30" src="/static/indexLike1.png" mode="aspectFit" /> <view class="number ml10 c666 f28">6.6w</view> </view> </view> </view> </view> <!-- 用户列表 --> <view class="userList" v-if="tabIndex === 1"> <view class="item df aic mtb40 plr10" v-for="(item,index) in userList.data" :key="index" @click="handleUser(item)"> <view class="avatar fs0"> <image class="wh110 cir" :src="item.format_userPortrait" mode="aspectFill" /> </view> <view class="user oh f1 mlr25"> <view class="nickname c333 f32">{{item.userNickname}}</view> <view class="fans c999 f24">粉丝:{{item.userFans}}</view> </view> <view class="button fs0"> <view class="btn cancel w150" v-if="item.isAttention">取消关注</view> <view class="btn focus w150" v-else>关注</view> </view> </view> </view> </view> </template> </view> </template> <style lang="scss"> image { width: 100%; height: 100%; } // 顶部 .apex { position: fixed; top: 0; left: 0; right: 0; z-index: 1; background-color: #fff; } // .search { height: 60rpx; background-color: #f1f1f1; } // 搜索列表 .searchList { // 单项 .item { background-color: #f1f1f1; } } // 热搜列表 .hotList { .item+.item { border-top: 1rpx solid #F6F6F6; } .item:nth-child(1) .number { color: #FF0F2E; } .item:nth-child(2) .number { color: #FF370F; } .item:nth-child(3) .number { color: #FF630F; } // 热度 .number { color: #999999; } // 标签 .label { margin-left: 20rpx; padding: 2rpx 10rpx; font-size: 20rpx; color: #fff; border-radius: 50rpx 50rpx 50rpx 2rpx; // 热 &.hot { background-color: #FF0F2E; } // 新 &.new { background-image: linear-gradient(123deg, #27EFE2 0%, #A45EFF 43%, #FF004F 99%); } } } // 分栏列表 .tabList { .item { .line { background-color: #333; width: 0; height: 10rpx; border-radius: 100rpx; } // 激活的 &.active { .txt { font-weight: bold; } .line { width: 30rpx; } } } } // 列表容器 .listBox { min-height: 95vh; background-color: #f8f8f8; .videoList { .coverImg { height: 376rpx; } } } </style>