视频上传组件

This commit is contained in:
xiaoshan
2023-05-11 17:49:02 +08:00
parent e065beebd3
commit 36ed22583f
4 changed files with 385 additions and 21 deletions

View File

@@ -78,8 +78,9 @@
defaultStyle(){
let style = {}
style.width = this.imageWidth + 'rpx'
if(this.imageHeight) style.height = this.imageHeight + 'rpx'
else style.height = this.imageWidth + 'rpx'
if(this.imageHeight) {
style.height = this.imageHeight + 'rpx'
} else style.height = this.imageWidth + 'rpx'
return style
}
},

View File

@@ -1,11 +1,28 @@
<template>
<view>
<swiper class="swiper">
<swiper-item v-for="(item, index) in list" :key="index">
<image v-if="item[keyName]" :src="item[keyName]" mode=""></image>
<image v-else :src="item" mode=""></image>
<view class="swiper-content">
<swiper class="swiper"
:autoplay="autoplay"
:current="current"
:interval="interval"
:duration="duration"
:circular="circular"
:vertical="vertical"
:previous-margin="previousMargin"
:next-margin="nextMargin"
@change="changeIndex">
<swiper-item
class="swiper-item" v-for="(item, index) in list" :key="index">
<view class="image" @click="jump(item)">
<image :style="[imageStyle]" :src="item.image" />
</view>
</swiper-item>
</swiper>
<view v-if="indicator=='num'" class="pagenum-box" :style="[numStyleP]">
{{current + 1}}/{{list.length}}
</view>
<view class="dot-box" :style="[dotBoxStyle]">
<view class="dot-item" @click="checkItem(index)" :style="[current==index ? dotActiveStyle : dotStyle]" v-for="(item,index) in list" :key="index" />
</view>
</view>
</template>
@@ -14,48 +31,235 @@
* List 轮播图列表
* @description 该组件为轮播图组件
* @tutorial
* @property {Boolean} indicatorDots 控制是否显示面板指示点 (默认 false
* @property {String | Number} duration 滑块切换过程所需时间ms)(默认 300
* @property {String | Number} imageWidth 图片宽度rpx默认 100%
* @property {String | Number} imageHeight 图片高度rpx)(默认 100%
* @property {String | Number} radius 图片圆角rpx默认 0
* @property {Boolean} autoplay 控制是否自动播放 (默认 true
* @property {String | Number} duration 滑动动画时长(默认 500
* @property {String | Number} interval 自动切换时间间隔(默认 2000
* @property {Boolean} circular 控制是否循环播放 (默认 true
* @property {Boolean} vertical 控制滚动方向 (默认 横向false
* @property {String} previousMargin 前边距,可用于露出前一项的一小部分,接受 px 和 rpx 值
* @property {String} nextMargin 后边距,可用于露出后一项的一小部分,接受 px 和 rpx 值
* @property {String} numPosition 数字面板定位 (默认 bottomLeft
* @property {String} numStyle 数字面板样式style (默认 bottomLeft 可选上下top/bottom;左右Left/Center/Right
* @property {Boolean} indicator 控制是否显示面板指示样式 (默认 无 可选:无 null 数字页码num 指示点: dot
* @property {String} indicatorColor 指示点背景颜色 (默认 rgba(255,255,255,0.6))
* @property {String} indicatorActiveColor 当前滑块对应指示点背景颜色 (默认 #ffffff)
* @property {String | Number} indicatorActiveWidth 当前滑块对应指示点宽度 (默认 12rpx
* @property {String | Number} dotBottom 指示点距离轮播图底部上移距离 (默认 32rpx
* @property {String} keyName list数组中指定对象的目标属性名默认 'url'
*/
import request from '@/utils/request'
export default {
name:"lxk-swiper",
props: {
list: {
type: Array,
default(){
return []
}
imageWidth: {
type: [Number, String],
default: 0
},
indicatorDots: {
imageHeight: {
type: [Number, String],
default: 0
},
radius: {
type: [Number, String],
default: 0
},
autoplay: {
type: Boolean,
default: false
default: true
},
interval: {
type: [Number, String],
default: 2000
},
duration: {
type: [String, Number],
default: '300'
default: '500'
},
circular: {
type: Boolean,
default: true
},
vertical: {
type: Boolean,
default: false
},
previousMargin: {
type: String,
default: '0px'
},
nextMargin: {
type: String,
default: '0px'
},
numStyle: {
type: Object,
default(){
return {}
}
},
numPosition: {
type: String,
default: 'bottomLeft'
},
indicator: {
type: String,
default: 'null'
},
indicatorColor: {
type: String,
default: 'rgba(255,255,255,0.6)'
},
indicatorActiveColor: {
type: String,
default: '#ffffff'
},
indicatorActiveWidth: {
type: [Number, String],
default: 24
},
dotBottom: {
type: [Number, String],
default: 32
},
keyName: {
type: String,
defalut: 'url'
defalut: 'image'
}
},
computed: {
imageStyle() {
let style = {}
if(this.imageWidth) style.width = this.imageWidth + 'rpx'
else style.width = '100%'
if(this.imageHeight) style.height = this.imageHeight + 'rpx'
else style.height = '100%'
style.borderRadius = this.radius + 'rpx'
return style
},
numStyleP() {
let style = {}
if(this.numPosition.indexOf('top') != -1) style.top = '20rpx'
if(this.numPosition.indexOf('bottom') != -1) style.bottom = '20rpx'
if(this.numPosition.indexOf('Left') != -1) style.left = '20rpx'
if(this.numPosition.indexOf('Right') != -1) style.right = '20rpx'
if(this.numPosition.indexOf('Center') != -1) {
style.left = '50%'
style.transform = 'translateX(-50%)'
}
if(this.numStyle) {
style = {...style, ...this.numStyle}
}
return style
},
dotBoxStyle() {
let style = {}
style.bottom = this.dotBottom + 'rpx'
return style
},
dotStyle() {
let style = {}
style.background = this.indicatorColor
return style
},
dotActiveStyle() {
let style = {}
style.width = this.indicatorActiveWidth +'rpx'
style.background = this.indicatorActiveColor
return style
}
},
data() {
return {
current: 0,
list: [{
// Image: 'https://cdn.uviewui.com/uview/resources/video.mp4',
image: 'https://cdn.uviewui.com/uview/swiper/swiper1.png',
title: '昨夜星辰昨夜风,画楼西畔桂堂东',
poster: 'https://cdn.uviewui.com/uview/swiper/swiper1.png',
url: 'www.baidu.com',
jump: 'app',
type: 'video'
},{
image: 'https://cdn.uviewui.com/uview/swiper/swiper2.png',
title: '身无彩凤双飞翼,心有灵犀一点通',
type: 'image'
},{
image: 'https://cdn.uviewui.com/uview/swiper/swiper3.png',
title: '谁念西风独自凉,萧萧黄叶闭疏窗,沉思往事立残阳'
}],
};
},
created() {
},
methods: {
// 获取轮播图
getList() {
},
// 点击跳转
jump(item) {
},
// 轮播图滚动变化
changeIndex(e) {
this.current = e.detail.current
},
// 点击指示点
checkItem(index) {
this.current = index
}
}
}
</script>
<style lang="scss">
.swiper-content {
position: relative;
width: 100%;
height: 100%;
.swiper {
width: 100%;
height: 100%;
.swiper-item {
.image {
display: flex;
justify-content: center;
align-items: center;
width: 100%;
height: 100%;
}
}
}
.pagenum-box {
position: absolute;
width: 74rpx;
height: 40rpx;
background: rgba(255,255,255,0.5);
border-radius: 40rpx;
font-size: 20rpx;
font-family: San Francisco Text-Regular, San Francisco Text;
font-weight: 400;
color: #222222;
text-align: center;
line-height: 40rpx;
}
.dot-box {
position: absolute;
bottom: 32rpx;
display: flex;
align-items: center;
justify-content: center;
width: 100%;
.dot-item {
margin: 0 6rpx;
width: 12rpx;
height: 12rpx;
border-radius: 6rpx;
}
}
}
</style>

View File

@@ -0,0 +1,145 @@
<template>
<view class="upload-box">
<view v-if="value" class="upload-box-items" :style="[defaultStyle]">
<view class="" v-html="videoHtml" />
<image v-if="clearIcon" :src="clearIcon" mode="" @click="del" />
<image v-else class="clear" src="@/static/images/components/upload/clear.png" mode="widthFix" @click="del" />
</view>
<view v-else class="upload-box-items" :style="[defaultStyle]" @click="chooseVideo">
<image v-if="uploadIcon" :src="uploadIcon" mode="" />
<image v-else src="@/static/images/components/upload/plus_upLoad_icon.png" mode="" />
</view>
</view>
</template>
<script>/**
* image-upload 图片上传组件
* @description 该组件为图片上传组件
* @tutorial
* @property {String} value v-model 图片结果
* @property {String | Number} imageWidth 上传图片宽度默认198rpx
* @property {String | Number} imageHeight 上传图片宽度(默认等于宽度)
* @property {String} uploadIcon 上传图片图标
* @property {String} clearIcon 删除图片
* @example <image-upload v-model="value" />
*/
import config from '@/config';
import { getToken } from '@/utils/auth';
export default {
name:"video-upload",
props: {
value: {
type: String,
default: ''
},
/** 图片宽度 */
width: {
type: [Number, String],
default: 600
},
/** 图片高度 */
height: {
type: [Number, String],
default: 328
},
/** 上传图片背景 */
uploadIcon: {
type: String,
default: ''
},
/** 清除按钮图片 */
clearIcon: {
type: String,
default: ''
}
},
computed: {
defaultStyle(){
let style = {}
style.width = this.width + 'rpx'
if(this.height) {
style.height = this.height + 'rpx'
} else style.height = this.width + 'rpx'
return style
},
videoHtml() {
return `<video src="${this.value}" style="width: 100%;height: 100%;" controls="controls" ></video>`
},
},
methods: {
// 移除图片
del() {
this.$emit('input', '')
},
// 选择图片
chooseVideo(){
uni.chooseVideo({
success: res => {
uni.showLoading({
title: '文件上传中',
mask: true
});
this.updata(res.tempFilePaths)
}
})
},
// 上传
updata(url) {
// 默认请求地址
let baseURL = config.fileUploadUrl;
let token = getToken();
uni.uploadFile({
url: baseURL, // 仅为示例,非真实的接口地址
filePath: url,
name: 'file',
header: {
'Authorization': token ? 'Bearer' + ' ' + token : ''
},
success: (res) => {
uni.hideLoading();
let url = JSON.parse(res.data).data.url;
this.$emit('success', url)
},
fail: (error) => {
uni.hideLoading();
uni.showToast({
title: error.msg,
icon: 'none'
})
this.$emit('fail', error.msg)
}
})
}
}
}
</script>
<style lang="scss">
.upload-box {
display: flex;
flex-flow: wrap;
}
.upload-box-items {
position: relative;
margin-right: 20rpx;
margin-bottom: 20rpx;
font-size: 24rpx;
color: #979797;
background: #FEFEFE;
// border-radius: 20rpx;
image {
width: 100%;
height: 100%;
border-radius: 20rpx;
}
.clear {
position: absolute;
top: 0;
right: 0;
transform: translate(40%, -40%);
width: 48rpx;
border-radius: 50%;
background-color: white;
}
}
</style>

View File

@@ -6,10 +6,16 @@
<image-upload v-model="images" :loop="true" />
</view>
</view>
<view class="">
<label for="">视频上传组件</label>
<view class="video-upload">
<video-upload v-model="video" />
</view>
</view>
<view class="">
<label>轮播图组件</label>
<view class="image-upload">
<lxk-swiper />
<view class="branner-box">
<lxk-swiper :indicatorDots="true" />
</view>
</view>
</view>
@@ -20,6 +26,7 @@
data() {
return {
images: 'https://jidansc.oss-cn-hangzhou.aliyuncs.com/2023/05/06/b2149e0fb0fc49ad8a8137f175b6f45f.jpg,https://jidansc.oss-cn-hangzhou.aliyuncs.com/2023/05/06/ce6a0adece6f461c9c2b50933adf8d62.jpg,https://jidansc.oss-cn-hangzhou.aliyuncs.com/2023/05/06/cca1213a9be0402788d32035a39acbb5.jpg,https://jidansc.oss-cn-hangzhou.aliyuncs.com/2023/05/06/f882c188b16a41daa86e550fa6213cf2.jpg',
video: 'https://cdn.uviewui.com/uview/resources/video.mp4'
};
},
watch: {
@@ -35,4 +42,11 @@
.image-upload {
padding: 22rpx;
}
.video-upload {
}
.branner-box {
width: 750rpx;
height: 500rpx;
}
</style>