上一篇文章快速搭建前端网络请求有跟大家介绍Vue快速搭建一个H5页面,以及怎样实现H5和Native原生事件交互。基于此基础,我们今天来用WeUI.js实现手机图片的上传。

Package.json配置

1
2
3
4
5
6
7
8
9
"dependencies": {
"jquery": "^3.5.0",
"moment": "^2.24.0",
"vue-datetime": "^1.0.0-beta.11",
"weui.js": "^1.2.1"
},
"devDependencies": {
"weui": "^2.1.3"
}

Weui-uploader

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<div class="weui-uploader">
<div class="weui-uploader__bd">
<ul class="weui-uploader__files1" id="uploaderFiles" v-on:click="prevImageAction" >
<li class="weui-uploader__file weui-uploader__file_status" v-for="(item,index) in imageSources"
v-bind:key="index" :data-id="index+1" v-bind:style="{backgroundImage:'url(' + item.url + ')'}"></li>
</ul>
<div class="weui-uploader__input-box" >
<input id="uploaderInput" class="weui-uploader__input" type="file" accept="image/*" multiple="">
</div>
</div>
</div>
<script>
import weui from 'weui.js' //weuiJs
import $ from 'jquery' //引入jquery
...

由于weui-uploader依赖jquery,我们在挂载的时候,将uploader节点通过jquery获取到。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
mounted:function(){
let t = this;
var weuiLoading = null;
weui.uploader('#uploader', {
url: this.$http.defaults.baseURL +'/upload/image/',
auto: true, //自动还是手动上传
type: 'file', //file类型,base64类型
fileVal: 'file', //文件上传域的name
compress: {
width: 1600,
height: 1600,
quality: 0.65
},
onBeforeQueued: function(files) {
// `this` 是轮询到的文件, `files` 是所有文件

if(["image/jpg", "image/jpeg", "image/png", "image/gif"].indexOf(this.type) < 0){
weui.topTips('请上传图片');
return false; // 阻止文件添加
}
if(this.size > 10 * 1024 * 1024){
weui.topTips('请上传不超过10M的图片');
return false;
}
if (files.length > 1) { // 防止一下子选择过多文件
weui.topTips('只能上传1张图片,请重新选择');
return false;
}

// return true; // 阻止默认行为,不插入预览图的框架
},
onQueued: function(){

t.imageSources = [this];
weuiLoading = t.$weui.loading('上传中');
// console.log(this.status); // 文件的状态:'ready', 'progress', 'success', 'fail'
// console.log(this.base64); // 如果是base64上传,file.base64可以获得文件的base64
// this.upload(); // 如果是手动上传,这里可以通过调用upload来实现;也可以用它来实现重传。
// this.stop(); // 中断上传
// return true; // 阻止默认行为,不显示预览图的图像
},
onBeforeSend: function(data, headers){
console.log("上传onBeforeSend");
console.log(this, data);
t.imageSources = [this];

// $.extend(data, { name: "file"}); // 可以扩展此对象来控制上传参数
// $.extend(headers, {'Content-Disposition': 'form-data; name=file;filename='+this.name,'Content-Type':this.type}); // 可以扩展此对象来控制上传头部
// $.extend(headers, {'file':this});
// return false; // 阻止文件上传
},
onProgress: function(procent){
t.imageSources = [this];
// return true; // 阻止默认行为,不使用默认的进度显示
},
onSuccess: function (ret) {
weuiLoading.hide();
console.log("上传成功");
t.imageSources = [this];
console.log(this.status);
console.log(this, ret);
if(ret.status == 1){
t.liveCoverUrl = ret.data.url;
}
// return true; // 阻止默认行为,不使用默认的成功态
},
onError: function(err){
weuiLoading.hide();
console.log("上传失败");
t.imageSources = [this];
console.log(this.status);
// return true; // 阻止默认行为,不使用默认的失败态
}
});
},

注意点:type: ‘file’控制为file类型即可,然后自动上传。另外,在Android机器上 input type=file accept=”image/*” multiple=”” 还需要android的webview配置开启文件权限才可以读取相册的图片。

页面跳转配置

为了实现页面与页面之前的跳转以及动画过渡,我们对App.vue进行了改进。我们根据路径跳转的长度比较来选择不同的动画样式。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
<template>
<div id="app">
<transition :name="transitionName">
<keep-alive >
<router-view v-if="$route.meta.keepAlive" />
</keep-alive>
</transition>

<transition :name="transitionName">
<router-view v-if="!$route.meta.keepAlive"/>
</transition>
</div>
</template>

<style>
.fade-right-leave-active,
.fade-right-enter-active,
.fade-left-leave-active,
.fade-left-enter-active {
transition: all 0.4s ease;
position: absolute;
left: 0;
top: 0;
}

.fade-right-enter {
transform: translate3d(-50%, 0, 0);
opacity: 0;
}

.fade-right-leave-to {
transform: translate3d(50%, 0, 0);
opacity: 0;
}

.fade-left-enter {
transform: translate3d(50%, 0, 0);
opacity: 0;
}

.fade-left-leave-to {
transform: translate3d(-50%, 0, 0);
opacity: 0;
}
</style>

<script>
export default {
name: 'app',
data(){
return{
transitionName: '',
//transitionName 如果是同级的,过渡效果也可以根据别名路径的长度。
}
},
watch: {
'$route' (to, from) {

const toDepth = to.path.split('/').length
const fromDepth = from.path.split('/').length
this.transitionName = toDepth < fromDepth ? 'fade-right' : 'fade-left'
}
}
}
</script>

Moment 日期格式化工具

1
2
3
4
5
6
7
8
9
10
11
12
<datetime input-class ="weui-input"   placeholder="选择开播时间"  format="yyyy-MM-dd HH:mm" type="datetime" v-model="beginDatetime"  :minute-step="15"
:max-datetime="endDatetime">
<datetime input-class ="weui-input" :min-datetime="beginDatetime" :minute-step="15" placeholder="选择结束时间" format="yyyy-MM-dd HH:mm" type="datetime" v-model="endDatetime"></datetime>

<script>
//在main.js引入
import { Datetime } from 'vue-datetime'
import 'vue-datetime/dist/vue-datetime.css'

//在vue文件引入
import moment from "moment";
</script>
1
2
3
4
5
6
7
8
9
10
11
12
   //提交数据的时候,将Date类型转成long类型
let begninTime = moment(this.beginDatetime).valueOf();
let endTime = moment(this.endDatetime).valueOf();

//数据解析的时候,将long类型转成日期类型
let pageVue = this;
if(liveRoom.begin > 0){
pageVue.beginDatetime = moment(liveRoom.begin).format();
}
if(liveRoom.end > 0){
pageVue.endDatetime = moment(liveRoom.end).format();
}

计算上个月的时间:

1
2
3
4
5
6
7
lastMonthData: function() {
const end = new Date()
const start = new Date()
start.setTime(start.getTime() - 3600 * 1000 * 24 * 30);
this.beginDateStr = moment(start.getTime()).format('YYYY-MM-DD');
this.endDateStr = moment(end.getTime()).format('YYYY-MM-DD');
},

WeUI-datePicker

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<div class="weui-cells__group weui-cells__group_form">
<div class="weui-cells__title">时间范围</div>
<div class="weui-cells">
<div class="weui-cell weui-cell_access" v-on:click="showComonPickerAction">
<div class="weui-cell__hd"><label class="weui-label">时间段</label></div>
<div class="weui-cell__bd weui-cell__bd_right">{{ticketItem? ticketItem.label:''}}</div>
<div class="weui-cell__ft"></div>
</div>
<div class="weui-cell weui-cell_access" v-on:click="showStartDatePickerAction">
<div class="weui-cell__hd"><label class="weui-label">开始日期</label></div>
<div class="weui-cell__bd weui-cell__bd_right">{{beginDateStr}}</div>
<div class="weui-cell__ft"></div>
</div>
<div class="weui-cell weui-cell_access" v-on:click="showEndDatePickerAction">
<div class="weui-cell__hd"><label class="weui-label">结束日期</label></div>
<div class="weui-cell__bd weui-cell__bd_right">{{endDateStr}}</div>
<div class="weui-cell__ft"></div>
</div>
</div>
</div>

开始时间和结束时间结合使用:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
//显示开始时间
showStartDatePickerAction: function() {
//weUI 显示日期控件
let that = this;
this.$weui.datePicker({
end: that.endDateStr,
cron: '* * *',
defaultValue: that.beginDateStr.split("-"),
onChange: function(result) {
var dateArr = Array();
for (var i = 0; i < result.length; i++) {
let item = result[i];
let valueStr = '' + item.value;
if (i > 0 && valueStr.length == 1) {
valueStr = '0' + valueStr;
}
dateArr.push(valueStr);
}
that.beginDateStr = dateArr.join("-");
},
onConfirm: function(result) {

var dateArr = Array();
for (var i = 0; i < result.length; i++) {
let item = result[i];
let valueStr = '' + item.value;
if (i > 0 && valueStr.length == 1) {
valueStr = '0' + valueStr;
}
dateArr.push(valueStr);
}
that.beginDateStr = dateArr.join("-");
},
id: 'startDatePicker',
title: '选择开始日期'
});
},

//显示结束时间
showEndDatePickerAction: function(e) {
//weUI 显示日期控件
let that = this;
this.$weui.datePicker({
start: that.beginDateStr,
end: new Date(),
cron: '* * *',
defaultValue: that.endDateStr.split("-"),
onChange: function(result) {
var dateArr = Array();
for (var i = 0; i < result.length; i++) {
let item = result[i];
let valueStr = '' + item.value;
if (i > 0 && valueStr.length == 1) {
valueStr = '0' + valueStr;
}
dateArr.push(valueStr);
}
that.endDateStr = dateArr.join("-");
},
onConfirm: function(result) {

var dateArr = Array();
for (var i = 0; i < result.length; i++) {
let item = result[i];
let valueStr = '' + item.value;
if (i > 0 && valueStr.length == 1) {
valueStr = '0' + valueStr;
}
dateArr.push(valueStr);
}
that.endDateStr = dateArr.join("-");
},
id: 'endDatePicker',
title: '选择结束日期'
});
},

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
//自定义时间段
showComonPickerAction: function() {
var typesArr = ['近一周', '近一月', '近一年'];
var dataArr = Array();
typesArr.forEach(function(value, index) {
dataArr.push({
label: value,
value: index
});
});

let that = this;
this.$weui.picker(dataArr, {
defaultValue: [1],
className: 'custom-picker-item',
container: 'body',
onChange: function(result) {},
onConfirm: function(result) {
if (result.length) {
that.ticketItem = result[0];

if (that.ticketItem.value == 0) {
const end = new Date();
const start = new Date();
start.setTime(start.getTime() - 3600 * 1000 * 24 * 7);
that.beginDateStr = moment(start.getTime()).format('YYYY-MM-DD');
that.endDateStr = moment(end.getTime()).format('YYYY-MM-DD');
} else if (that.ticketItem.value == 1) {
that.lastMonthData();
} else {
const end = new Date()
const start = new Date()
start.setTime(start.getTime() - 3600 * 1000 * 24 * 365);
that.beginDateStr = moment(start.getTime()).format('YYYY-MM-DD');
that.endDateStr = moment(end.getTime()).format('YYYY-MM-DD');
}
}
},
id: 'picker',
title: '时间段筛选'
});
}

列表滚到底部自动加载更多

1
2
3
4
<div class="weui-loadmore" v-if="hasMoreDataFlag">
<i class="weui-loading"></i>
<span class="weui-loadmore__tips">正在加载</span>
</div>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
mounted: function() {
// 添加滚动事件,检测滚动到页面底部
window.addEventListener('scroll', this.scrollBottom);
},
methods: {

scrollBottom(event) {

let scrollTop = document.body.scrollTop;

// 滚动到页面底部时 && 请求加载已完成 && 还有下一页的数据;
if ((((window.screen.height + scrollTop) >= (document.body.scrollHeight)) && this.requestLoadingFinished &&
this.hasMoreDataFlag)) {
this.requestLoadingFinished = false;
this.pageNumber++;

this.loadCustomerDataRequest();
}
},
}

评论