发布日期:2024年7月10日
一、项目架构设计
本教程将开发一个完整的短视频社交应用,包含以下核心模块:
- 视频模块:瀑布流展示与拍摄发布
- 社交模块:即时通讯与好友系统
- 推荐系统:个性化内容分发
- 商业化模块:直播带货与打赏
- 多端适配:小程序+App+H5
技术栈:UniApp + Vue3 + Pinia + uView + WebSocket
二、项目初始化与配置
1. 环境准备
# 安装HBuilderX
# 下载地址:https://www.dcloud.io/hbuilderx.html
# 创建UniApp项目
文件 → 新建 → 项目 → UniApp → 选择Vue3版本
# 安装必要依赖
npm install @dcloudio/uni-ui pinia uview-ui
2. 目录结构规划
src/
├── api/ # 接口服务
├── components/ # 公共组件
│ ├── video/ # 视频组件
│ └── chat/ # 聊天组件
├── composables/ # 组合式函数
├── pages/ # 页面组件
│ ├── home/ # 首页
│ └── profile/ # 个人中心
├── static/ # 静态资源
│ ├── icons/ # 图标
│ └── styles/ # 全局样式
├── store/ # Pinia状态
├── uni_modules/ # 插件模块
├── App.vue
└── main.js
三、短视频模块实现
1. 视频瀑布流组件
<template>
<scroll-view
scroll-y
class="video-feed"
@scrolltolower="loadMore"
>
<video-item
v-for="item in videoList"
:key="item.id"
:video="item"
@play="handlePlay"
/>
</scroll-view>
</template>
<script setup>
import { ref } from 'vue'
import { onReachBottom } from '@dcloudio/uni-app'
const videoList = ref([])
const currentPage = ref(1)
const fetchVideos = async () => {
const res = await uni.request({
url: '/api/videos',
data: { page: currentPage.value }
})
videoList.value = [...videoList.value, ...res.data]
}
const handlePlay = (id) => {
// 暂停其他视频
videoList.value.forEach(v => {
if (v.id !== id) {
uni.createVideoContext(`video-${v.id}`).pause()
}
})
}
onReachBottom(() => {
currentPage.value++
fetchVideos()
})
fetchVideos()
</script>
2. 视频拍摄与压缩
// pages/publish/publish.vue
const chooseVideo = () => {
uni.chooseMedia({
count: 1,
mediaType: ['video'],
sourceType: ['camera'],
maxDuration: 60,
camera: 'back',
success: (res) => {
compressVideo(res.tempFiles[0])
}
})
}
const compressVideo = (file) => {
uni.compressVideo({
src: file.tempFilePath,
quality: 'medium',
success: (res) => {
uploadVideo(res.tempFilePath)
}
})
}
const uploadVideo = (path) => {
uni.uploadFile({
url: '/api/upload',
filePath: path,
name: 'video',
success: (res) => {
const data = JSON.parse(res.data)
publishVideo(data.url)
}
})
}
四、即时通讯模块
1. WebSocket连接管理
// composables/useWebSocket.js
import { ref } from 'vue'
export function useWebSocket() {
const socket = ref(null)
const messages = ref([])
const connect = () => {
socket.value = uni.connectSocket({
url: 'wss://your-websocket-url',
success: () => {
console.log('WebSocket连接成功')
}
})
socket.value.onMessage((res) => {
const message = JSON.parse(res.data)
messages.value.push(message)
})
}
const send = (message) => {
if (socket.value?.readyState === 1) {
socket.value.send({
data: JSON.stringify(message)
})
}
}
return { socket, messages, connect, send }
}
2. 聊天界面实现
<template>
<view class="chat-container">
<scroll-view
scroll-y
class="message-list"
:scroll-top="scrollTop"
>
<message-bubble
v-for="(msg, index) in messages"
:key="index"
:message="msg"
/>
</scroll-view>
<view class="input-area">
<input
v-model="inputMsg"
placeholder="输入消息..."
/>
<button @click="sendMessage">发送</button>
</view>
</view>
</template>
<script setup>
import { ref, watch } from 'vue'
import { useWebSocket } from '@/composables/useWebSocket'
const { messages, send } = useWebSocket()
const inputMsg = ref('')
const scrollTop = ref(0)
const sendMessage = () => {
if (inputMsg.value.trim()) {
send({
type: 'text',
content: inputMsg.value,
timestamp: Date.now()
})
inputMsg.value = ''
}
}
watch(messages, () => {
// 自动滚动到底部
setTimeout(() => {
scrollTop.value = 99999
}, 100)
})
</script>
五、性能优化策略
1. 虚拟列表优化
// components/virtual-list.vue
<template>
<scroll-view
scroll-y
:style="{ height: `${height}px` }"
@scroll="handleScroll"
>
<view :style="{ height: `${totalHeight}px` }">
<view
v-for="item in visibleItems"
:key="item.id"
:style="{
position: 'absolute',
top: `${item.offset}px`,
width: '100%'
}"
>
<slot :item="item.data" />
</view>
</view>
</scroll-view>
</template>
<script setup>
import { computed, ref } from 'vue'
const props = defineProps({
items: Array,
itemHeight: Number,
height: Number,
buffer: { type: Number, default: 5 }
})
const scrollTop = ref(0)
const visibleItems = computed(() => {
const startIdx = Math.max(0, Math.floor(scrollTop.value / props.itemHeight) - props.buffer)
const endIdx = Math.min(
props.items.length,
startIdx + Math.ceil(props.height / props.itemHeight) + 2 * props.buffer
)
return props.items.slice(startIdx, endIdx).map((item, i) => ({
...item,
offset: (startIdx + i) * props.itemHeight
}))
})
const totalHeight = computed(() => props.items.length * props.itemHeight)
const handleScroll = (e) => {
scrollTop.value = e.detail.scrollTop
}
</script>
2. 图片懒加载
<template>
<image
:src="placeholder"
:data-src="realSrc"
:class="{ loaded: isLoaded }"
@load="handleLoad"
@error="handleError"
/>
</template>
<script setup>
import { ref, onMounted } from 'vue'
const props = defineProps({
src: String,
placeholder: { type: String, default: '/static/placeholder.png' }
})
const realSrc = ref(props.placeholder)
const isLoaded = ref(false)
const loadImage = () => {
const observer = uni.createIntersectionObserver(this)
observer.relativeToViewport()
observer.observe('.image', (res) => {
if (res.intersectionRatio > 0) {
realSrc.value = props.src
observer.disconnect()
}
})
}
onMounted(() => {
loadImage()
})
</script>
六、多端适配方案
1. 条件编译
<template>
<view>
<!-- #ifdef MP-WEIXIN -->
<ad unit-id="your-weixin-ad-unit-id"></ad>
<!-- #endif -->
<!-- #ifdef APP-PLUS -->
<ad :adpid="your-app-adpid"></ad>
<!-- #endif -->
</view>
</template>
<script>
// #ifdef H5
const SDK = require('h5-sdk')
// #endif
// #ifdef MP-WEIXIN
const SDK = require('weixin-sdk')
// #endif
</script>
2. 原生组件封装
// components/native-webview.vue
<template>
<!-- #ifdef APP-PLUS -->
<web-view :src="url"></web-view>
<!-- #endif -->
<!-- #ifdef H5 -->
<iframe :src="url" frameborder="0"></iframe>
<!-- #endif -->
<!-- #ifdef MP-WEIXIN -->
<web-view :src="url"></web-view>
<!-- #endif -->
</template>
七、打包发布流程
1. 小程序发布
# 微信小程序打包
npm run build:mp-weixin
# 使用微信开发者工具上传
# 项目 → 导入项目 → 选择dist/build/mp-weixin目录
# 提交审核
# 开发工具 → 上传 → 填写版本信息 → 提交审核
2. App打包发布
# 生成Android APK
发行 → 原生App-云打包 → 选择Android → 使用DCloud证书
# iOS打包
发行 → 原生App-云打包 → 选择iOS → 上传证书文件
# 上传到应用商店
# Android: 上传到各大应用市场
# iOS: 通过App Store Connect提交
八、总结与扩展
通过本教程,您已经掌握了:
- UniApp项目架构设计
- 短视频功能开发
- 即时通讯实现
- 跨平台性能优化
- 多端发布流程
扩展学习方向:
- UniApp插件开发
- 原生能力扩展
- 小程序云开发
- Flutter混合开发