主頁 > 前端設計 > uni-app實戰之社區交友APP(4)首頁開發

uni-app實戰之社區交友APP(4)首頁開發

2021-01-27 12:50:50 前端設計

文章目錄

  • 前言
  • 一、圖文串列樣式開發
    • 1.pages.json配置
    • 2.頭像、昵稱和關注按鈕
    • 3.標題和互動按鈕
    • 4.封裝樣式組件
  • 二、串列組件優化
    • 1.全域分割線開發
    • 2.影片特效
    • 3.關注功能完善
    • 4.頂踩功能
  • 三、滾動選項卡開發
    • 1.選項卡動態顯示
    • 2.串列滑動實作
    • 3.串列顯示和同步
    • 4.上拉加載開發
    • 5.封裝上拉加載組件
    • 6.封裝無資料默認組件
  • 總結

前言

本文主要介紹了首頁圖文串列和滾動選項卡的開發:
圖文串列的開發,包括頂部導航欄配置,圖文串列項(頭像、昵稱、關注按鈕、標題、標題封面圖、點贊、踩、評論和分享)等的開發;
串列組件優化,包括分割線的開發和封裝,影片特效實作,關注、頂踩功能的完善;
滾動選項卡開發,包括頂部選項卡開發、串列的同步顯示和滑動,上拉加載的開發和封裝,無資料組件開發等,

一、圖文串列樣式開發

1.pages.json配置

洗掉之前創建的demo頁面及其目錄,之前在配置pages.json時,"pages"中并未設定style,此時需要設定"app-plus",即配置編譯到 App 平臺時的特定樣式,

先下載發帖的圖示,演示如下:
uniapp social app index develop post icon add

解壓下載后的壓縮包并將其中的iconfont.ttf復制到專案目錄下的static目錄下,并作為首頁配置的app-plus>titleNView>buttons>fontSrc
同時在我的專案頁面選擇Unicode,并復制發帖icon的代碼,例如,修改為uni-app支持的格式\ue668,作為app-plus>titleNView>buttons>text
關于app-plus的說明可參考檔案https://uniapp.dcloud.io/collocation/pages?id=app-plus,

pages.json如下:

{
	"pages": [ //pages陣列中第一項表示應用啟動頁,參考:https://uniapp.dcloud.io/collocation/pages
		{
			"path": "pages/index/index",
			"style": {
				"app-plus": {
					// 導航欄配置
					"titleNView": {
						// 搜索框配置
						"searchInput": {
							"align":"center",
							"backgroundColor":"#F5F4F2",
							"borderRadius":"4px",
							"disabled": true,
							"placeholder": "搜索帖子",
							"placeholderColor": "#6D6C67"
						},
						// 按鈕設定
						"buttons": [
							{
								"color":"#333333",
								"colorPressed":"#FD597C",
								"float":"right",
								"fontSize":"20px",
								"fontSrc":"/static/iconfont.ttf",
								"text": "\ue668"
							}
						]
					}
				}
			}
		}
	    ,{
            "path" : "pages/news/news",
            "style" :                                                                                    
            {
                "navigationBarTitleText": "",
                "enablePullDownRefresh": false
            }
            
        }
        ,{
            "path" : "pages/msg/msg",
            "style" :                                                                                    
            {
                "navigationBarTitleText": "",
                "enablePullDownRefresh": false
            }
            
        }
        ,{
            "path" : "pages/my/my",
            "style" :                                                                                    
            {
                "navigationBarTitleText": "",
                "enablePullDownRefresh": false
            }
            
        }
        
    ],
	"globalStyle": {
		"navigationBarTextStyle": "black",
		"navigationBarTitleText": "Community Dating",
		"navigationBarBackgroundColor": "#FFFFFF",
		"backgroundColor": "#FFFFFF"
	},
	"tabBar": {
		"color":"#323232",
		"selectedColor":"#ED6384",
		"backgroundColor":"#FFFFFF",
		"borderStyle": "black",
		"list": [
			{
				"pagePath": "pages/index/index",
				"text": "首頁",
				"iconPath": "static/tabbar/index.png",
				"selectedIconPath": "static/tabbar/indexed.png"
			},
			{
				"pagePath": "pages/news/news",
				"text": "動態",
				"iconPath": "static/tabbar/news.png",
				"selectedIconPath": "static/tabbar/newsed.png"
			},
			{
				"pagePath": "pages/msg/msg",
				"text": "訊息",
				"iconPath": "static/tabbar/paper.png",
				"selectedIconPath": "static/tabbar/papered.png"
			},
			{
				"pagePath": "pages/my/my",
				"text": "我的",
				"iconPath": "static/tabbar/home.png",
				"selectedIconPath": "static/tabbar/homed.png"
			}
		]
	}
}

顯示:
uniapp social app index develop pages search show

可以看到,定義出了搜索框和發帖按鈕,點擊按鈕會改變顏色,

2.頭像、昵稱和關注按鈕

uni-app 支持的通用 css 單位包括 px、rpx:

  • px
    即螢屏像素,
  • rpx
    即回應式px,一種根據螢屏寬度自適應的動態單位,以750寬的螢屏為基準,750rpx恰好為螢屏寬度,

開發者可以通過設計稿基準寬度計算頁面元素 rpx 值,設計稿 1px 與框架樣式 1rpx 轉換公式為設計稿 1px / 設計稿基準寬度 = 框架樣式 1rpx / 750rpx,所以頁面元素寬度在 uni-app 中的寬度計算公式為750 * 元素在設計稿中的寬度 / 設計稿基準寬度
更多可參考https://uniapp.dcloud.io/frame?id=尺寸單位,

index.vue頁面設定頭像顯示如下:

<template>
	<view>
		<image src="/static/img/userpic/12.jpg" style="width: 65rpx; height: 65rpx;"></image>
	</view>
</template>

<script>
	export default {
		data() {
			return {

			}
		},
		onLoad() {

		},
		methods: {

		}
	}
</script>

<style>

</style>

顯示:
uniapp social app index develop list header

在不同尺寸的設備上,其大小會自動縮放,

如需直接使用樣式和素材等檔案,可以直接點擊加QQ群 Python極客部落963624318 ,在群檔案夾uni-app實戰之社區交友APP中下載即可,

先實作圖文串列的第一部分,即頭像、昵稱和關注按鈕,如下:

<template>
	<view>
		<!-- 串列樣式 -->
		<view style="padding: 20rpx;">
			<!-- 頭像、昵稱和關注按鈕 -->
			<view style="display: flex; align-items: center; justify-content: space-between;">
				<view style="display: flex; align-items: center;">
					<!-- 頭像 -->
					<image src="/static/img/userpic/12.jpg" mode="" style="width: 65rpx; height: 65rpx; border-radius: 100%; margin-right: 20rpx;" lazy-load></image>
					<!-- 昵稱和發布時間 -->
					<view>
						<view style="font-size: 30rpx; line-height: 1.5;">Corley</view>
						<text style="color: #9D9589; font-size: 25rpx; line-height: 1.5;">2021-01-24 上午11:20</text>
					</view>
				</view>
				<!-- 按鈕 -->
				<view style="width: 90rpx; height: 50rpx; display: flex; align-items: center; justify-content: center; border-radius: 5rpx; background-color: #FF4A6A; color: #FFFFFF;">
					關注
				</view>
			</view>
			<!-- 標題 -->
			<view></view>
			<!-- 圖片 -->
			<view></view>
			<!-- 圖示按鈕 -->
			<view></view>
		</view>
	</view>
</template>

<script>
	export default {
		data() {
			return {

			}
		},
		onLoad() {

		},
		methods: {

		}
	}
</script>

<style>

</style>

顯示:
uniapp social app index develop list header nickname follow

顯然,實作了頭像、昵稱、發布日期和關注按鈕的展示,

3.標題和互動按鈕

現進一步實作串列項的第二部分,即發帖標題、點贊、評論和分享等,

先按照之前的方法在https://www.iconfont.cn/中添加點贊、踩、評論和分享的圖示,再將iconfont.css更新至common/icon.css中,

index.vue如下:

<template>
	<view>
		<!-- 串列樣式 -->
		<view style="padding: 20rpx;">
			<!-- 頭像、昵稱和關注按鈕 -->
			<view style="display: flex; align-items: center; justify-content: space-between;">
				<view style="display: flex; align-items: center;">
					<!-- 頭像 -->
					<image src="/static/img/userpic/12.jpg" mode="" style="width: 65rpx; height: 65rpx; border-radius: 100%; margin-right: 20rpx;"
					 lazy-load></image>
					<!-- 昵稱和發布時間 -->
					<view>
						<view style="font-size: 30rpx; line-height: 1.5;">Corley</view>
						<text style="color: #9D9589; font-size: 25rpx; line-height: 1.5;">2021-01-24 上午11:20</text>
					</view>
				</view>
				<!-- 按鈕 -->
				<view style="width: 90rpx; height: 50rpx; display: flex; align-items: center; justify-content: center; border-radius: 5rpx; background-color: #FF4A6A; color: #FFFFFF;">
					關注
				</view>
			</view>
			<!-- 標題 -->
			<view style="font-size: 30rpx; margin: 10rpx 0;">
				uni-app入門教程
			</view>
			<!-- 圖片 -->
			<image src="/static/img/datapic/42.jpg" style="height: 350rpx; width: 100%; border-radius: 5rpx;"></image>
			<!-- 圖示按鈕 -->
			<view style="display: flex; align-items: center;">
				<view style="flex: 1; display: flex; align-items: center; justify-content: center;">
					<text class="iconfont icon-dianzan" style="margin-right: 20rpx;"></text>
					<text>1</text>
				</view>
				<view style="flex: 1; display: flex; align-items: center; justify-content: center;">
					<text class="iconfont icon-cai" style="margin-right: 20rpx;"></text>
					<text>1</text>
				</view>
				<view style="flex: 1; display: flex; align-items: center; justify-content: center;">
					<text class="iconfont icon-pinglun" style="margin-right: 20rpx;"></text>
					<text>1</text>
				</view>
				<view style="flex: 1; display: flex; align-items: center; justify-content: center;">
					<text class="iconfont icon-fenxiang" style="margin-right: 20rpx;"></text>
					<text>1</text>
				</view>
			</view>
		</view>
	</view>
</template>

<script>
	export default {
		data() {
			return {

			}
		},
		onLoad() {

		},
		methods: {

		}
	}
</script>

<style>

</style>

顯示:
uniapp social app index develop list header dianzan cai

可以看到,已經實作了一個串列項的基本內容,

4.封裝樣式組件

雖然已經實作了串列,但是可以看到代碼很冗余、有大量CSS重復代碼,同時串列可以復用,也可以封裝成組件,來提高代碼的復用率
先優化專案代碼,將CSS樣式提取到公共的CSS檔案中,
common下新建檔案base.css,保存公共樣式如下:

/* 內外邊距 */
.p-2 {
	padding: 20rpx;
}

/* flex布局 */
.flex {
	display: flex;
}
.align-center {
	align-items: center;
}
.justify-between {
	justify-content: space-between;
}
.justify-center {
	justify-content: center;
}
.flex-1 {
	flex: 1;
}

/* 圓角 */
.rounded-circle {
	border-radius: 100%;
}
.rounded {
	border-radius: 8rpx;
}

/* margin */
.mr-2 {
	margin-right: 20rpx;
}
.my-1 {
	margin-top: 10rpx;
	margin-bottom: 0rpx;
}

/* 字體 */
.font-md {
	font-size: 35rpx;
}
.font {
	font-size: 30rpx;
}
.font-sm {
	font-size: 25rpx;
}

/* 文字顏色 */
.text-white {
	color: #FFFFFF;
}
.text-light-muted {
	color: #A9A5A0; 
}

/* 寬度 */
/* #ifndef APP-PLUS-NVUE */
.w-100 {
	width: 100%;
}
/* #endif */

base.css檔案不僅可以應用于該專案,也可以應用于其他uni-app專案,

common目錄下新建common.css保存本專案全域樣式,如下:

/* 本專案全域樣式 */
.bg-main {
	background-color: #FF4A6A;
}

App.vue中匯入CSS檔案,如下:

<script>
	export default {
		onLaunch: function() {
			console.log('App Launch')
		},
		onShow: function() {
			console.log('App Show')
		},
		onHide: function() {
			console.log('App Hide')
		}
	}
</script>

<style>
	/*每個頁面公共css */
	/* 官方CSS庫 */
	@import url("./common/uni.css");
	/* 自定義圖示庫 */
	@import url("./common/icon.css");
	/* 影片庫 */
	@import url("./common/animate.css");
	/* 自定義樣式庫 */
	@import url("./common/base.css");
	/* 全域樣式 */
	@import url("./common/common.css");
</style>

index.vue簡化如下:

<template>
	<view>
		<!-- 串列樣式 -->
		<view class="p-2">
			<!-- 頭像、昵稱和關注按鈕 -->
			<view class="flex align-center justify-between">
				<view class="flex align-center">
					<!-- 頭像 -->
					<image class="rounded-circle mr-2" src="/static/img/userpic/12.jpg" mode="" style="width: 65rpx; height: 65rpx;"
					 lazy-load></image>
					<!-- 昵稱和發布時間 -->
					<view>
						<view class="font" style="line-height: 1.5;">Corley</view>
						<text class="font-sm text-light-muted" style="line-height: 1.5;">2021-01-24 上午11:20</text>
					</view>
				</view>
				<!-- 按鈕 -->
				<view class="flex align-center justify-center rounded bg-main text-white" style="width: 90rpx; height: 50rpx;">
					關注
				</view>
			</view>
			<!-- 標題 -->
			<view class="font my-1">
				uni-app入門教程
			</view>
			<!-- 圖片 -->
			<image class="rounded w-100" src="/static/img/datapic/42.jpg" style="height: 350rpx;"></image>
			<!-- 圖示按鈕 -->
			<view class="flex align-center">
				<view class="flex align-center justify-center flex-1">
					<text class="iconfont icon-dianzan mr-2"></text>
					<text>1</text>
				</view>
				<view class="flex align-center justify-center flex-1">
					<text class="iconfont icon-cai mr-2"></text>
					<text>1</text>
				</view>
				<view class="flex align-center justify-center flex-1">
					<text class="iconfont icon-pinglun mr-2"></text>
					<text>1</text>
				</view>
				<view class="flex align-center justify-center flex-1">
					<text class="iconfont icon-fenxiang mr-2"></text>
					<text>1</text>
				</view>
			</view>
		</view>
	</view>
</template>

<script>
	export default {
		data() {
			return {

			}
		},
		onLoad() {

		},
		methods: {

		}
	}
</script>

<style>

</style>

顯然,此時代碼更加簡潔美觀,并且可以達到與之前同樣的效果,

現進一步實作將串列項封裝為組件
首先替換資料、實作串列渲染,如下:

<template>
	<view>
		<block v-for="(item, index) in list" :key="index">
			<!-- 串列樣式 -->
			<view class="p-2">
				<!-- 頭像、昵稱和關注按鈕 -->
				<view class="flex align-center justify-between">
					<view class="flex align-center">
						<!-- 頭像 -->
						<image class="rounded-circle mr-2" :src="item.userpic" mode="" style="width: 65rpx; height: 65rpx;"
						 lazy-load></image>
						<!-- 昵稱和發布時間 -->
						<view>
							<view class="font" style="line-height: 1.5;">{{item.username}}</view>
							<text class="font-sm text-light-muted" style="line-height: 1.5;">{{item.newstime}}</text>
						</view>
					</view>
					<!-- 按鈕 -->
					<view class="flex align-center justify-center rounded bg-main text-white" style="width: 90rpx; height: 50rpx;">
						{{item.isFollow?'已關注':'關注'}}
					</view>
				</view>
				<!-- 標題 -->
				<view class="font my-1">
					{{item.title}}
				</view>
				<!-- 圖片 -->
				<image class="rounded w-100" :src="item.titlepic" style="height: 350rpx;"></image>
				<!-- 圖示按鈕 -->
				<view class="flex align-center">
					<view class="flex align-center justify-center flex-1">
						<text class="iconfont icon-dianzan mr-2"></text>
						<text>{{item.support.support_count}}</text>
					</view>
					<view class="flex align-center justify-center flex-1">
						<text class="iconfont icon-cai mr-2"></text>
						<text>{{item.support.unsupport_count}}</text>
					</view>
					<view class="flex align-center justify-center flex-1">
						<text class="iconfont icon-pinglun mr-2"></text>
						<text>{{item.comment_count}}</text>
					</view>
					<view class="flex align-center justify-center flex-1">
						<text class="iconfont icon-fenxiang mr-2"></text>
						<text>{{item.share_count}}</text>
					</view>
				</view>
			</view>
		</block>

	</view>
</template>

<script>
	export default {
		data() {
			return {
				list: [
					{
						username: "Corley",
						userpic: "/static/img/userpic/12.jpg",
						newstime: "2021-01-24 上午11:30",
						isFollow: false,
						title: "uni-app入門教程",
						titlepic: "/static/img/datapic/42.jpg",
						support: {
							type: "support",
							support_count: 1,
							unsupport_count: 2
						},
						comment_count: 2,
						share_count: 2
					},
					{
						username: "Ashley",
						userpic: "/static/img/userpic/20.jpg",
						newstime: "2021-01-24 下午14:00",
						isFollow: true,
						title: "uni-app實戰之社區交友APP",
						titlepic: "/static/img/datapic/30.jpg",
						support: {
							type: "support",
							support_count: 5,
							unsupport_count: 1
						},
						comment_count: 3,
						share_count: 0
					}
				]
			}
		},
		onLoad() {

		},
		methods: {

		}
	}
</script>

<style>

</style>

顯示:
uniapp social app index develop pages list render

顯然,已經實作了串列渲染,

再實作封裝到組件,專案下新建components目錄,下新建common目錄,下建common-list.vue作為串列組件,如下:

<template>
	<view class="p-2">
		<!-- 頭像、昵稱和關注按鈕 -->
		<view class="flex align-center justify-between">
			<view class="flex align-center">
				<!-- 頭像 -->
				<image class="rounded-circle mr-2" :src="item.userpic" mode="" style="width: 65rpx; height: 65rpx;"
				 lazy-load></image>
				<!-- 昵稱和發布時間 -->
				<view>
					<view class="font" style="line-height: 1.5;">{{item.username}}</view>
					<text class="font-sm text-light-muted" style="line-height: 1.5;">{{item.newstime}}</text>
				</view>
			</view>
			<!-- 按鈕 -->
			<view class="flex align-center justify-center rounded bg-main text-white" style="width: 90rpx; height: 50rpx;">
				{{item.isFollow?'已關注':'關注'}}
			</view>
		</view>
		<!-- 標題 -->
		<view class="font my-1">
			{{item.title}}
		</view>
		<!-- 圖片 -->
		<image class="rounded w-100" :src="item.titlepic" style="height: 350rpx;"></image>
		<!-- 圖示按鈕 -->
		<view class="flex align-center">
			<view class="flex align-center justify-center flex-1">
				<text class="iconfont icon-dianzan mr-2"></text>
				<text>{{item.support.support_count}}</text>
			</view>
			<view class="flex align-center justify-center flex-1">
				<text class="iconfont icon-cai mr-2"></text>
				<text>{{item.support.unsupport_count}}</text>
			</view>
			<view class="flex align-center justify-center flex-1">
				<text class="iconfont icon-pinglun mr-2"></text>
				<text>{{item.comment_count}}</text>
			</view>
			<view class="flex align-center justify-center flex-1">
				<text class="iconfont icon-fenxiang mr-2"></text>
				<text>{{item.share_count}}</text>
			</view>
		</view>
	</view>
</template>

<script>
	export default {
		props: {
			item: Object,
			index: Number
		},
	}
</script>

<style>
</style>

index.vue中匯入并使用組件即可,如下:

<template>
	<view>
		<block v-for="(item, index) in list" :key="index">
			<!-- 串列 -->
			<common-list :item="item" :index="index"></common-list>
		</block>

	</view>
</template>

<script>
	import commonList from '@/components/common/common-list.vue';
	export default {
		data() {
			return {
				list: [
					{
						username: "Corley",
						userpic: "/static/img/userpic/12.jpg",
						newstime: "2021-01-24 上午11:30",
						isFollow: false,
						title: "uni-app入門教程",
						titlepic: "/static/img/datapic/42.jpg",
						support: {
							type: "support",
							support_count: 1,
							unsupport_count: 2
						},
						comment_count: 2,
						share_count: 2
					},
					{
						username: "Ashley",
						userpic: "/static/img/userpic/20.jpg",
						newstime: "2021-01-24 下午14:00",
						isFollow: true,
						title: "uni-app實戰之社區交友APP",
						titlepic: "/static/img/datapic/30.jpg",
						support: {
							type: "support",
							support_count: 5,
							unsupport_count: 1
						},
						comment_count: 3,
						share_count: 0
					}
				]
			}
		},
		components: {
			commonList
		},
		onLoad() {

		},
		methods: {

		}
	}
</script>

<style>

</style>

可以達到與之前相同的效果,

二、串列組件優化

1.全域分割線開發

全域分割線也是以組件的形式添加,
先在components/common下新建divider.vue如下:

<template>
	<view style="height: 15rpx; background-color: #F5F5F4;"></view>
</template>

<script>
</script>

<style>
</style>

因為分割線可能在很多地方都會用到,所以可以添加到全域組件,main.js中添加如下:

import Vue from 'vue'
import App from './App'

Vue.config.productionTip = false

// 引入全域組件
import divider from './components/common/divider.vue';
Vue.component('divider', divider)

App.mpType = 'app'

const app = new Vue({
    ...App
})
app.$mount()

index.vue中無需匯入、直接使用即可,如下:

<template>
	<view>
		<block v-for="(item, index) in list" :key="index">
			<!-- 串列 -->
			<common-list :item="item" :index="index"></common-list>
			<!-- 全域分割線 -->
			<divider></divider>
		</block>

	</view>
</template>

<script>
	import commonList from '@/components/common/common-list.vue';
	export default {
		data() {
			return {
				list: [
					{
						username: "Corley",
						userpic: "/static/img/userpic/12.jpg",
						newstime: "2021-01-24 上午11:30",
						isFollow: false,
						title: "uni-app入門教程",
						titlepic: "/static/img/datapic/42.jpg",
						support: {
							type: "support",
							support_count: 1,
							unsupport_count: 2
						},
						comment_count: 2,
						share_count: 2
					},
					{
						username: "Ashley",
						userpic: "/static/img/userpic/20.jpg",
						newstime: "2021-01-24 下午14:00",
						isFollow: true,
						title: "uni-app實戰之社區交友APP",
						titlepic: "/static/img/datapic/30.jpg",
						support: {
							type: "support",
							support_count: 5,
							unsupport_count: 1
						},
						comment_count: 3,
						share_count: 0
					}
				]
			}
		},
		components: {
			commonList
		},
		onLoad() {

		},
		methods: {

		}
	}
</script>

<style>

</style>

顯示:
uniapp social app index develop list divider

可以看到,有比較明顯的分割線效果,

2.影片特效

現在進一步給串列組件添加影片特效,

因為有的帖子沒有封面圖,因此需要v-if進行判斷,需要修改組件common-list.vue,如下:

<template>
	<view class="p-2">
		<!-- 頭像、昵稱和關注按鈕 -->
		<view class="flex align-center justify-between">
			<view class="flex align-center">
				<!-- 頭像 -->
				<image class="rounded-circle mr-2" :src="item.userpic" mode="" style="width: 65rpx; height: 65rpx;"
				 lazy-load></image>
				<!-- 昵稱和發布時間 -->
				<view>
					<view class="font" style="line-height: 1.5;">{{item.username}}</view>
					<text class="font-sm text-light-muted" style="line-height: 1.5;">{{item.newstime}}</text>
				</view>
			</view>
			<!-- 按鈕 -->
			<view class="flex align-center justify-center rounded bg-main text-white" style="width: 90rpx; height: 50rpx;">
				{{item.isFollow?'已關注':'關注'}}
			</view>
		</view>
		<!-- 標題 -->
		<view class="font my-1">
			{{item.title}}
		</view>
		<!-- 圖片 -->
		<image v-if="item.titlepic" class="rounded w-100" :src="item.titlepic" style="height: 350rpx;"></image>
		<!-- 圖示按鈕 -->
		<view class="flex align-center">
			<view class="flex align-center justify-center flex-1">
				<text class="iconfont icon-dianzan mr-2"></text>
				<text>{{item.support.support_count}}</text>
			</view>
			<view class="flex align-center justify-center flex-1">
				<text class="iconfont icon-cai mr-2"></text>
				<text>{{item.support.unsupport_count}}</text>
			</view>
			<view class="flex align-center justify-center flex-1">
				<text class="iconfont icon-pinglun mr-2"></text>
				<text>{{item.comment_count}}</text>
			</view>
			<view class="flex align-center justify-center flex-1">
				<text class="iconfont icon-fenxiang mr-2"></text>
				<text>{{item.share_count}}</text>
			</view>
		</view>
	</view>
</template>

<script>
	export default {
		props: {
			item: Object,
			index: Number
		},
	}
</script>

<style>
</style>

index.vue增加測驗資料,如下:

<template>
	<view>
		<block v-for="(item, index) in list" :key="index">
			<!-- 串列 -->
			<common-list :item="item" :index="index"></common-list>
			<!-- 全域分割線 -->
			<divider></divider>
		</block>

	</view>
</template>

<script>
	import commonList from '@/components/common/common-list.vue';
	export default {
		data() {
			return {
				list: [
					{
						username: "Corley",
						userpic: "/static/img/userpic/12.jpg",
						newstime: "2021-01-24 上午11:30",
						isFollow: false,
						title: "uni-app入門教程",
						titlepic: "/static/img/datapic/42.jpg",
						support: {
							type: "support",
							support_count: 1,
							unsupport_count: 2
						},
						comment_count: 2,
						share_count: 2
					},
					{
						username: "Brittany",
						userpic: "/static/img/userpic/16.jpg",
						newstime: "2021-01-24 下午14:00",
						isFollow: false,
						title: "商業資料分析從入門到入職",
						support: {
							type: "support",
							support_count: 2,
							unsupport_count: 0
						},
						comment_count: 5,
						share_count: 1
					},
					{
						username: "Ashley",
						userpic: "/static/img/userpic/20.jpg",
						newstime: "2021-01-24 下午14:44",
						isFollow: true,
						title: "uni-app實戰之社區交友APP",
						titlepic: "/static/img/datapic/30.jpg",
						support: {
							type: "support",
							support_count: 5,
							unsupport_count: 1
						},
						comment_count: 3,
						share_count: 0
					}
				]
			}
		},
		components: {
			commonList
		},
		onLoad() {

		},
		methods: {

		}
	}
</script>

<style>

</style>

顯示:
uniapp social app index develop optimize titlepic v-if

可以看到,沒有封面圖片,也能正常顯示,

此時再實作點擊關注按鈕、添加影片特效,common-list.vue如下:

<template>
	<view class="p-2">
		<!-- 頭像、昵稱和關注按鈕 -->
		<view class="flex align-center justify-between">
			<view class="flex align-center">
				<!-- 頭像 -->
				<image class="rounded-circle mr-2" :src="item.userpic" mode="" style="width: 65rpx; height: 65rpx;"
				 lazy-load></image>
				<!-- 昵稱和發布時間 -->
				<view>
					<view class="font" style="line-height: 1.5;">{{item.username}}</view>
					<text class="font-sm text-light-muted" style="line-height: 1.5;">{{item.newstime}}</text>
				</view>
			</view>
			<!-- 按鈕 -->
			<view class="flex align-center justify-center rounded bg-main text-white animate__animated animate__faster" hover-class="animate__jello" style="width: 90rpx; height: 50rpx;">
				{{item.isFollow?'已關注':'關注'}}
			</view>
		</view>
		<!-- 標題 -->
		<view class="font my-1">
			{{item.title}}
		</view>
		<!-- 圖片 -->
		<image v-if="item.titlepic" class="rounded w-100" :src="item.titlepic" style="height: 350rpx;"></image>
		<!-- 圖示按鈕 -->
		<view class="flex align-center">
			<view class="flex align-center justify-center flex-1">
				<text class="iconfont icon-dianzan mr-2"></text>
				<text>{{item.support.support_count}}</text>
			</view>
			<view class="flex align-center justify-center flex-1">
				<text class="iconfont icon-cai mr-2"></text>
				<text>{{item.support.unsupport_count}}</text>
			</view>
			<view class="flex align-center justify-center flex-1">
				<text class="iconfont icon-pinglun mr-2"></text>
				<text>{{item.comment_count}}</text>
			</view>
			<view class="flex align-center justify-center flex-1">
				<text class="iconfont icon-fenxiang mr-2"></text>
				<text>{{item.share_count}}</text>
			</view>
		</view>
	</view>
</template>

<script>
	export default {
		props: {
			item: Object,
			index: Number
		},
	}
</script>

<style>
</style>

顯示:
uniapp social app index develop optimize follow animation

可以看到,點擊關注按鈕時,已實作了影片效果,

現進一步實作4個圖示的特效,如下:

<template>
	<view class="p-2">
		<!-- 頭像、昵稱和關注按鈕 -->
		<view class="flex align-center justify-between">
			<view class="flex align-center">
				<!-- 頭像 -->
				<image class="rounded-circle mr-2" :src="item.userpic" mode="" style="width: 65rpx; height: 65rpx;"
				 lazy-load></image>
				<!-- 昵稱和發布時間 -->
				<view>
					<view class="font" style="line-height: 1.5;">{{item.username}}</view>
					<text class="font-sm text-light-muted" style="line-height: 1.5;">{{item.newstime}}</text>
				</view>
			</view>
			<!-- 按鈕 -->
			<view class="flex align-center justify-center rounded bg-main text-white animate__animated animate__faster" hover-class="animate__jello" style="width: 90rpx; height: 50rpx;">
				{{item.isFollow?'已關注':'關注'}}
			</view>
		</view>
		<!-- 標題 -->
		<view class="font my-1">
			{{item.title}}
		</view>
		<!-- 圖片 -->
		<image v-if="item.titlepic" class="rounded w-100" :src="item.titlepic" style="height: 350rpx;"></image>
		<!-- 圖示按鈕 -->
		<view class="flex align-center">
			<view class="flex align-center justify-center flex-1 animate__animated animate__faster" hover-class="animate__jello text-main">
				<text class="iconfont icon-dianzan mr-2"></text>
				<text>{{item.support.support_count}}</text>
			</view>
			<view class="flex align-center justify-center flex-1 animate__animated animate__faster" hover-class="animate__jello text-main">
				<text class="iconfont icon-cai mr-2"></text>
				<text>{{item.support.unsupport_count}}</text>
			</view>
			<view class="flex align-center justify-center flex-1 animate__animated animate__faster" hover-class="animate__jello text-main">
				<text class="iconfont icon-pinglun mr-2"></text>
				<text>{{item.comment_count}}</text>
			</view>
			<view class="flex align-center justify-center flex-1 animate__animated animate__faster" hover-class="animate__jello text-main">
				<text class="iconfont icon-fenxiang mr-2"></text>
				<text>{{item.share_count}}</text>
			</view>
		</view>
	</view>
</template>

<script>
	export default {
		props: {
			item: Object,
			index: Number
		},
	}
</script>

<style>
</style>

common.css如下:

/* 本專案全域樣式 */
/* 背景 */
.bg-main {
	background-color: #FF4A6A;
}

/* 文本顏色 */
.text-main {
	color: #FF4A6A;
}

顯示:
uniapp social app index develop optimize dianzan animation

顯然,也實作了影片效果,

3.關注功能完善

common-list組件需要定義介面,點擊頭像可以進入個人空間,點擊關注按鈕可以真正進行關注操作,點擊點贊和踩實作資料更新,點擊評論、轉發、標題和圖片等跳轉到詳情頁,一般可以通過系結事件實作,

common-list.vue組件系結事件實作介面如下:

<template>
	<view class="p-2">
		<!-- 頭像、昵稱和關注按鈕 -->
		<view class="flex align-center justify-between">
			<view class="flex align-center">
				<!-- 頭像 -->
				<image class="rounded-circle mr-2" :src="item.userpic" mode="" style="width: 65rpx; height: 65rpx;" @click="openSpace"
				 lazy-load></image>
				<!-- 昵稱和發布時間 -->
				<view>
					<view class="font" style="line-height: 1.5;">{{item.username}}</view>
					<text class="font-sm text-light-muted" style="line-height: 1.5;">{{item.newstime}}</text>
				</view>
			</view>
			<!-- 按鈕 -->
			<view class="flex align-center justify-center rounded bg-main text-white animate__animated animate__faster" hover-class="animate__jello" style="width: 90rpx; height: 50rpx;" @click="follow">
				{{item.isFollow?'已關注':'關注'}}
			</view>
		</view>
		<!-- 標題 -->
		<view class="font my-1" @click="openDetail">
			{{item.title}}
		</view>
		<!-- 圖片 -->
		<image v-if="item.titlepic" class="rounded w-100" :src="item.titlepic" style="height: 350rpx;" @click="openDetail"></image>
		<!-- 圖示按鈕 -->
		<view class="flex align-center">
			<view class="flex align-center justify-center flex-1 animate__animated animate__faster" hover-class="animate__jello text-main" @click="doSupport('support')">
				<text class="iconfont icon-dianzan mr-2"></text>
				<text>{{item.support.support_count}}</text>
			</view>
			<view class="flex align-center justify-center flex-1 animate__animated animate__faster" hover-class="animate__jello text-main" @click="doSupport('unsupport')">
				<text class="iconfont icon-cai mr-2"></text>
				<text>{{item.support.unsupport_count}}</text>
			</view>
			<view class="flex align-center justify-center flex-1 animate__animated animate__faster" hover-class="animate__jello text-main" @click="openDetail">
				<text class="iconfont icon-pinglun mr-2"></text>
				<text>{{item.comment_count}}</text>
			</view>
			<view class="flex align-center justify-center flex-1 animate__animated animate__faster" hover-class="animate__jello text-main" @click="openDetail">
				<text class="iconfont icon-fenxiang mr-2"></text>
				<text>{{item.share_count}}</text>
			</view>
		</view>
	</view>
</template>

<script>
	export default {
		props: {
			item: Object,
			index: Number
		},
		methods: {
			// 打開個人空間
			openSpace(){
				console.log('Space opened');
			},
			// 關注
			follow(){
				console.log('Followed');
			},
			// 進入詳情頁
			openDetail(){
				console.log('Detail opened');
			},
			// 頂踩操作
			doSupport(type){
				console.log(type)
			}
		}
	}
</script>

<style>
</style>

顯示:
uniapp social app index develop optimize follow interface

可以看到,已經模擬出了介面操作,
現進一步實作關注功能,如下:

<template>
	<view class="p-2">
		<!-- 頭像、昵稱和關注按鈕 -->
		<view class="flex align-center justify-between">
			<view class="flex align-center">
				<!-- 頭像 -->
				<image class="rounded-circle mr-2" :src="item.userpic" mode="" style="width: 65rpx; height: 65rpx;" @click="openSpace"
				 lazy-load></image>
				<!-- 昵稱和發布時間 -->
				<view>
					<view class="font" style="line-height: 1.5;">{{item.username}}</view>
					<text class="font-sm text-light-muted" style="line-height: 1.5;">{{item.newstime}}</text>
				</view>
			</view>
			<!-- 按鈕 -->
			<view v-if="!item.isFollow" class="flex align-center justify-center rounded bg-main text-white animate__animated animate__faster"
			 hover-class="animate__jello" style="width: 90rpx; height: 50rpx;" @click="follow">
				關注
			</view>
		</view>
		<!-- 標題 -->
		<view class="font my-1" @click="openDetail">
			{{item.title}}
		</view>
		<!-- 圖片 -->
		<image v-if="item.titlepic" class="rounded w-100" :src="item.titlepic" style="height: 350rpx;" @click="openDetail"></image>
		<!-- 圖示按鈕 -->
		<view class="flex align-center">
			<view class="flex align-center justify-center flex-1 animate__animated animate__faster" hover-class="animate__jello text-main"
			 @click="doSupport('support')">
				<text class="iconfont icon-dianzan mr-2"></text>
				<text>{{item.support.support_count}}</text>
			</view>
			<view class="flex align-center justify-center flex-1 animate__animated animate__faster" hover-class="animate__jello text-main"
			 @click="doSupport('unsupport')">
				<text class="iconfont icon-cai mr-2"></text>
				<text>{{item.support.unsupport_count}}</text>
			</view>
			<view class="flex align-center justify-center flex-1 animate__animated animate__faster" hover-class="animate__jello text-main"
			 @click="openDetail">
				<text class="iconfont icon-pinglun mr-2"></text>
				<text>{{item.comment_count}}</text>
			</view>
			<view class="flex align-center justify-center flex-1 animate__animated animate__faster" hover-class="animate__jello text-main"
			 @click="openDetail">
				<text class="iconfont icon-fenxiang mr-2"></text>
				<text>{{item.share_count}}</text>
			</view>
		</view>
	</view>
</template>

<script>
	export default {
		props: {
			item: Object,
			index: Number
		},
		methods: {
			// 打開個人空間
			openSpace() {
				console.log('Space opened');
			},
			// 關注
			follow() {
				console.log('Followed');
				// 通知父組件
				this.$emit('follow', this.index);
			},
			// 進入詳情頁
			openDetail() {
				console.log('Detail opened');
			},
			// 頂踩操作
			doSupport(type) {
				console.log(type)
			}
		}
	}
</script>

<style>
</style>

父組件index.vue如下:

<template>
	<view>
		<block v-for="(item, index) in list" :key="index">
			<!-- 串列 -->
			<common-list :item="item" :index="index" @follow="follow"></common-list>
			<!-- 全域分割線 -->
			<divider></divider>
		</block>
	</view>
</template>

<script>
	import commonList from '@/components/common/common-list.vue';
	export default {
		data() {
			return {
				list: [
					{
						username: "Corley",
						userpic: "/static/img/userpic/12.jpg",
						newstime: "2021-01-24 上午11:30",
						isFollow: false,
						title: "uni-app入門教程",
						titlepic: "/static/img/datapic/42.jpg",
						support: {
							type: "support",
							support_count: 1,
							unsupport_count: 2
						},
						comment_count: 2,
						share_count: 2
					},
					{
						username: "Brittany",
						userpic: "/static/img/userpic/16.jpg",
						newstime: "2021-01-24 下午14:00",
						isFollow: false,
						title: "商業資料分析從入門到入職",
						support: {
							type: "support",
							support_count: 2,
							unsupport_count: 0
						},
						comment_count: 5,
						share_count: 1
					},
					{
						username: "Ashley",
						userpic: "/static/img/userpic/20.jpg",
						newstime: "2021-01-24 下午14:44",
						isFollow: true,
						title: "uni-app實戰之社區交友APP",
						titlepic: "/static/img/datapic/30.jpg",
						support: {
							type: "support",
							support_count: 5,
							unsupport_count: 1
						},
						comment_count: 3,
						share_count: 0
					}
				]
			}
		},
		components: {
			commonList
		},
		onLoad() {

		},
		methods: {
			// 關注
			follow(e){
				console.log('Index followed');
				console.log(e);
				this.list[e].isFollow = true;
				uni.showToast({
					title: '關注'+this.list[e].username+'成功'
				})
			}
		}
	}
</script>

<style>

</style>

可以看到,實作了子組件common-list向父組件index的訊息傳遞,

顯示:
uniapp social app index develop optimize follow

顯然,實作了正常的關注功能,

4.頂踩功能

現完善頂踩功能介面,
頂踩有3種狀態:頂、踩或未操作,點擊頂按鈕后,對應數值加1,并且顏色變為激活狀態,

common-list.vue如下:

<template>
	<view class="p-2">
		<!-- 頭像、昵稱和關注按鈕 -->
		<view class="flex align-center justify-between">
			<view class="flex align-center">
				<!-- 頭像 -->
				<image class="rounded-circle mr-2" :src="item.userpic" mode="" style="width: 65rpx; height: 65rpx;" @click="openSpace"
				 lazy-load></image>
				<!-- 昵稱和發布時間 -->
				<view>
					<view class="font" style="line-height: 1.5;">{{item.username}}</view>
					<text class="font-sm text-light-muted" style="line-height: 1.5;">{{item.newstime}}</text>
				</view>
			</view>
			<!-- 按鈕 -->
			<view v-if="!item.isFollow" class="flex align-center justify-center rounded bg-main text-white animate__animated animate__faster"
			 hover-class="animate__jello" style="width: 90rpx; height: 50rpx;" @click="follow">
				關注
			</view>
		</view>
		<!-- 標題 -->
		<view class="font my-1" @click="openDetail">
			{{item.title}}
		</view>
		<!-- 圖片 -->
		<image v-if="item.titlepic" class="rounded w-100" :src="item.titlepic" style="height: 350rpx;" @click="openDetail"></image>
		<!-- 圖示按鈕 -->
		<view class="flex align-center">
			<!-- 頂 -->
			<view class="flex align-center justify-center flex-1 animate__animated animate__faster" hover-class="animate__jello text-main"
			 @click="doSupport('support')" :class="item.support.type === 'support' ? 'support-active' : ''">
				<text class="iconfont icon-dianzan mr-2"></text>
				<text>{{item.support.support_count > 0 ? item.support.support_count : '支持'}}</text>
			</view>
			<!-- 踩 -->
			<view class="flex align-center justify-center flex-1 animate__animated animate__faster" hover-class="animate__jello text-main"
			 @click="doSupport('unsupport')" :class="item.support.type === 'unsupport' ? 'support-active' : ''">
				<text class="iconfont icon-cai mr-2"></text>
				<text>{{item.support.unsupport_count > 0 ? item.support.unsupport_count : '反對'}}</text>
			</view>
			<view class="flex align-center justify-center flex-1 animate__animated animate__faster" hover-class="animate__jello text-main"
			 @click="openDetail">
				<text class="iconfont icon-pinglun mr-2"></text>
				<text>{{item.comment_count > 0 ? item.comment_count : '評論'}}</text>
			</view>
			<view class="flex align-center justify-center flex-1 animate__animated animate__faster" hover-class="animate__jello text-main"
			 @click="openDetail">
				<text class="iconfont icon-fenxiang mr-2"></text>
				<text>{{item.share_count > 0 ? item.share_count : '分享'}}</text>
			</view>
		</view>
	</view>
</template>

<script>
	export default {
		props: {
			item: Object,
			index: Number
		},
		methods: {
			// 打開個人空間
			openSpace() {
				console.log('Space opened');
			},
			// 關注
			follow() {
				console.log('Followed');
				// 通知父組件
				this.$emit('follow', this.index);
			},
			// 進入詳情頁
			openDetail() {
				console.log('Detail opened');
			},
			// 頂踩操作
			doSupport(type) {
				console.log(type);
				// 通知父組件
				this.$emit('doSupport', {
					type,
					index: this.index
				})
			}
		}
	}
</script>

<style>
	.support-active {
		color: #FF4A6A;
	}
</style>

index.vue如下:

<template>
	<view>
		<block v-for="(item, index) in list" :key="index">
			<!-- 串列 -->
			<common-list :item="item" :index="index" @follow="follow" @doSupport="doSupport"></common-list>
			<!-- 全域分割線 -->
			<divider></divider>
		</block>
	</view>
</template>

<script>
	import commonList from '@/components/common/common-list.vue';
	export default {
		data() {
			return {
				list: [{
						username: "Corley",
						userpic: "/static/img/userpic/12.jpg",
						newstime: "2021-01-24 上午11:30",
						isFollow: false,
						title: "uni-app入門教程",
						titlepic: "/static/img/datapic/42.jpg",
						support: {
							type: "support", // 頂
							support_count: 1,
							unsupport_count: 2
						},
						comment_count: 2,
						share_count: 2
					},
					{
						username: "Brittany",
						userpic: "/static/img/userpic/16.jpg",
						newstime: "2021-01-24 下午14:00",
						isFollow: false,
						title: "商業資料分析從入門到入職",
						support: {
							type: "unsupport", // 踩
							support_count: 2,
							unsupport_count: 3
						},
						comment_count: 5,
						share_count: 1
					},
					{
						username: "Jessica",
						userpic: "/static/img/userpic/7.jpg",
						newstime: "2021-01-24 下午14:44",
						isFollow: true,
						title: "Django+Vue開發生鮮電商平臺",
						titlepic: "/static/img/datapic/11.jpg",
						support: {
							type: "", // 未操作
							support_count: 2,
							unsupport_count: 7
						},
						comment_count: 0,
						share_count: 2
					},
					{
						username: "Ashley",
						userpic: "/static/img/userpic/20.jpg",
						newstime: "2021-01-24 下午18:20",
						isFollow: true,
						title: "uni-app實戰之社區交友APP",
						titlepic: "/static/img/datapic/30.jpg",
						support: {
							type: "support",
							support_count: 5,
							unsupport_count: 1
						},
						comment_count: 3,
						share_count: 0
					}
				]
			}
		},
		components: {
			commonList
		},
		onLoad() {

		},
		methods: {
			// 關注
			follow(e) {
				console.log('Index followed');
				console.log(e);
				this.list[e].isFollow = true;
				uni.showToast({
					title: '關注' + this.list[e].username + '成功'
				})
			},
			// 頂踩操作
			doSupport(e) {
				console.log(e);
				// 獲取當前串列項
				let item = this.list[e.index];
				let msg = e.type === 'support' ? '頂' : '踩';
				// 之前未頂踩過
				if (item.support.type === '') {
					item.support[e.type + '_count']++;
				}
				// 之前已頂過并且現在的操作為踩,則頂-1、踩+1
				else if (item.support.type === 'support' && e.type === 'unsupport') {
					item.support.support_count--;
					item.support.unsupport_count++;
				}
				// 之前已踩過并且現在的操作為頂,則踩-1、頂+1
				else if (item.support.type === 'unsupport' && e.type === 'support') {
					item.support.unsupport_count--;
					item.support.support_count++;
				}
				item.support.type = e.type;
				uni.showToast({
					title: msg + '成功'
				})
			}
		}
	}
</script>

<style>

</style>

在父組件和子組件中進行了一系列優化,包括圖示顏色變化,限制用戶要么為頂要么為踩、并且只能踩頂一次、不能多次踩頂,次數為0時顯示文本等,

顯示:
uniapp social app index develop optimize ding cai

顯然,已經實作了頂踩的基本功能,

三、滾動選項卡開發

1.選項卡動態顯示

滾動選項卡采用scroll-view組件實作,其scroll-into-view屬性可以加速開發,

先實作滾動選項卡,base.css設定scroll-view樣式如下:

/* 內外邊距 */
.p-2 {
	padding: 20rpx;
}

/* flex布局 */
.flex {
	display: flex;
}

.align-center {
	align-items: center;
}

.justify-between {
	justify-content: space-between;
}

.justify-center {
	justify-content: center;
}

.flex-1 {
	flex: 1;
}

/* 圓角 */
.rounded-circle {
	border-radius: 100%;
}

.rounded {
	border-radius: 8rpx;
}

/* margin */
.mr-2 {
	margin-right: 20rpx;
}

.my-1 {
	margin-top: 10rpx;
	margin-bottom: 0rpx;
}

/* padding */
.px-5 {
	padding-left: 50rpx;
	padding-right: 50rpx;
}

.py-3 {
	padding-top: 30rpx;
	padding-bottom: 30rpx;
}

/* 字體 */
.font-md {
	font-size: 35rpx;
}

.font {
	font-size: 30rpx;
}

.font-sm {
	font-size: 25rpx;
}

/* 文字顏色 */
.text-white {
	color: #FFFFFF;
}

.text-light-muted {
	color: #A9A5A0;
}

/* 寬度 */
/* #ifndef APP-PLUS-NVUE */
.w-100 {
	width: 100%;
}

/* #endif */

/* scroll-view */
/* #ifndef APP-PLUS-NVUE */
.scroll-row {
	width: 100%;
	white-space: nowrap;
}

.scroll-row-item {
	display: inline-block !important;
}

/* #endif */

index.vue中增加滾動選項卡如下:

<template>
	<view>
		<!-- 頂部選項卡 -->
		<scroll-view scroll-x="true" class="scroll-row">
			<view v-for="i in 20" :key="i" class="scroll-row-item px-5 py-3">{{i}}</view>
		</scroll-view>
		<block v-for="(item, index) in list" :key="index">
			<!-- 串列 -->
			<common-list :item="item" :index="index" @follow="follow" @doSupport="doSupport"></common-list>
			<!-- 全域分割線 -->
			<divider></divider>
		</block>
	</view>
</template>

<script>
	import commonList from '@/components/common/common-list.vue';
	export default {
		data() {
			return {
				list: [{
						username: "Corley",
						userpic: "/static/img/userpic/12.jpg",
						newstime: "2021-01-24 上午11:30",
						isFollow: false,
						title: "uni-app入門教程",
						titlepic: "/static/img/datapic/42.jpg",
						support: {
							type: "support", // 頂
							support_count: 1,
							unsupport_count: 2
						},
						comment_count: 2,
						share_count: 2
					},
					{
						username: "Brittany",
						userpic: "/static/img/userpic/16.jpg",
						newstime: "2021-01-24 下午14:00",
						isFollow: false,
						title: "商業資料分析從入門到入職",
						support: {
							type: "unsupport", // 踩
							support_count: 2,
							unsupport_count: 3
						},
						comment_count: 5,
						share_count: 1
					},
					{
						username: "Jessica",
						userpic: "/static/img/userpic/7.jpg",
						newstime: "2021-01-24 下午14:44",
						isFollow: true,
						title: "Django+Vue開發生鮮電商平臺",
						titlepic: "/static/img/datapic/11.jpg",
						support: {
							type: "", // 未操作
							support_count: 2,
							unsupport_count: 7
						},
						comment_count: 0,
						share_count: 2
					},
					{
						username: "Ashley",
						userpic: "/static/img/userpic/20.jpg",
						newstime: "2021-01-24 下午18:20",
						isFollow: true,
						title: "uni-app實戰之社區交友APP",
						titlepic: "/static/img/datapic/30.jpg",
						support: {
							type: "support",
							support_count: 5,
							unsupport_count: 1
						},
						comment_count: 3,
						share_count: 0
					}
				]
			}
		},
		components: {
			commonList
		},
		onLoad() {

		},
		methods: {
			// 關注
			follow(e) {
				console.log('Index followed');
				console.log(e);
				this.list[e].isFollow = true;
				uni.showToast({
					title: '關注' + this.list[e].username + '成功'
				})
			},
			// 頂踩操作
			doSupport(e) {
				console.log(e);
				// 獲取當前串列項
				let item = this.list[e.index];
				let msg = e.type === 'support' ? '頂' : '踩';
				// 之前未頂踩過
				if (item.support.type === '') {
					item.support[e.type + '_count']++;
				}
				// 之前已頂過并且現在的操作為踩,則頂-1、踩+1
				else if (item.support.type === 'support' && e.type === 'unsupport') {
					item.support.support_count--;
					item.support.unsupport_count++;
				}
				// 之前已踩過并且現在的操作為頂,則踩-1、頂+1
				else if (item.support.type === 'unsupport' && e.type === 'support') {
					item.support.unsupport_count--;
					item.support.support_count++;
				}
				item.support.type = e.type;
				uni.showToast({
					title: msg + '成功'
				})
			}
		}
	}
</script>

<style>

</style>

顯示:
uniapp social app index develop scrolltab scroll

可以看到,已經實作了滾動,

現實作選項卡內容顯示,如下:

<template>
	<view>
		<!-- 頂部選項卡 -->
		<scroll-view scroll-x="true" class="scroll-row ">
			<view v-for="(item, index) in tabBars" :key="index" class="scroll-row-item px-3 py-2 font-md" :id="'tab'+index" :class="tabIndex === index ? 'text-main font-lg font-weight-bold' : ''">{{item.name}}</view>
		</scroll-view>
		<block v-for="(item, index) in list" :key="index">
			<!-- 串列 -->
			<common-list :item="item" :index="index" @follow="follow" @doSupport="doSupport"></common-list>
			<!-- 全域分割線 -->
			<divider></divider>
		</block>
	</view>
</template>

<script>
	import commonList from '@/components/common/common-list.vue';
	export default {
		data() {
			return {
				list: [{
						username: "Corley",
						userpic: "/static/img/userpic/12.jpg",
						newstime: "2021-01-24 上午11:30",
						isFollow: false,
						title: "uni-app入門教程",
						titlepic: "/static/img/datapic/42.jpg",
						support: {
							type: "support", // 頂
							support_count: 1,
							unsupport_count: 2
						},
						comment_count: 2,
						share_count: 2
					},
					{
						username: "Brittany",
						userpic: "/static/img/userpic/16.jpg",
						newstime: "2021-01-24 下午14:00",
						isFollow: false,
						title: "商業資料分析從入門到入職",
						support: {
							type: "unsupport", // 踩
							support_count: 2,
							unsupport_count: 3
						},
						comment_count: 5,
						share_count: 1
					},
					{
						username: "Jessica",
						userpic: "/static/img/userpic/7.jpg",
						newstime: "2021-01-24 下午14:44",
						isFollow: true,
						title: "Django+Vue開發生鮮電商平臺",
						titlepic: "/static/img/datapic/11.jpg",
						support: {
							type: "", // 未操作
							support_count: 2,
							unsupport_count: 7
						},
						comment_count: 0,
						share_count: 2
					},
					{
						username: "Ashley",
						userpic: "/static/img/userpic/20.jpg",
						newstime: "2021-01-24 下午18:20",
						isFollow: true,
						title: "uni-app實戰之社區交友APP",
						titlepic: "/static/img/datapic/30.jpg",
						support: {
							type: "support",
							support_count: 5,
							unsupport_count: 1
						},
						comment_count: 3,
						share_count: 0
					}
				],
				// 頂部選項卡
				tabBars: [{
						name: '關注'
					},
					{
						name: '推薦'
					},
					{
						name: '體育'
					},
					{
						name: '熱點'
					},
					{
						name: '財經'
					},
					{
						name: '娛樂'
					},
					{
						name: '軍事'
					}
				],
				tabIndex: 0
			}
		},
		components: {
			commonList
		},
		onLoad() {

		},
		methods: {
			// 關注
			follow(e) {
				console.log('Index followed');
				console.log(e);
				this.list[e].isFollow = true;
				uni.showToast({
					title: '關注' + this.list[e].username + '成功'
				})
			},
			// 頂踩操作
			doSupport(e) {
				console.log(e);
				// 獲取當前串列項
				let item = this.list[e.index];
				let msg = e.type === 'support' ? '頂' : '踩';
				// 之前未頂踩過
				if (item.support.type === '') {
					item.support[e.type + '_count']++;
				}
				// 之前已頂過并且現在的操作為踩,則頂-1、踩+1
				else if (item.support.type === 'support' && e.type === 'unsupport') {
					item.support.support_count--;
					item.support.unsupport_count++;
				}
				// 之前已踩過并且現在的操作為頂,則踩-1、頂+1
				else if (item.support.type === 'unsupport' && e.type === 'support') {
					item.support.unsupport_count--;
					item.support.support_count++;
				}
				item.support.type = e.type;
				uni.showToast({
					title: msg + '成功'
				})
			}
		}
	}
</script>

<style>

</style>

base.css如下:

/* 內外邊距 */
.p-2 {
	padding: 20rpx;
}

/* flex布局 */
.flex {
	display: flex;
}

.align-center {
	align-items: center;
}

.justify-between {
	justify-content: space-between;
}

.justify-center {
	justify-content: center;
}

.flex-1 {
	flex: 1;
}

/* 圓角 */
.rounded-circle {
	border-radius: 100%;
}

.rounded {
	border-radius: 8rpx;
}

/* margin */
.mr-2 {
	margin-right: 20rpx;
}

.my-1 {
	margin-top: 10rpx;
	margin-bottom: 0rpx;
}

/* padding */
.px-5 {
	padding-left: 50rpx;
	padding-right: 50rpx;
}

.px-3 {
	padding-left: 30rpx;
	padding-right: 30rpx;
}

.py-3 {
	padding-top: 30rpx;
	padding-bottom: 30rpx;
}

.py-2 {
	padding-top: 20rpx;
	padding-bottom: 20rpx;
}

/* 字體 */
.font-lg {
	font-size: 40rpx;
}

.font-md {
	font-size: 35rpx;
}

.font {
	font-size: 30rpx;
}

.font-sm {
	font-size: 25rpx;
}

.font-weight-bold {
	font-weight: bold;
}

/* 文字顏色 */
.text-white {
	color: #FFFFFF;
}

.text-light-muted {
	color: #A9A5A0;
}

/* 寬度 */
/* #ifndef APP-PLUS-NVUE */
.w-100 {
	width: 100%;
}

/* #endif */

/* scroll-view */
/* #ifndef APP-PLUS-NVUE */
.scroll-row {
	width: 100%;
	white-space: nowrap;
}

.scroll-row-item {
	display: inline-block !important;
}

/* #endif */

顯示:
uniapp social app index develop scrolltab scroll list

再系結事件實作動態滾動和影片顯示的效果,如下:

<template>
	<view>
		<!-- 頂部選項卡 -->
		<scroll-view scroll-x="true" class="scroll-row" :scroll-into-view="scrollInto" :scroll-with-animation="true">
			<view v-for="(item, index) in tabBars" :key="index" class="scroll-row-item px-3 py-2 font-md" :id="'tab'+index"
			 :class="tabIndex === index ? 'text-main font-lg font-weight-bold' : ''" @click="changeTab(index)">{{item.name}}</view>
		</scroll-view>
		<block v-for="(item, index) in list" :key="index">
			<!-- 串列 -->
			<common-list :item="item" :index="index" @follow="follow" @doSupport="doSupport"></common-list>
			<!-- 全域分割線 -->
			<divider></divider>
		</block>
	</view>
</template>

<script>
	import commonList from '@/components/common/common-list.vue';
	export default {
		data() {
			return {
				list: [{
						username: "Corley",
						userpic: "/static/img/userpic/12.jpg",
						newstime: "2021-01-24 上午11:30",
						isFollow: false,
						title: "uni-app入門教程",
						titlepic: "/static/img/datapic/42.jpg",
						support: {
							type: "support", // 頂
							support_count: 1,
							unsupport_count: 2
						},
						comment_count: 2,
						share_count: 2
					},
					{
						username: "Brittany",
						userpic: "/static/img/userpic/16.jpg",
						newstime: "2021-01-24 下午14:00",
						isFollow: false,
						title: "商業資料分析從入門到入職",
						support: {
							type: "unsupport", // 踩
							support_count: 2,
							unsupport_count: 3
						},
						comment_count: 5,
						share_count: 1
					},
					{
						username: "Jessica",
						userpic: "/static/img/userpic/7.jpg",
						newstime: "2021-01-24 下午14:44",
						isFollow: true,
						title: "Django+Vue開發生鮮電商平臺",
						titlepic: "/static/img/datapic/11.jpg",
						support: {
							type: "", // 未操作
							support_count: 2,
							unsupport_count: 7
						},
						comment_count: 0,
						share_count: 2
					},
					{
						username: "Ashley",
						userpic: "/static/img/userpic/20.jpg",
						newstime: "2021-01-24 下午18:20",
						isFollow: true,
						title: "uni-app實戰之社區交友APP",
						titlepic: "/static/img/datapic/30.jpg",
						support: {
							type: "support",
							support_count: 5,
							unsupport_count: 1
						},
						comment_count: 3,
						share_count: 0
					}
				],
				// 頂部選項卡
				tabBars: [{
						name: '關注'
					},
					{
						name: '推薦'
					},
					{
						name: '體育'
					},
					{
						name: '熱點'
					},
					{
						name: '財經'
					},
					{
						name: '娛樂'
					},
					{
						name: '軍事'
					},
					{
						name: '歷史'
					},
					{
						name: '本地'
					}
					
				],
				tabIndex: 0,
				scrollInto: ''
			}
		},
		components: {
			commonList
		},
		onLoad() {

		},
		methods: {
			// 關注
			follow(e) {
				console.log('Index followed');
				console.log(e);
				this.list[e].isFollow = true;
				uni.showToast({
					title: '關注' + this.list[e].username + '成功'
				})
			},
			// 頂踩操作
			doSupport(e) {
				console.log(e);
				// 獲取當前串列項
				let item = this.list[e.index];
				let msg = e.type === 'support' ? '頂' : '踩';
				// 之前未頂踩過
				if (item.support.type === '') {
					item.support[e.type + '_count']++;
				}
				// 之前已頂過并且現在的操作為踩,則頂-1、踩+1
				else if (item.support.type === 'support' && e.type === 'unsupport') {
					item.support.support_count--;
					item.support.unsupport_count++;
				}
				// 之前已踩過并且現在的操作為頂,則踩-1、頂+1
				else if (item.support.type === 'unsupport' && e.type === 'support') {
					item.support.unsupport_count--;
					item.support.support_count++;
				}
				item.support.type = e.type;
				uni.showToast({
					title: msg + '成功'
				})
			},
			// 切換選項
			changeTab(index) {
				if (this.tabIndex === index){
					return;
				}
				this.tabIndex = index;
				// 滾動到指定元素
				this.scrollInto = 'tab' + index;
			}
		}
	}
</script>

<style>

</style>

顯示:
uniapp social app index develop scrolltab scroll dynamic

可以看到,已經實作了動態滑動,

2.串列滑動實作

現進一步實作點擊選項卡,下面顯示對應的串列,使用swiper(滑塊視圖容器)實作,可以做輪播圖和滑動串列,其常見屬性和含義如下:

屬性名型別默認值含義
indicator-dotsBooleanfalse是否顯示面板指示點
autoplayBooleanfalse是否自動切換
currentNumber0當前所在滑塊的 index
intervalNumber5000自動切換時間間隔
durationNumber500滑動影片時長

具體可參考https://uniapp.dcloud.io/component/swiper,

先實作滑塊,并與上面的選項卡聯動,如下:

<template>
	<view>
		<!-- 頂部選項卡 -->
		<scroll-view scroll-x="true" class="scroll-row" :scroll-into-view="scrollInto" :scroll-with-animation="true">
			<view v-for="(item, index) in tabBars" :key="index" class="scroll-row-item px-3 py-2 font-md" :id="'tab'+index"
			 :class="tabIndex === index ? 'text-main font-lg font-weight-bold' : ''" @click="changeTab(index)">{{item.name}}</view>
		</scroll-view>
		<!-- 滑塊 -->
		<swiper :duration="150" :current="tabIndex" @change="onChangeTab">
			<swiper-item v-for="(item, index) in tabBars" :key="index">
				<view class="swiper-item">{{item.name}}</view>
			</swiper-item>
		</swiper>
		<block v-for="(item, index) in list" :key="index">
			<!-- 串列 -->
			<common-list :item="item" :index="index" @follow="follow" @doSupport="doSupport"></common-list>
			<!-- 全域分割線 -->
			<divider></divider>
		</block>
	</view>
</template>

<script>
	import commonList from '@/components/common/common-list.vue';
	export default {
		data() {
			return {
				list: [{
						username: "Corley",
						userpic: "/static/img/userpic/12.jpg",
						newstime: "2021-01-24 上午11:30",
						isFollow: false,
						title: "uni-app入門教程",
						titlepic: "/static/img/datapic/42.jpg",
						support: {
							type: "support", // 頂
							support_count: 1,
							unsupport_count: 2
						},
						comment_count: 2,
						share_count: 2
					},
					{
						username: "Brittany",
						userpic: "/static/img/userpic/16.jpg",
						newstime: "2021-01-24 下午14:00",
						isFollow: false,
						title: "商業資料分析從入門到入職",
						support: {
							type: "unsupport", // 踩
							support_count: 2,
							unsupport_count: 3
						},
						comment_count: 5,
						share_count: 1
					},
					{
						username: "Jessica",
						userpic: "/static/img/userpic/7.jpg",
						newstime: "2021-01-24 下午14:44",
						isFollow: true,
						title: "Django+Vue開發生鮮電商平臺",
						titlepic: "/static/img/datapic/11.jpg",
						support: {
							type: "", // 未操作
							support_count: 2,
							unsupport_count: 7
						},
						comment_count: 0,
						share_count: 2
					},
					{
						username: "Ashley",
						userpic: "/static/img/userpic/20.jpg",
						newstime: "2021-01-24 下午18:20",
						isFollow: true,
						title: "uni-app實戰之社區交友APP",
						titlepic: "/static/img/datapic/30.jpg",
						support: {
							type: "support",
							support_count: 5,
							unsupport_count: 1
						},
						comment_count: 3,
						share_count: 0
					}
				],
				// 頂部選項卡
				tabBars: [{
						name: '關注'
					},
					{
						name: '推薦'
					},
					{
						name: '體育'
					},
					{
						name: '熱點'
					},
					{
						name: '財經'
					},
					{
						name: '娛樂'
					},
					{
						name: '軍事'
					},
					{
						name: '歷史'
					},
					{
						name: '本地'
					}
					
				],
				tabIndex: 0,
				scrollInto: ''
			}
		},
		components: {
			commonList
		},
		onLoad() {

		},
		methods: {
			// 關注
			follow(e) {
				console.log('Index followed');
				console.log(e);
				this.list[e].isFollow = true;
				uni.showToast({
					title: '關注' + this.list[e].username + '成功'
				})
			},
			// 頂踩操作
			doSupport(e) {
				console.log(e);
				// 獲取當前串列項
				let item = this.list[e.index];
				let msg = e.type === 'support' ? '頂' : '踩';
				// 之前未頂踩過
				if (item.support.type === '') {
					item.support[e.type + '_count']++;
				}
				// 之前已頂過并且現在的操作為踩,則頂-1、踩+1
				else if (item.support.type === 'support' && e.type === 'unsupport') {
					item.support.support_count--;
					item.support.unsupport_count++;
				}
				// 之前已踩過并且現在的操作為頂,則踩-1、頂+1
				else if (item.support.type === 'unsupport' && e.type === 'support') {
					item.support.unsupport_count--;
					item.support.support_count++;
				}
				item.support.type = e.type;
				uni.showToast({
					title: msg + '成功'
				})
			},
			// 切換選項
			changeTab(index) {
				if (this.tabIndex === index){
					return;
				}
				this.tabIndex = index;
				// 滾動到指定元素
				this.scrollInto = 'tab' + index;
			},
			// 監聽滑動
			onChangeTab(e) {
				console.log(e);
				this.changeTab(e.detail.current);
		}
	}
</script>

<style>

</style>

顯示:
uniapp social app index develop scrolltab swiper connect

可以看到,實作了滑塊,并且滑塊可以和選項卡實作聯動同步

現實作滑塊串列示意,如下:

<template>
	<view>
		<!-- 頂部選項卡 -->
		<scroll-view scroll-x="true" class="scroll-row" :scroll-into-view="scrollInto" :scroll-with-animation="true" style="height: 100rpx;">
			<view v-for="(item, index) in tabBars" :key="index" class="scroll-row-item px-3 py-2 font-md" :id="'tab'+index"
			 :class="tabIndex === index ? 'text-main font-lg font-weight-bold' : ''" @click="changeTab(index)">{{item.name}}</view>
		</scroll-view>
		<!-- 滑塊 -->
		<swiper :duration="150" :current="tabIndex" @change="onChangeTab" :style="'height: '+scrollH+'px;'">
			<swiper-item v-for="(item, index) in tabBars" :key="index">
				<scroll-view scroll-y="true" :style="'height: '+scrollH+'px;'">
					<view v-for="i in 100" :key="i">{{i}}</view>
				</scroll-view>
			</swiper-item>
		</swiper>
		<block v-for="(item, index) in list" :key="index">
			<!-- 串列 -->
			<common-list :item="item" :index="index" @follow="follow" @doSupport="doSupport"></common-list>
			<!-- 全域分割線 -->
			<divider></divider>
		</block>
	</view>
</template>

<script>
	import commonList from '@/components/common/common-list.vue';
	export default {
		data() {
			return {
				list: [{
						username: "Corley",
						userpic: "/static/img/userpic/12.jpg",
						newstime: "2021-01-24 上午11:30",
						isFollow: false,
						title: "uni-app入門教程",
						titlepic: "/static/img/datapic/42.jpg",
						support: {
							type: "support", // 頂
							support_count: 1,
							unsupport_count: 2
						},
						comment_count: 2,
						share_count: 2
					},
					{
						username: "Brittany",
						userpic: "/static/img/userpic/16.jpg",
						newstime: "2021-01-24 下午14:00",
						isFollow: false,
						title: "商業資料分析從入門到入職",
						support: {
							type: "unsupport", // 踩
							support_count: 2,
							unsupport_count: 3
						},
						comment_count: 5,
						share_count: 1
					},
					{
						username: "Jessica",
						userpic: "/static/img/userpic/7.jpg",
						newstime: "2021-01-24 下午14:44",
						isFollow: true,
						title: "Django+Vue開發生鮮電商平臺",
						titlepic: "/static/img/datapic/11.jpg",
						support: {
							type: "", // 未操作
							support_count: 2,
							unsupport_count: 7
						},
						comment_count: 0,
						share_count: 2
					},
					{
						username: "Ashley",
						userpic: "/static/img/userpic/20.jpg",
						newstime: "2021-01-24 下午18:20",
						isFollow: true,
						title: "uni-app實戰之社區交友APP",
						titlepic: "/static/img/datapic/30.jpg",
						support: {
							type: "support",
							support_count: 5,
							unsupport_count: 1
						},
						comment_count: 3,
						share_count: 0
					}
				],
				// 頂部選項卡
				tabBars: [{
						name: '關注'
					},
					{
						name: '推薦'
					},
					{
						name: '體育'
					},
					{
						name: '熱點'
					},
					{
						name: '財經'
					},
					{
						name: '娛樂'
					},
					{
						name: '軍事'
					},
					{
						name: '歷史'
					},
					{
						name: '本地'
					}

				],
				tabIndex: 0,
				scrollInto: '',
				// 串列高度
				scrollH: 600
			}
		},
		components: {
			commonList
		},
		onLoad() {
			uni.getSystemInfo({
				success:function(res){
					console.log(res);
					this.scrollH = res.windowHeight - uni.upx2px(100);
				}
			})
		},
		methods: {
			// 關注
			follow(e) {
				console.log('Index followed');
				console.log(e);
				this.list[e].isFollow = true;
				uni.showToast({
					title: '關注' + this.list[e].username + '成功'
				})
			},
			// 頂踩操作
			doSupport(e) {
				console.log(e);
				// 獲取當前串列項
				let item = this.list[e.index];
				let msg = e.type === 'support' ? '頂' : '踩';
				// 之前未頂踩過
				if (item.support.type === '') {
					item.support[e.type + '_count']++;
				}
				// 之前已頂過并且現在的操作為踩,則頂-1、踩+1
				else if (item.support.type === 'support' && e.type === 'unsupport') {
					item.support.support_count--;
					item.support.unsupport_count++;
				}
				// 之前已踩過并且現在的操作為頂,則踩-1、頂+1
				else if (item.support.type === 'unsupport' && e.type === 'support') {
					item.support.unsupport_count--;
					item.support.support_count++;
				}
				item.support.type = e.type;
				uni.showToast({
					title: msg + '成功'
				})
			},
			// 切換選項
			changeTab(index) {
				if (this.tabIndex === index) {
					return;
				}
				this.tabIndex = index;
				// 滾動到指定元素
				this.scrollInto = 'tab' + index;
			},
			// 監聽滑動
			onChangeTab(e) {
				console.log(e);
				this.changeTab(e.detail.current);
			}
		}
	}
</script>

<style>

</style>

為了給swiper設定高度,在生命周期onLoad()通過uni.getSystemInfo()獲取windowHeight,即可使用視窗高度,具體為螢屏高度除去NavigationBar和TabBar的高度,再減去選項卡的高度(呼叫uni.upx2px()轉化為以px為單位),

顯示:
uniapp social app index develop scrolltab swiper list

可以看到,實作了串列滑動,

3.串列顯示和同步

現完善串列項,將之前實作的block放入swiper中,并根據頂部選項卡顯示不同的串列,
index.vue如下:

<template>
	<view>
		<!-- 頂部選項卡 -->
		<scroll-view scroll-x="true" class="scroll-row" :scroll-into-view="scrollInto" :scroll-with-animation="true" style="height: 100rpx;">
			<view v-for="(item, index) in tabBars" :key="index" class="scroll-row-item px-3 py-2 font-md" :id="'tab'+index"
			 :class="tabIndex === index ? 'text-main font-lg font-weight-bold' : ''" @click="changeTab(index)">{{item.name}}</view>
		</scroll-view>
		<!-- 滑塊 -->
		<swiper :duration="150" :current="tabIndex" @change="onChangeTab" :style="'height: '+scrollH+'px;'">
			<swiper-item v-for="(item, index) in newsList" :key="index">
				<scroll-view scroll-y="true" :style="'height: '+scrollH+'px;'">
					<block v-for="(item2, index2) in item.list" :key="index2">
						<!-- 串列 -->
						<common-list :item="item2" :index="index2" @follow="follow" @doSupport="doSupport"></common-list>
						<!-- 全域分割線 -->
						<divider></divider>
					</block>
				</scroll-view>
			</swiper-item>
		</swiper>

	</view>
</template>

<script>
	import commonList from '@/components/common/common-list.vue';
	export default {
		data() {
			return {
				newsList: [],
				// 頂部選項卡
				tabBars: [{
						name: '關注'
					},
					{
						name: '推薦'
					},
					{
						name: '體育'
					},
					{
						name: '熱點'
					},
					{
						name: '財經'
					},
					{
						name: '娛樂'
					},
					{
						name: '軍事'
					},
					{
						name: '歷史'
					},
					{
						name: '本地'
					}

				],
				tabIndex: 0,
				scrollInto: '',
				// 串列高度
				scrollH: 600
			}
		},
		components: {
			commonList
		},
		onLoad() {
			uni.getSystemInfo({
					success: function(res) {
						console.log(res);
						this.scrollH = res.windowHeight - uni.upx2px(100);
					}
				}),
				// 根據選項生成串列
				this.getData();
		},
		methods: {
			// 關注
			follow(e) {
				console.log('Index followed');
				console.log(e);
				this.list[e].isFollow = true;
				uni.showToast({
					title: '關注' + this.list[e].username + '成功'
				})
			},
			// 頂踩操作
			doSupport(e) {
				console.log(e);
				// 獲取當前串列項
				let item = this.list[e.index];
				let msg = e.type === 'support' ? '頂' : '踩';
				// 之前未頂踩過
				if (item.support.type === '') {
					item.support[e.type + '_count']++;
				}
				// 之前已頂過并且現在的操作為踩,則頂-1、踩+1
				else if (item.support.type === 'support' && e.type === 'unsupport') {
					item.support.support_count--;
					item.support.unsupport_count++;
				}
				// 之前已踩過并且現在的操作為頂,則踩-1、頂+1
				else if (item.support.type === 'unsupport' && e.type === 'support') {
					item.support.unsupport_count--;
					item.support.support_count++;
				}
				item.support.type = e.type;
				uni.showToast({
					title: msg + '成功'
				})
			},
			// 切換選項
			changeTab(index) {
				if (this.tabIndex === index) {
					return;
				}
				this.tabIndex = index;
				// 滾動到指定元素
				this.scrollInto = 'tab' + index;
			},
			// 監聽滑動
			onChangeTab(e) {
				console.log(e);
				this.changeTab(e.detail.current);
			},
			// 獲取資料
			getData() {
				var arr = [];
				for (let i = 0; i < this.tabBars.length; i++) {
					let obj = {
						list: [{
								username: "Corley",
								userpic: "/static/img/userpic/12.jpg",
								newstime: "2021-01-24 上午11:30",
								isFollow: false,
								title: "uni-app入門教程",
								titlepic: "/static/img/datapic/42.jpg",
								support: {
									type: "support", // 頂
									support_count: 1,
									unsupport_count: 2
								},
								comment_count: 2,
								share_count: 2
							},
							{
								username: "Brittany",
								userpic: "/static/img/userpic/16.jpg",
								newstime: "2021-01-24 下午14:00",
								isFollow: false,
								title: "商業資料分析從入門到入職",
								support: {
									type: "unsupport", // 踩
									support_count: 2,
									unsupport_count: 3
								},
								comment_count: 5,
								share_count: 1
							},
							{
								username: "Jessica",
								userpic: "/static/img/userpic/7.jpg",
								newstime: "2021-01-24 下午14:44",
								isFollow: true,
								title: "Django+Vue開發生鮮電商平臺",
								titlepic: "/static/img/datapic/11.jpg",
								support: {
									type: "", // 未操作
									support_count: 2,
									unsupport_count: 7
								},
								comment_count: 0,
								share_count: 2
							},
							{
								username: "Ashley",
								userpic: "/static/img/userpic/20.jpg",
								newstime: "2021-01-24 下午18:20",
								isFollow: true,
								title: "uni-app實戰之社區交友APP",
								titlepic: "/static/img/datapic/30.jpg",
								support: {
									type: "support",
									support_count: 5,
									unsupport_count: 1
								},
								comment_count: 3,
								share_count: 0
							}
						]
					}
					arr.push(obj)
				}
				this.newsList = arr;
			}
		}
	}
</script>

<style>

</style>

顯示:
uniapp social app index develop scrolltab swiper list data

可以看到,已經實作了動態切換和顯示資料,

4.上拉加載開發

現實作上拉到底部加載資料,需要實作各個選項卡獨立上拉加載,

先實作基本的下拉加載,如下:

<template>
	<view>
		<!-- 頂部選項卡 -->
		<scroll-view scroll-x="true" class="scroll-row" :scroll-into-view="scrollInto" :scroll-with-animation="true" style="height: 100rpx;">
			<view v-for="(item, index) in tabBars" :key="index" class="scroll-row-item px-3 py-2 font-md" :id="'tab'+index"
			 :class="tabIndex === index ? 'text-main font-lg font-weight-bold' : ''" @click="changeTab(index)">{{item.name}}</view>
		</scroll-view>
		<!-- 滑塊 -->
		<swiper :duration="150" :current="tabIndex" @change="onChangeTab" :style="'height: '+scrollH+'px;'">
			<swiper-item v-for="(item, index) in newsList" :key="index">
				<scroll-view scroll-y="true" :style="'height: '+scrollH+'px;'" @scrolltolower="loadMore(index)">
					<!-- 串列 -->
					<block v-for="(item2, index2) in item.list" :key="index2">
						<!-- 串列組件 -->
						<common-list :item="item2" :index="index2" @follow="follow" @doSupport="doSupport"></common-list>
						<!-- 全域分割線 -->
						<divider></divider>
					</block>
					<!-- 上拉加載 -->
					<view class="flex align-center justify-center py-3">
						<text class="font text-light-muted">{{item.loadmore}}</text>
					</view>
				</scroll-view>
			</swiper-item>
		</swiper>

	</view>
</template>

<script>
	import commonList from '@/components/common/common-list.vue';
	export default {
		data() {
			return {
				newsList: [],
				// 頂部選項卡
				tabBars: [{
						name: '關注'
					},
					{
						name: '推薦'
					},
					{
						name: '體育'
					},
					{
						name: '熱點'
					},
					{
						name: '財經'
					},
					{
						name: '娛樂'
					},
					{
						name: '軍事'
					},
					{
						name: '歷史'
					},
					{
						name: '本地'
					}

				],
				tabIndex: 0,
				scrollInto: '',
				// 串列高度
				scrollH: 600
			}
		},
		components: {
			commonList
		},
		onLoad() {
			uni.getSystemInfo({
					success: function(res) {
						console.log(res);
						this.scrollH = res.windowHeight - uni.upx2px(100);
					}
				}),
				// 根據選項生成串列
				this.getData();
		},
		methods: {
			// 關注
			follow(e) {
				console.log('Index followed');
				console.log(e);
				this.list[e].isFollow = true;
				uni.showToast({
					title: '關注' + this.list[e].username + '成功'
				})
			},
			// 頂踩操作
			doSupport(e) {
				console.log(e);
				// 獲取當前串列項
				let item = this.list[e.index];
				let msg = e.type === 'support' ? '頂' : '踩';
				// 之前未頂踩過
				if (item.support.type === '') {
					item.support[e.type + '_count']++;
				}
				// 之前已頂過并且現在的操作為踩,則頂-1、踩+1
				else if (item.support.type === 'support' && e.type === 'unsupport') {
					item.support.support_count--;
					item.support.unsupport_count++;
				}
				// 之前已踩過并且現在的操作為頂,則踩-1、頂+1
				else if (item.support.type === 'unsupport' && e.type === 'support') {
					item.support.unsupport_count--;
					item.support.support_count++;
				}
				item.support.type = e.type;
				uni.showToast({
					title: msg + '成功'
				})
			},
			// 切換選項
			changeTab(index) {
				if (this.tabIndex === index) {
					return;
				}
				this.tabIndex = index;
				// 滾動到指定元素
				this.scrollInto = 'tab' + index;
			},
			// 監聽滑動
			onChangeTab(e) {
				console.log(e);
				this.changeTab(e.detail.current);
			},
			// 獲取資料
			getData() {
				var arr = [];
				for (let i = 0; i < this.tabBars.length; i++) {
					// 生成串列模板
					let obj = {
						// 3種狀態:1.上拉加載更多;2.加載中...;3.沒有更多了,
						loadmore: "上拉加載更多", 
						list: [{
								username: "Corley",
								userpic: "/static/img/userpic/12.jpg",
								newstime: "2021-01-24 上午11:30",
								isFollow: false,
								title: "uni-app入門教程",
								titlepic: "/static/img/datapic/42.jpg",
								support: {
									type: "support", // 頂
									support_count: 1,
									unsupport_count: 2
								},
								comment_count: 2,
								share_count: 2
							},
							{
								username: "Brittany",
								userpic: "/static/img/userpic/16.jpg",
								newstime: "2021-01-24 下午14:00",
								isFollow: false,
								title: "商業資料分析從入門到入職",
								support: {
									type: "unsupport", // 踩
									support_count: 2,
									unsupport_count: 3
								},
								comment_count: 5,
								share_count: 1
							},
							{
								username: "Jessica",
								userpic: "/static/img/userpic/7.jpg",
								newstime: "2021-01-24 下午14:44",
								isFollow: true,
								title: "Django+Vue開發生鮮電商平臺",
								titlepic: "/static/img/datapic/11.jpg",
								support: {
									type: "", // 未操作
									support_count: 2,
									unsupport_count: 7
								},
								comment_count: 0,
								share_count: 2
							},
							{
								username: "Ashley",
								userpic: "/static/img/userpic/20.jpg",
								newstime: "2021-01-24 下午18:20",
								isFollow: true,
								title: "uni-app實戰之社區交友APP",
								titlepic: "/static/img/datapic/30.jpg",
								support: {
									type: "support",
									support_count: 5,
									unsupport_count: 1
								},
								comment_count: 3,
								share_count: 0
							}
						]
					}
					arr.push(obj)
				}
				this.newsList = arr;
			},
			// 上拉加載更多
			loadMore(index) {
				this.newsList[index].loadmore = '加載中...';
			}
		}
	}
</script>

<style>

</style>

顯示:
uniapp social app index develop loadmore first

可以看到,在下拉到底之前,訊息為上拉加載更多,到底后觸發@scrolltolower事件,變為加載中...

再實作模擬加載更多資料,如下:

<template>
	<view>
		<!-- 頂部選項卡 -->
		<scroll-view scroll-x="true" class="scroll-row" :scroll-into-view="scrollInto" :scroll-with-animation="true" style="height: 100rpx;">
			<view v-for="(item, index) in tabBars" :key="index" class="scroll-row-item px-3 py-2 font-md" :id="'tab'+index"
			 :class="tabIndex === index ? 'text-main font-lg font-weight-bold' : ''" @click="changeTab(index)">{{item.name}}</view>
		</scroll-view>
		<!-- 滑塊 -->
		<swiper :duration="150" :current="tabIndex" @change="onChangeTab" :style="'height: '+scrollH+'px;'">
			<swiper-item v-for="(item, index) in newsList" :key="index">
				<scroll-view scroll-y="true" :style="'height: '+scrollH+'px;'" @scrolltolower="loadMore(index)">
					<!-- 串列 -->
					<block v-for="(item2, index2) in item.list" :key="index2">
						<!-- 串列組件 -->
						<common-list :item="item2" :index="index2" @follow="follow" @doSupport="doSupport"></common-list>
						<!-- 全域分割線 -->
						<divider></divider>
					</block>
					<!-- 上拉加載 -->
					<view class="flex align-center justify-center py-3">
						<text class="font text-light-muted">{{item.loadmore}}</text>
					</view>
				</scroll-view>
			</swiper-item>
		</swiper>

	</view>
</template>

<script>
	import commonList from '@/components/common/common-list.vue';
	export default {
		data() {
			return {
				newsList: [],
				// 頂部選項卡
				tabBars: [{
						name: '關注'
					},
					{
						name: '推薦'
					},
					{
						name: '體育'
					},
					{
						name: '熱點'
					},
					{
						name: '財經'
					},
					{
						name: '娛樂'
					},
					{
						name: '軍事'
					},
					{
						name: '歷史'
					},
					{
						name: '本地'
					}

				],
				tabIndex: 0,
				scrollInto: '',
				// 串列高度
				scrollH: 600
			}
		},
		components: {
			commonList
		},
		onLoad() {
			uni.getSystemInfo({
					success: function(res) {
						console.log(res);
						this.scrollH = res.windowHeight - uni.upx2px(100);
					}
				}),
				// 根據選項生成串列
				this.getData();
		},
		methods: {
			// 關注
			follow(e) {
				console.log('Index followed');
				console.log(e);
				this.list[e].isFollow = true;
				uni.showToast({
					title: '關注' + this.list[e].username + '成功'
				})
			},
			// 頂踩操作
			doSupport(e) {
				console.log(e);
				// 獲取當前串列項
				let item = this.list[e.index];
				let msg = e.type === 'support' ? '頂' : '踩';
				// 之前未頂踩過
				if (item.support.type === '') {
					item.support[e.type + '_count']++;
				}
				// 之前已頂過并且現在的操作為踩,則頂-1、踩+1
				else if (item.support.type === 'support' && e.type === 'unsupport') {
					item.support.support_count--;
					item.support.unsupport_count++;
				}
				// 之前已踩過并且現在的操作為頂,則踩-1、頂+1
				else if (item.support.type === 'unsupport' && e.type === 'support') {
					item.support.unsupport_count--;
					item.support.support_count++;
				}
				item.support.type = e.type;
				uni.showToast({
					title: msg + '成功'
				})
			},
			// 切換選項
			changeTab(index) {
				if (this.tabIndex === index) {
					return;
				}
				this.tabIndex = index;
				// 滾動到指定元素
				this.scrollInto = 'tab' + index;
			},
			// 監聽滑動
			onChangeTab(e) {
				console.log(e);
				this.changeTab(e.detail.current);
			},
			// 獲取資料
			getData() {
				var arr = [];
				for (let i = 0; i < this.tabBars.length; i++) {
					// 生成串列模板
					let obj = {
						// 3種狀態:1.上拉加載更多;2.加載中...;3.沒有更多了,
						loadmore: "上拉加載更多", 
						list: [{
								username: "Corley",
								userpic: "/static/img/userpic/12.jpg",
								newstime: "2021-01-24 上午11:30",
								isFollow: false,
								title: "uni-app入門教程",
								titlepic: "/static/img/datapic/42.jpg",
								support: {
									type: "support", // 頂
									support_count: 1,
									unsupport_count: 2
								},
								comment_count: 2,
								share_count: 2
							},
							{
								username: "Brittany",
								userpic: "/static/img/userpic/16.jpg",
								newstime: "2021-01-24 下午14:00",
								isFollow: false,
								title: "商業資料分析從入門到入職",
								support: {
									type: "unsupport", // 踩
									support_count: 2,
									unsupport_count: 3
								},
								comment_count: 5,
								share_count: 1
							},
							{
								username: "Jessica",
								userpic: "/static/img/userpic/7.jpg",
								newstime: "2021-01-24 下午14:44",
								isFollow: true,
								title: "Django+Vue開發生鮮電商平臺",
								titlepic: "/static/img/datapic/11.jpg",
								support: {
									type: "", // 未操作
									support_count: 2,
									unsupport_count: 7
								},
								comment_count: 0,
								share_count: 2
							},
							{
								username: "Ashley",
								userpic: "/static/img/userpic/20.jpg",
								newstime: "2021-01-24 下午18:20",
								isFollow: true,
								title: "uni-app實戰之社區交友APP",
								titlepic: "/static/img/datapic/30.jpg",
								support: {
									type: "support",
									support_count: 5,
									unsupport_count: 1
								},
								comment_count: 3,
								share_count: 0
							}
						]
					}
					arr.push(obj)
				}
				this.newsList = arr;
			},
			// 上拉加載更多
			loadMore(index) {
				// 獲取當前串列
				let item = this.newsList[index];
				// 修改當前串列加載狀態
				item.loadmore = '加載中...';
				// 模擬資料請求
				setTimeout(()=>{
					// 加載資料
					item.list = [...item.list, ...item.list];
					// 恢復加載狀態
					this.newsList[index].loadmore = '上拉加載更多';
				}, 2000)
			}
		}
	}
</script>

<style>

</style>

其中,[...item.list, ...item.list]是ES6的語法,為擴展運算子,即將item.list再復制一份;
之所以可以通過操作item變數來操作資料,是因為指向了相同的地址,即同一個參考,

顯示:
uniapp social app index develop loadmore data double

可以看到,模擬出了加載更多資料,

5.封裝上拉加載組件

前面實作的上拉加載更多并沒有進行判斷,可以一直向下滑動加載更多,顯然這是不合理的,因此需要進行判斷

index.vue如下:

<template>
	<view>
		<!-- 頂部選項卡 -->
		<scroll-view scroll-x="true" class="scroll-row" :scroll-into-view="scrollInto" :scroll-with-animation="true" style="height: 100rpx;">
			<view v-for="(item, index) in tabBars" :key="index" class="scroll-row-item px-3 py-2 font-md" :id="'tab'+index"
			 :class="tabIndex === index ? 'text-main font-lg font-weight-bold' : ''" @click="changeTab(index)">{{item.name}}</view>
		</scroll-view>
		<!-- 滑塊 -->
		<swiper :duration="150" :current="tabIndex" @change="onChangeTab" :style="'height: '+scrollH+'px;'">
			<swiper-item v-for="(item, index) in newsList" :key="index">
				<scroll-view scroll-y="true" :style="'height: '+scrollH+'px;'" @scrolltolower="loadMore(index)">
					<!-- 串列 -->
					<block v-for="(item2, index2) in item.list" :key="index2">
						<!-- 串列組件 -->
						<common-list :item="item2" :index="index2" @follow="follow" @doSupport="doSupport"></common-list>
						<!-- 全域分割線 -->
						<divider></divider>
					</block>
					<!-- 上拉加載 -->
					<view class="flex align-center justify-center py-3">
						<text class="font text-light-muted">{{item.loadmore}}</text>
					</view>
				</scroll-view>
			</swiper-item>
		</swiper>

	</view>
</template>

<script>
	import commonList from '@/components/common/common-list.vue';
	export default {
		data() {
			return {
				newsList: [],
				// 頂部選項卡
				tabBars: [{
						name: '關注'
					},
					{
						name: '推薦'
					},
					{
						name: '體育'
					},
					{
						name: '熱點'
					},
					{
						name: '財經'
					},
					{
						name: '娛樂'
					},
					{
						name: '軍事'
					},
					{
						name: '歷史'
					},
					{
						name: '本地'
					}

				],
				tabIndex: 0,
				scrollInto: '',
				// 串列高度
				scrollH: 600
			}
		},
		components: {
			commonList
		},
		onLoad() {
			uni.getSystemInfo({
					success: function(res) {
						console.log(res);
						this.scrollH = res.windowHeight - uni.upx2px(100);
					}
				}),
				// 根據選項生成串列
				this.getData();
		},
		methods: {
			// 關注
			follow(e) {
				console.log('Index followed');
				console.log(e);
				this.list[e].isFollow = true;
				uni.showToast({
					title: '關注' + this.list[e].username + '成功'
				})
			},
			// 頂踩操作
			doSupport(e) {
				console.log(e);
				// 獲取當前串列項
				let item = this.list[e.index];
				let msg = e.type === 'support' ? '頂' : '踩';
				// 之前未頂踩過
				if (item.support.type === '') {
					item.support[e.type + '_count']++;
				}
				// 之前已頂過并且現在的操作為踩,則頂-1、踩+1
				else if (item.support.type === 'support' && e.type === 'unsupport') {
					item.support.support_count--;
					item.support.unsupport_count++;
				}
				// 之前已踩過并且現在的操作為頂,則踩-1、頂+1
				else if (item.support.type === 'unsupport' && e.type === 'support') {
					item.support.unsupport_count--;
					item.support.support_count++;
				}
				item.support.type = e.type;
				uni.showToast({
					title: msg + '成功'
				})
			},
			// 切換選項
			changeTab(index) {
				if (this.tabIndex === index) {
					return;
				}
				this.tabIndex = index;
				// 滾動到指定元素
				this.scrollInto = 'tab' + index;
			},
			// 監聽滑動
			onChangeTab(e) {
				console.log(e);
				this.changeTab(e.detail.current);
			},
			// 獲取資料
			getData() {
				var arr = [];
				for (let i = 0; i < this.tabBars.length; i++) {
					// 生成串列模板
					let obj = {
						// 3種狀態:1.上拉加載更多;2.加載中...;3.沒有更多了,
						loadmore: "上拉加載更多", 
						list: [{
								username: "Corley",
								userpic: "/static/img/userpic/12.jpg",
								newstime: "2021-01-24 上午11:30",
								isFollow: false,
								title: "uni-app入門教程",
								titlepic: "/static/img/datapic/42.jpg",
								support: {
									type: "support", // 頂
									support_count: 1,
									unsupport_count: 2
								},
								comment_count: 2,
								share_count: 2
							},
							{
								username: "Brittany",
								userpic: "/static/img/userpic/16.jpg",
								newstime: "2021-01-24 下午14:00",
								isFollow: false,
								title: "商業資料分析從入門到入職",
								support: {
									type: "unsupport", // 踩
									support_count: 2,
									unsupport_count: 3
								},
								comment_count: 5,
								share_count: 1
							},
							{
								username: "Jessica",
								userpic: "/static/img/userpic/7.jpg",
								newstime: "2021-01-24 下午14:44",
								isFollow: true,
								title: "Django+Vue開發生鮮電商平臺",
								titlepic: "/static/img/datapic/11.jpg",
								support: {
									type: "", // 未操作
									support_count: 2,
									unsupport_count: 7
								},
								comment_count: 0,
								share_count: 2
							},
							{
								username: "Ashley",
								userpic: "/static/img/userpic/20.jpg",
								newstime: "2021-01-24 下午18:20",
								isFollow: true,
								title: "uni-app實戰之社區交友APP",
								titlepic: "/static/img/datapic/30.jpg",
								support: {
									type: "support",
									support_count: 5,
									unsupport_count: 1
								},
								comment_count: 3,
								share_count: 0
							}
						]
					}
					arr.push(obj)
				}
				this.newsList = arr;
			},
			// 上拉加載更多
			loadMore(index) {
				// 獲取當前串列
				let item = this.newsList[index];
				// 判斷是否處于可加載狀態
				if (item.loadmore !== '上拉加載更多') return;
				// 修改當前串列加載狀態
				item.loadmore = '加載中...';
				// 模擬資料請求
				setTimeout(()=>{
					// 加載資料
					item.list = [...item.list, ...item.list];
					// 恢復加載狀態
					this.newsList[index].loadmore = '上拉加載更多';
				}, 2000)
			}
		}
	}
</script>

<style>

</style>

效果與之前相同,如果loadmore不為上拉加載更多,則會停止加載更多資料,

現將下拉加載更多封裝為組件,components/common下新建load-more.vue如下:

<template>
	<view class="flex align-center justify-center py-3">
		<text class="font text-light-muted">{{loadmore}}</text>
	</view>
</template>

<script>
	export default {
		props: ['loadmore']
	}
</script>

<style>
</style>

index.vue中使用組件如下:

<template>
	<view>
		<!-- 頂部選項卡 -->
		<scroll-view scroll-x="true" class="scroll-row" :scroll-into-view="scrollInto" :scroll-with-animation="true" style="height: 100rpx;">
			<view v-for="(item, index) in tabBars" :key="index" class="scroll-row-item px-3 py-2 font-md" :id="'tab'+index"
			 :class="tabIndex === index ? 'text-main font-lg font-weight-bold' : ''" @click="changeTab(index)">{{item.name}}</view>
		</scroll-view>
		<!-- 滑塊 -->
		<swiper :duration="150" :current="tabIndex" @change="onChangeTab" :style="'height: '+scrollH+'px;'">
			<swiper-item v-for="(item, index) in newsList" :key="index">
				<scroll-view scroll-y="true" :style="'height: '+scrollH+'px;'" @scrolltolower="loadMore(index)">
					<!-- 串列 -->
					<block v-for="(item2, index2) in item.list" :key="index2">
						<!-- 串列組件 -->
						<common-list :item="item2" :index="index2" @follow="follow" @doSupport="doSupport"></common-list>
						<!-- 全域分割線 -->
						<divider></divider>
					</block>
					<!-- 上拉加載 -->
					<load-more :loadmore="item.loadmore"></load-more>
				</scroll-view>
			</swiper-item>
		</swiper>

	</view>
</template>

<script>
	import commonList from '@/components/common/common-list.vue';
	import loadMore from '@/components/common/load-more.vue';
	export default {
		data() {
			return {
				newsList: [],
				// 頂部選項卡
				tabBars: [{
						name: '關注'
					},
					{
						name: '推薦'
					},
					{
						name: '體育'
					},
					{
						name: '熱點'
					},
					{
						name: '財經'
					},
					{
						name: '娛樂'
					},
					{
						name: '軍事'
					},
					{
						name: '歷史'
					},
					{
						name: '本地'
					}

				],
				tabIndex: 0,
				scrollInto: '',
				// 串列高度
				scrollH: 600
			}
		},
		components: {
			commonList,
			loadMore
		},
		onLoad() {
			uni.getSystemInfo({
					success: function(res) {
						console.log(res);
						this.scrollH = res.windowHeight - uni.upx2px(100);
					}
				}),
				// 根據選項生成串列
				this.getData();
		},
		methods: {
			// 關注
			follow(e) {
				console.log('Index followed');
				console.log(e);
				this.list[e].isFollow = true;
				uni.showToast({
					title: '關注' + this.list[e].username + '成功'
				})
			},
			// 頂踩操作
			doSupport(e) {
				console.log(e);
				// 獲取當前串列項
				let item = this.list[e.index];
				let msg = e.type === 'support' ? '頂' : '踩';
				// 之前未頂踩過
				if (item.support.type === '') {
					item.support[e.type + '_count']++;
				}
				// 之前已頂過并且現在的操作為踩,則頂-1、踩+1
				else if (item.support.type === 'support' && e.type === 'unsupport') {
					item.support.support_count--;
					item.support.unsupport_count++;
				}
				// 之前已踩過并且現在的操作為頂,則踩-1、頂+1
				else if (item.support.type === 'unsupport' && e.type === 'support') {
					item.support.unsupport_count--;
					item.support.support_count++;
				}
				item.support.type = e.type;
				uni.showToast({
					title: msg + '成功'
				})
			},
			// 切換選項
			changeTab(index) {
				if (this.tabIndex === index) {
					return;
				}
				this.tabIndex = index;
				// 滾動到指定元素
				this.scrollInto = 'tab' + index;
			},
			// 監聽滑動
			onChangeTab(e) {
				console.log(e);
				this.changeTab(e.detail.current);
			},
			// 獲取資料
			getData() {
				var arr = [];
				for (let i = 0; i < this.tabBars.length; i++) {
					// 生成串列模板
					let obj = {
						// 3種狀態:1.上拉加載更多;2.加載中...;3.沒有更多了,
						loadmore: "上拉加載更多", 
						list: [{
								username: "Corley",
								userpic: "/static/img/userpic/12.jpg",
								newstime: "2021-01-24 上午11:30",
								isFollow: false,
								title: "uni-app入門教程",
								titlepic: "/static/img/datapic/42.jpg",
								support: {
									type: "support", // 頂
									support_count: 1,
									unsupport_count: 2
								},
								comment_count: 2,
								share_count: 2
							},
							{
								username: "Brittany",
								userpic: "/static/img/userpic/16.jpg",
								newstime: "2021-01-24 下午14:00",
								isFollow: false,
								title: "商業資料分析從入門到入職",
								support: {
									type: "unsupport", // 踩
									support_count: 2,
									unsupport_count: 3
								},
								comment_count: 5,
								share_count: 1
							},
							{
								username: "Jessica",
								userpic: "/static/img/userpic/7.jpg",
								newstime: "2021-01-24 下午14:44",
								isFollow: true,
								title: "Django+Vue開發生鮮電商平臺",
								titlepic: "/static/img/datapic/11.jpg",
								support: {
									type: "", // 未操作
									support_count: 2,
									unsupport_count: 7
								},
								comment_count: 0,
								share_count: 2
							},
							{
								username: "Ashley",
								userpic: "/static/img/userpic/20.jpg",
								newstime: "2021-01-24 下午18:20",
								isFollow: true,
								title: "uni-app實戰之社區交友APP",
								titlepic: "/static/img/datapic/30.jpg",
								support: {
									type: "support",
									support_count: 5,
									unsupport_count: 1
								},
								comment_count: 3,
								share_count: 0
							}
						]
					}
					arr.push(obj)
				}
				this.newsList = arr;
			},
			// 上拉加載更多
			loadMore(index) {
				// 獲取當前串列
				let item = this.newsList[index];
				// 判斷是否處于可加載狀態
				if (item.loadmore !== '上拉加載更多') return;
				// 修改當前串列加載狀態
				item.loadmore = '加載中...';
				// 模擬資料請求
				setTimeout(()=>{
					// 加載資料
					item.list = [...item.list, ...item.list];
					// 恢復加載狀態
					this.newsList[index].loadmore = '上拉加載更多';
				}, 2000)
			}
		}
	}
</script>

<style>

</style>

效果與之前相同,

6.封裝無資料默認組件

先實作沒有資料的情況,如下:

<template>
	<view>
		<!-- 頂部選項卡 -->
		<scroll-view scroll-x="true" class="scroll-row" :scroll-into-view="scrollInto" :scroll-with-animation="true" style="height: 100rpx;">
			<view v-for="(item, index) in tabBars" :key="index" class="scroll-row-item px-3 py-2 font-md" :id="'tab'+index"
			 :class="tabIndex === index ? 'text-main font-lg font-weight-bold' : ''" @click="changeTab(index)">{{item.name}}</view>
		</scroll-view>
		<!-- 滑塊 -->
		<swiper :duration="150" :current="tabIndex" @change="onChangeTab" :style="'height: '+scrollH+'px;'">
			<swiper-item v-for="(item, index) in newsList" :key="index">
				<scroll-view scroll-y="true" :style="'height: '+scrollH+'px;'" @scrolltolower="loadMore(index)">
					<!-- 有資料 -->
					<template v-if="item.list.length > 0">
						<!-- 串列 -->
						<block v-for="(item2, index2) in item.list" :key="index2">
							<!-- 串列組件 -->
							<common-list :item="item2" :index="index2" @follow="follow" @doSupport="doSupport"></common-list>
							<!-- 全域分割線 -->
							<divider></divider>
						</block>
						<!-- 上拉加載 -->
						<load-more :loadmore="item.loadmore"></load-more>
					</template>
					<!-- 無資料 -->
					<template v-else>
						<view class="flex flex-column align-center justify-center pt-7">
							<image src="@/static/common/nothing.jpg" style="width: 300rpx; height: 300rpx;"></image>
							<text class="font-md">這里什么都沒有哦~</text>
						</view>
					</template>
				</scroll-view>
			</swiper-item>
		</swiper>

	</view>
</template>

<script>
	const test_data = [{
			username: "Corley",
			userpic: "/static/img/userpic/12.jpg",
			newstime: "2021-01-24 上午11:30",
			isFollow: false,
			title: "uni-app入門教程",
			titlepic: "/static/img/datapic/42.jpg",
			support: {
				type: "support", // 頂
				support_count: 1,
				unsupport_count: 2
			},
			comment_count: 2,
			share_count: 2
		},
		{
			username: "Brittany",
			userpic: "/static/img/userpic/16.jpg",
			newstime: "2021-01-24 下午14:00",
			isFollow: false,
			title: "商業資料分析從入門到入職",
			support: {
				type: "unsupport", // 踩
				support_count: 2,
				unsupport_count: 3
			},
			comment_count: 5,
			share_count: 1
		},
		{
			username: "Jessica",
			userpic: "/static/img/userpic/7.jpg",
			newstime: "2021-01-24 下午14:44",
			isFollow: true,
			title: "Django+Vue開發生鮮電商平臺",
			titlepic: "/static/img/datapic/11.jpg",
			support: {
				type: "", // 未操作
				support_count: 2,
				unsupport_count: 7
			},
			comment_count: 0,
			share_count: 2
		},
		{
			username: "Ashley",
			userpic: "/static/img/userpic/20.jpg",
			newstime: "2021-01-24 下午18:20",
			isFollow: true,
			title: "uni-app實戰之社區交友APP",
			titlepic: "/static/img/datapic/30.jpg",
			support: {
				type: "support",
				support_count: 5,
				unsupport_count: 1
			},
			comment_count: 3,
			share_count: 0
		}
	];
	import commonList from '@/components/common/common-list.vue';
	import loadMore from '@/components/common/load-more.vue';
	export default {
		data() {
			return {
				newsList: [],
				// 頂部選項卡
				tabBars: [{
						name: '關注'
					},
					{
						name: '推薦'
					},
					{
						name: '體育'
					},
					{
						name: '熱點'
					},
					{
						name: '財經'
					},
					{
						name: '娛樂'
					},
					{
						name: '軍事'
					},
					{
						name: '歷史'
					},
					{
						name: '本地'
					}

				],
				tabIndex: 0,
				scrollInto: '',
				// 串列高度
				scrollH: 600
			}
		},
		components: {
			commonList,
			loadMore
		},
		onLoad() {
			uni.getSystemInfo({
					success: function(res) {
						console.log(res);
						this.scrollH = res.windowHeight - uni.upx2px(100);
					}
				}),
				// 根據選項生成串列
				this.getData();
		},
		methods: {
			// 關注
			follow(e) {
				console.log('Index followed');
				console.log(e);
				this.list[e].isFollow = true;
				uni.showToast({
					title: '關注' + this.list[e].username + '成功'
				})
			},
			// 頂踩操作
			doSupport(e) {
				console.log(e);
				// 獲取當前串列項
				let item = this.list[e.index];
				let msg = e.type === 'support' ? '頂' : '踩';
				// 之前未頂踩過
				if (item.support.type === '') {
					item.support[e.type + '_count']++;
				}
				// 之前已頂過并且現在的操作為踩,則頂-1、踩+1
				else if (item.support.type === 'support' && e.type === 'unsupport') {
					item.support.support_count--;
					item.support.unsupport_count++;
				}
				// 之前已踩過并且現在的操作為頂,則踩-1、頂+1
				else if (item.support.type === 'unsupport' && e.type === 'support') {
					item.support.unsupport_count--;
					item.support.support_count++;
				}
				item.support.type = e.type;
				uni.showToast({
					title: msg + '成功'
				})
			},
			// 切換選項
			changeTab(index) {
				if (this.tabIndex === index) {
					return;
				}
				this.tabIndex = index;
				// 滾動到指定元素
				this.scrollInto = 'tab' + index;
			},
			// 監聽滑動
			onChangeTab(e) {
				console.log(e);
				this.changeTab(e.detail.current);
			},
			// 獲取資料
			getData() {
				var arr = [];
				for (let i = 0; i < this.tabBars.length; i++) {
					// 生成串列模板
					let obj = {
						// 3種狀態:1.上拉加載更多;2.加載中...;3.沒有更多了,
						loadmore: "上拉加載更多",
						list: []
					}
					if (i % 3 !== 2) {
						obj.list = test_data;
					}
					arr.push(obj)
				}
				this.newsList = arr;
			},
			// 上拉加載更多
			loadMore(index) {
				// 獲取當前串列
				let item = this.newsList[index];
				// 判斷是否處于可加載狀態
				if (item.loadmore !== '上拉加載更多') return;
				// 修改當前串列加載狀態
				item.loadmore = '加載中...';
				// 模擬資料請求
				setTimeout(() => {
					// 加載資料
					item.list = [...item.list, ...item.list];
					// 恢復加載狀態
					this.newsList[index].loadmore = '上拉加載更多';
				}, 2000)
			}
		}
	}
</script>

<style>

</style>

base.css定義樣式如下:

/* 內外邊距 */
.p-2 {
	padding: 20rpx;
}

/* flex布局 */
.flex {
	display: flex;
}
.flex-column {
	flex-direction: column;
}

.align-center {
	align-items: center;
}

.justify-between {
	justify-content: space-between;
}

.justify-center {
	justify-content: center;
}

.flex-1 {
	flex: 1;
}

/* 圓角 */
.rounded-circle {
	border-radius: 100%;
}

.rounded {
	border-radius: 8rpx;
}

/* margin */
.mr-2 {
	margin-right: 20rpx;
}

.my-1 {
	margin-top: 10rpx;
	margin-bottom: 0rpx;
}

/* padding */
.px-5 {
	padding-left: 50rpx;
	padding-right: 50rpx;
}

.px-3 {
	padding-left: 30rpx;
	padding-right: 30rpx;
}

.py-3 {
	padding-top: 30rpx;
	padding-bottom: 30rpx;
}

.py-2 {
	padding-top: 20rpx;
	padding-bottom: 20rpx;
}

.pt-7 {
	padding-top: 70rpx;
}

/* 字體 */
.font-lg {
	font-size: 40rpx;
}

.font-md {
	font-size: 35rpx;
}

.font {
	font-size: 30rpx;
}

.font-sm {
	font-size: 25rpx;
}

.font-weight-bold {
	font-weight: bold;
}

/* 文字顏色 */
.text-white {
	color: #FFFFFF;
}

.text-light-muted {
	color: #A9A5A0;
}

/* 寬度 */
/* #ifndef APP-PLUS-NVUE */
.w-100 {
	width: 100%;
}

/* #endif */

/* scroll-view */
/* #ifndef APP-PLUS-NVUE */
.scroll-row {
	width: 100%;
	white-space: nowrap;
}

.scroll-row-item {
	display: inline-block !important;
}

/* #endif */

顯示:
uniapp social app index develop nodata view

可以看到,部分頁面沒有資料,顯示的是圖片和提示文字,

再實作封裝為組件,components/common下新建no-thing.vue如下:

<template>
	<view class="flex flex-column align-center justify-center pt-7">
		<image src="@/static/common/nothing.jpg" style="width: 300rpx; height: 300rpx;"></image>
		<text class="font-md">這里什么都沒有哦~</text>
	</view>
</template>

<script>
</script>

<style>
</style>

main.js中引入全域組件如下:

import Vue from 'vue'
import App from './App'

Vue.config.productionTip = false

// 引入全域組件
import divider from './components/common/divider.vue';
Vue.component('divider', divider)
import noThing from './components/common/no-thing.vue';
Vue.component('no-thing', noThing)

App.mpType = 'app'

const app = new Vue({
    ...App
})
app.$mount()

index.vue中使用全域組件如下:

<template>
	<view>
		<!-- 頂部選項卡 -->
		<scroll-view scroll-x="true" class="scroll-row" :scroll-into-view="scrollInto" :scroll-with-animation="true" style="height: 100rpx;">
			<view v-for="(item, index) in tabBars" :key="index" class="scroll-row-item px-3 py-2 font-md" :id="'tab'+index"
			 :class="tabIndex === index ? 'text-main font-lg font-weight-bold' : ''" @click="changeTab(index)">{{item.name}}</view>
		</scroll-view>
		<!-- 滑塊 -->
		<swiper :duration="150" :current="tabIndex" @change="onChangeTab" :style="'height: '+scrollH+'px;'">
			<swiper-item v-for="(item, index) in newsList" :key="index">
				<scroll-view scroll-y="true" :style="'height: '+scrollH+'px;'" @scrolltolower="loadMore(index)">
					<!-- 有資料 -->
					<template v-if="item.list.length > 0">
						<!-- 串列 -->
						<block v-for="(item2, index2) in item.list" :key="index2">
							<!-- 串列組件 -->
							<common-list :item="item2" :index="index2" @follow="follow" @doSupport="doSupport"></common-list>
							<!-- 全域分割線 -->
							<divider></divider>
						</block>
						<!-- 上拉加載 -->
						<load-more :loadmore="item.loadmore"></load-more>
					</template>
					<!-- 無資料 -->
					<template v-else>
						<no-thing></no-thing>
					</template>
				</scroll-view>
			</swiper-item>
		</swiper>

	</view>
</template>

<script>
	const test_data = [{
			username: "Corley",
			userpic: "/static/img/userpic/12.jpg",
			newstime: "2021-01-24 上午11:30",
			isFollow: false,
			title: "uni-app入門教程",
			titlepic: "/static/img/datapic/42.jpg",
			support: {
				type: "support", // 頂
				support_count: 1,
				unsupport_count: 2
			},
			comment_count: 2,
			share_count: 2
		},
		{
			username: "Brittany",
			userpic: "/static/img/userpic/16.jpg",
			newstime: "2021-01-24 下午14:00",
			isFollow: false,
			title: "商業資料分析從入門到入職",
			support: {
				type: "unsupport", // 踩
				support_count: 2,
				unsupport_count: 3
			},
			comment_count: 5,
			share_count: 1
		},
		{
			username: "Jessica",
			userpic: "/static/img/userpic/7.jpg",
			newstime: "2021-01-24 下午14:44",
			isFollow: true,
			title: "Django+Vue開發生鮮電商平臺",
			titlepic: "/static/img/datapic/11.jpg",
			support: {
				type: "", // 未操作
				support_count: 2,
				unsupport_count: 7
			},
			comment_count: 0,
			share_count: 2
		},
		{
			username: "Ashley",
			userpic: "/static/img/userpic/20.jpg",
			newstime: "2021-01-24 下午18:20",
			isFollow: true,
			title: "uni-app實戰之社區交友APP",
			titlepic: "/static/img/datapic/30.jpg",
			support: {
				type: "support",
				support_count: 5,
				unsupport_count: 1
			},
			comment_count: 3,
			share_count: 0
		}
	];
	import commonList from '@/components/common/common-list.vue';
	import loadMore from '@/components/common/load-more.vue';
	export default {
		data() {
			return {
				newsList: [],
				// 頂部選項卡
				tabBars: [{
						name: '關注'
					},
					{
						name: '推薦'
					},
					{
						name: '體育'
					},
					{
						name: '熱點'
					},
					{
						name: '財經'
					},
					{
						name: '娛樂'
					},
					{
						name: '軍事'
					},
					{
						name: '歷史'
					},
					{
						name: '本地'
					}

				],
				tabIndex: 0,
				scrollInto: '',
				// 串列高度
				scrollH: 600
			}
		},
		components: {
			commonList,
			loadMore
		},
		onLoad() {
			uni.getSystemInfo({
					success: function(res) {
						console.log(res);
						this.scrollH = res.windowHeight - uni.upx2px(100);
					}
				}),
				// 根據選項生成串列
				this.getData();
		},
		methods: {
			// 關注
			follow(e) {
				console.log('Index followed');
				console.log(e);
				this.list[e].isFollow = true;
				uni.showToast({
					title: '關注' + this.list[e].username + '成功'
				})
			},
			// 頂踩操作
			doSupport(e) {
				console.log(e);
				// 獲取當前串列項
				let item = this.list[e.index];
				let msg = e.type === 'support' ? '頂' : '踩';
				// 之前未頂踩過
				if (item.support.type === '') {
					item.support[e.type + '_count']++;
				}
				// 之前已頂過并且現在的操作為踩,則頂-1、踩+1
				else if (item.support.type === 'support' && e.type === 'unsupport') {
					item.support.support_count--;
					item.support.unsupport_count++;
				}
				// 之前已踩過并且現在的操作為頂,則踩-1、頂+1
				else if (item.support.type === 'unsupport' && e.type === 'support') {
					item.support.unsupport_count--;
					item.support.support_count++;
				}
				item.support.type = e.type;
				uni.showToast({
					title: msg + '成功'
				})
			},
			// 切換選項
			changeTab(index) {
				if (this.tabIndex === index) {
					return;
				}
				this.tabIndex = index;
				// 滾動到指定元素
				this.scrollInto = 'tab' + index;
			},
			// 監聽滑動
			onChangeTab(e) {
				console.log(e);
				this.changeTab(e.detail.current);
			},
			// 獲取資料
			getData() {
				var arr = [];
				for (let i = 0; i < this.tabBars.length; i++) {
					// 生成串列模板
					let obj = {
						// 3種狀態:1.上拉加載更多;2.加載中...;3.沒有更多了,
						loadmore: "上拉加載更多",
						list: []
					}
					if (i % 3 !== 2) {
						obj.list = test_data;
					}
					arr.push(obj)
				}
				this.newsList = arr;
			},
			// 上拉加載更多
			loadMore(index) {
				// 獲取當前串列
				let item = this.newsList[index];
				// 判斷是否處于可加載狀態
				if (item.loadmore !== '上拉加載更多') return;
				// 修改當前串列加載狀態
				item.loadmore = '加載中...';
				// 模擬資料請求
				setTimeout(() => {
					// 加載資料
					item.list = [...item.list, ...item.list];
					// 恢復加載狀態
					this.newsList[index].loadmore = '上拉加載更多';
				}, 2000)
			}
		}
	}
</script>

<style>

</style>

效果與之前相同,

總結

首頁的開發標志著進入正式的開發階段,代碼量逐漸增多、邏輯也逐漸復雜,圖文串列和滾動選項卡的開發業務邏輯較多,因此也進行了大量的優化,包括組件封裝和CSS樣式提取等,這都有利于專案的維護和擴展,

轉載請註明出處,本文鏈接:https://www.uj5u.com/qianduan/253112.html

標籤:其他

上一篇:JavaScript基礎:Iterator概念及用法

下一篇:chrome升了chrome88后,selenium修改window.navigator.webdriver

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • vue移動端上拉加載

    可能做得過于簡單或者比較low,請各位大佬留情,一起探討技術 ......

    uj5u.com 2020-09-10 04:38:07 more
  • 優美網站首頁,頂部多層導航

    一個個人用的瀏覽器首頁,可以把一下常用的網站放在這里,平常打開會比較方便。 第一步,HTML代碼 <script src=https://www.cnblogs.com/szharf/p/"js/jquery-3.4.1.min.js"></script> <div id="navigate"> <ul> <li class="labels labels_1"> ......

    uj5u.com 2020-09-10 04:38:47 more
  • 頁面為要加<!DOCTYPE html>

    最近因為寫一個js函式,需要用到$(window).height(); 由于手寫demo的時候,過于自信,其實對前端方面的認識也不夠體系,用文本檔案直接敲出來的html代碼,第一行沒有加上<!DOCTYPE html> 導致了$(window).height();的結果直接是整個document的高 ......

    uj5u.com 2020-09-10 04:38:52 more
  • WordPress網站程式手動升級要做好資料備份

    WordPress博客網站程式在進行升級前,必須要做好網站資料的備份,這個問題良家佐言是遇見過的;在剛開始接觸WordPress博客程式的時候,因為升級問題和博客網站的修改的一些嘗試,良家佐言是吃盡了苦頭。因為購買的是西部數碼的空間和域名,每當佐言把自己的WordPress博客網站搞到一塌糊涂的時候 ......

    uj5u.com 2020-09-10 04:39:30 more
  • WordPress程式不能升級為5.4.2版本的原因

    WordPress是一款個人博客系統,受到英文博客愛好者和中文博客愛好者的追捧,并逐步演化成一款內容管理系統軟體;它是使用PHP語言和MySQL資料庫開發的,用戶可以在支持PHP和MySQL資料庫的服務器上使用自己的博客。每一次WordPress程式的更新,就會牽動無數WordPress愛好者的心, ......

    uj5u.com 2020-09-10 04:39:49 more
  • 使用CSS3的偽元素進行首字母下沉和首行改變樣式

    網頁中常見的一種效果,首字改變樣式或者首行改變樣式,效果如下圖。 代碼: <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, ......

    uj5u.com 2020-09-10 04:40:09 more
  • 關于a標簽的講解

    什么是a標簽? <a> 標簽定義超鏈接,用于從一個頁面鏈接到另一個頁面。 <a> 元素最重要的屬性是 href 屬性,它指定鏈接的目標。 a標簽的語法格式:<a href=https://www.cnblogs.com/summerxbc/p/"指定要跳轉的目標界面的鏈接">需要展示給用戶看見的內容</a> a標簽 在所有瀏覽器中,鏈接的默認外觀如下: 未被訪問的鏈接帶 ......

    uj5u.com 2020-09-10 04:40:11 more
  • 前端輪播圖

    在需要輪播的頁面是引入swiper.min.js和swiper.min.css swiper.min.js地址: 鏈接:https://pan.baidu.com/s/15Uh516YHa4CV3X-RyjEIWw 提取碼:4aks swiper.min.css地址 鏈接:https://pan.b ......

    uj5u.com 2020-09-10 04:40:13 more
  • 如何設定html中的背景圖片(全屏顯示,且不拉伸)

    1 <style>2 body{background-image:url(https://uploadbeta.com/api/pictures/random/?key=BingEverydayWallpaperPicture); 3 background-size:cover;background ......

    uj5u.com 2020-09-10 04:40:16 more
  • Java學習——HTML詳解(上)

    HTML詳解 初識HTML Hyper Text Markup Language(超文本標記語言) 1 <!--DOCTYPE:告訴瀏覽器我們要使用什么規范--> 2 <!DOCTYPE html> 3 <html lang="en"> 4 <head> 5 <!--meta 描述性的標簽,描述一些 ......

    uj5u.com 2020-09-10 04:40:33 more
最新发布
  • 我的第一個NPM包:panghu-planebattle-esm(胖虎飛機大戰)使用說明

    好家伙,我的包終于開發完啦 歡迎使用胖虎的飛機大戰包!! 為你的主頁添加色彩 這是一個有趣的網頁小游戲包,使用canvas和js開發 使用ES6模塊化開發 效果圖如下: (覺得圖片太sb的可以自己改) 代碼已開源!! Git: https://gitee.com/tang-and-han-dynas ......

    uj5u.com 2023-04-20 07:59:23 more
  • 生產事故-走近科學之消失的JWT

    入職多年,面對生產環境,盡管都是小心翼翼,慎之又慎,還是難免捅出簍子。輕則滿頭大汗,面紅耳赤。重則系統停擺,損失資金。每一個生產事故的背后,都是寶貴的經驗和教訓,都是專案成員的血淚史。為了更好地防范和遏制今后的各類事故,特開此專題,長期更新和記錄大大小小的各類事故。有些是親身經歷,有些是經人耳傳口授 ......

    uj5u.com 2023-04-18 07:55:04 more
  • 記錄--Canvas實作打飛字游戲

    這里給大家分享我在網上總結出來的一些知識,希望對大家有所幫助 打開游戲界面,看到一個畫面簡潔、卻又富有挑戰性的游戲。螢屏上,有一個白色的矩形框,里面不斷下落著各種單詞,而我需要迅速地輸入這些單詞。如果我輸入的單詞與螢屏上的單詞匹配,那么我就可以獲得得分;如果我輸入的單詞錯誤或者時間過長,那么我就會輸 ......

    uj5u.com 2023-04-04 08:35:30 more
  • 了解 HTTP 看這一篇就夠

    在學習網路之前,了解它的歷史能夠幫助我們明白為何它會發展為如今這個樣子,引發探究網路的興趣。下面的這張圖片就展示了“互聯網”誕生至今的發展歷程。 ......

    uj5u.com 2023-03-16 11:00:15 more
  • 藍牙-低功耗中心設備

    //11.開啟藍牙配接器 openBluetoothAdapter //21.開始搜索藍牙設備 startBluetoothDevicesDiscovery //31.開啟監聽搜索藍牙設備 onBluetoothDeviceFound //30.停止監聽搜索藍牙設備 offBluetoothDevi ......

    uj5u.com 2023-03-15 09:06:45 more
  • canvas畫板(滑鼠和觸摸)

    <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>canves</title> <style> #canvas { cursor:url(../images/pen.png),crosshair; } #canvasdiv{ bo ......

    uj5u.com 2023-02-15 08:56:31 more
  • 手機端H5 實作自定義拍照界面

    手機端 H5 實作自定義拍照界面也可以使用 MediaDevices API 和 <video> 標簽來實作,和在桌面端做法基本一致。 首先,使用 MediaDevices.getUserMedia() 方法獲取攝像頭媒體流,并將其傳遞給 <video> 標簽進行渲染。 接著,使用 HTML 的 < ......

    uj5u.com 2023-01-12 07:58:22 more
  • 記錄--短視頻滑動播放在 H5 下的實作

    這里給大家分享我在網上總結出來的一些知識,希望對大家有所幫助 短視頻已經無數不在了,但是主體還是使用 app 來承載的。本文講述 H5 如何實作 app 的視頻滑動體驗。 無聲勝有聲,一圖頂百辯,且看下圖: 網址鏈接(需在微信或者手Q中瀏覽) 從上圖可以看到,我們主要實作的功能也是本文要講解的有: ......

    uj5u.com 2023-01-04 07:29:05 more
  • 一文讀懂 HTTP/1 HTTP/2 HTTP/3

    從 1989 年萬維網(www)誕生,HTTP(HyperText Transfer Protocol)經歷了眾多版本迭代,WebSocket 也在期間萌芽。1991 年 HTTP0.9 被發明。1996 年出現了 HTTP1.0。2015 年 HTTP2 正式發布。2020 年 HTTP3 或能正... ......

    uj5u.com 2022-12-24 06:56:02 more
  • 【HTML基礎篇002】HTML之form表單超詳解

    ??一、form表單是什么

    ??二、form表單的屬性

    ??三、input中的各種Type屬性值

    ??四、標簽 ......

    uj5u.com 2022-12-18 07:17:06 more