文章目录
1. 使用uView插件
1.1 安装(2.0):
npm install uview-ui@2.0.28
1.2 配置:
1.2.1 在根目录的pages.json中添加
"easycom": {
"^u-(.*)": "uview-ui/components/u-$1/u-$1.vue"
},
1.2.2 在根目录的uni.scss中添加
@import 'uview-ui/theme.scss';
1.2.3 在App.vue的style中添加
<style lang="scss">
/*每个页面公共css */
@import "uview-ui/index.scss";
@import url("./static/font/icon.scss");
uni-page-body,
html,
body {
height: 100%;
}
</style>
1.3 使用1.0和Nvue的处理
因为uview1.0 不支持nvue,所以会报很多错,在上步骤1.2.3时,加个判断
<style lang="scss">
/*每个页面公共css */
/* #ifndef APP-NVUE */
@import "uview-ui/index.scss";
@import url("./static/font/icon.scss");
uni-page-body,
html,
body {
height: 100%;
}
/* #endif */
</style>
2. 配置导航栏:
2.1 底部导航栏 图标及未选中图标
在pages.json文件
"tabBar": {
"color": "#7A7E83",
"selectedColor": "#007AFF",
"borderStyle": "black",
"backgroundColor": "#F8F8F8",
"list": [{
"navigationBarBackgroundColor": "#8A2BE2",
"pagePath": "pages/index/index",
"iconPath": "static/home.png", // 未选中
"selectedIconPath": "static/home_cur.png", // 选中
"text": "首页"
}
]
}
2.2 顶部导航栏
在pages.json文件
2.2.1 一般导航栏
"pages": [
{
"path": "pages/xuncha/xunchaList",
"style": {
"navigationBarBackgroundColor": "#3B6FFF",
"navigationBarTextStyle": "white",
"navigationBarTitleText": "巡查处置",
"app-plus": {
"titleNView": true
}
},
2.2.2 导航栏添加文字、图标、事件
"pages": [
"style": {
"navigationBarBackgroundColor": "#8A2BE2",
"navigationBarTextStyle": "white",
"navigationBarTitleText": "设施管理",
"app-plus": {
"titleNView": {
"backgroundImage": "linear-gradient(to right, #C280FF, #5E7EDB, #5E7EDB, #C280FF)",
"buttons": [{
"text": "\ue468", // 注意:此处只能使用Unicode码
"fontSrc": "./static/uni.ttf", // 需要引入字体
"fontSize": "25",
"float": "right"
}]
}
}
}
]
图标的点击事件:在该文件中,生命周期位置
// 监听tabbar右侧按钮的点击事件
onNavigationBarButtonTap(e) {
// 如果有多个图标,可以判断 e.float == 'right'
uni.navigateTo({
url: "xxx可以路由跳转"
})
},
2.2.3 定制导航栏
将titleNView 设为false
"pages": [
{
"path": "pages/xuncha/xunchaList",
"style": {
"navigationBarBackgroundColor": "#3B6FFF",
"navigationBarTextStyle": "white",
"navigationBarTitleText": "巡查处置",
"app-plus": {
"titleNView": false //去掉app+h5顶部导航
}
},
在文件中,配置地址:https://ext.dcloud.net.cn/plugin?name=uni-nav-bar
<uni-nav-bar fixed="true" background-color="#62e6b9" color="#fff" title="巡查处置" status-bar="true"
left-icon="back" :right-icon="userType != 1 ? 'plusempty' : ''" @clickRight="clickNavRight()" @clickLeft="clickNavLeft()">
</uni-nav-bar>
// 可以控制图标,还能自定义点击事件
2.2.4 导航栏加图片,加副标题
链接:https://uniapp.dcloud.io/component/navigation-bar.html#navigation-bar
<page-meta>
<navigation-bar
:title="nbTitle"
:title-icon="titleIcon"
:title-icon-radius="titleIconRadius"
:subtitle-text="subtitleText"
:subtitle-color="nbFrontColor"
:loading="nbLoading"
:front-color="nbFrontColor"
:background-color="nbBackgroundColor"
:color-animation-duration="2000"
color-animation-timing-func="easeIn"
/>
</page-meta>
data() {
return {
nbTitle: '大洋湾综合管理平台',
titleIcon: '/static/images/home/titleIcon.png',
titleIconRadius: '20px',
subtitleText: 'subtitleText',
nbLoading: false,
nbFrontColor: '#fff',
nbBackgroundColor: '#79C0D1',
}
}
2.3 底部导航栏,根权限展示不同的栏目
利用 uni.setTabBarItem
和 visible
来实现
在pages.json中配置齐全,然后在登陆后,根据后端返回的角色,来判断设置
if(res.data.data.userInfo.userType == 1) {
uni.setTabBarItem({
index: 2,
visible: false,
})
}
3. 下拉刷新 和 上拉加载
3.1 下拉刷新
- ① 首先在pages.json中开启
{
"path": "pages/xx/xx",
"style": {
// ...略
"enablePullDownRefresh": true, // 开启下拉动画
"app-plus": {
"titleNView": {
"backgroundImage": "linear-gradient(to right, #62e6b9, #20bd8d)"
}
}
}
},
- ② 然后在使用的地方,与onLoad等平级
onPullDownRefresh() {
uni.startPullDownRefresh({
success: () => {
this.getList(); // 每次下拉重新调用
uni.stopPullDownRefresh(); // 手动关闭下拉动画
}
})
},
3.2 上拉加载(分页)
- 在使用页面,与onLoad等平级
// 在模板底部加上
<u-loadmore :status="status" />
// js部分
data() {
return {
status: 'loadmore',
pageNo: 1
}
},
onReachBottom() {
this.status = 'loading';
setTimeout(() => {
this.pageNo += 1;
this.getDatas();
}, 1000)
},
methods: {
getDatas() {
// 请求时将pageNo传给后端即可
}
}
- 提示如果有搜索、或者下拉时,pageNo = 1即可。
4. 使用云数据库和云函数
4.1 新建云函数
在项目目录上右键 -> 新建uniCloud云开发环境 -> 阿里云(腾讯云只能认证一个) -> 在生成的uniCloud下的cloudfunctions 右键,新建云函数
'use strict';
const db = uniCloud.database(); // 获取数据库的引用
exports.main = async (event, context) => {
let num = event.scope*10;
const dbcmd = db.command; // 获取指令集
const {
data } = await db.collection('infoClassify').where({
// 获取 数据库集合引用, 并查询
// id: event.scope // 查找id 为请求值的数据
// id: parserInt(event.scope) // 有时候数据是字符串类型,需要转换一下(路由传参就是字符串型)
id: dbcmd.gte(num).and(dbcmd.lt(num+10)) // 查找 大于num且小于num+10的数据
}).get(); // 记得要get一下,否则查不到
//返回数据给客户端
return data
};
写完云函数后,记得右键【上传部署】
4.2 云数据库
在云数据库中,新建表,全部是 json格式的
4.3 使用云函数
// 在onLoad生命周期中使用
async onLoad() {
let {
result, success} = await uniCloud.callFunction({
name: "getClassify" // 刚才新建的云函数文件夹名字
})
console.log(result, success);
},
// 在监听器中使用
watch: {
activeIndex: {
handler: async function(val) {
let res = await uniCloud.callFunction({
name: 'leftClassify', // 云函数的文件夹名字
data: {
scope: val + 1
}
})
this.tabbar = res.result;
// 默认选中第一个
this.classifyId = this.tabbar[0].classifyId;
},
immediate: true
}
},
参考文档:https://uniapp.dcloud.net.cn/uniCloud/cf-functions?id=clientcallfunction
5. 图片上传和预览
5.1 uView 2.0版本
<u-form-item label="照片" labelWidth="100"></u-form-item>
<u-upload :fileList="info.xc" width="120" height="120" @afterRead="after" @delete="deletePic" multiple :maxCount="1" :previewFullImage="true" ></u-upload>
data() {
return {
fileList: [{
// 使用多张上传方式,可以实现预览
url: 'https://vkceyugu.cdn.bspapp.com/VKCEYUGU-4917ad8f-2b3c-4371-a1e5-dfe5771201c5/c814d40f-9041-4069-9ef2-063a94a08079.png'
}],
}
}
methods: {
// 删除图片
deletePic(event) {
this.fileList.splice(event.index, 1)
},
// 新增图片 - 单张(很少用)
async after(event) {
this.info.xc.push({
status: 'uploading',
message: '上传中'
})
const result = await this.uploadFilePromise(event.file[0].url, 99)
// 要先预览回显成功
// 方法一:使用splice和Object.assign
this.info.mp.splice(0, 1, Object.assign(this.info.mp[0], {
status: 'success',
message: '',
url: result
}))
// 方法二: 使用 $set 改变属性
// this.$set(this.info.xc[0], 'status', 'success')
// this.$set(this.info.xc[0], 'message', '')
// this.$set(this.info.xc[0], 'url', result)
},
// 新增图片 - 多张(尽量用)
async afterRead(event) {
// 当设置 mutiple 为 true 时, file 为数组格式,否则为对象格式
let lists = [].concat(event.file)
let fileListLen = this.fileList.length
lists.map((item) => {
this.fileList.push({
...item,
status: 'uploading',
message: '上传中'
})
})
for (let i = 0; i < lists.length; i++) {
const result = await this.uploadFilePromise(lists[i].url, i)
let item = this.info.fileList[fileListLen]
this.fileList.splice(fileListLen, 1, Object.assign(item, {
status: 'success',
message: '',
url: result
}))
fileListLen++
}
},
// 上传图片
uploadFilePromise(url, i) {
return new Promise((resolve, reject) => {
// 方式一:如果是上传到自己的云存储中
//uniCloud.uploadFile({
//cloudPath: `test${i}.jpg`, // 文件名
//filePath: url, // 文件信息
//success(res) {
//setTimeout(() => {
//resolve(res.fileID)
//}, 1000)
//}
//})
// 方式二:如果是调用后端接口
let a = uni.uploadFile({
url: 'http://192.168.2.21:7001/upload', // 仅为示例,非真实的接口地址
filePath: url,
name: 'file',
formData: {
user: 'test'
},
success: (res) => {
setTimeout(() => {
resolve(res.data.data)
}, 1000)
}
});
})
},
}
5.2 uView 1.0版本
<u-upload :action="uploadURL()" :fileList="fileList" width="120" height="120" multiple :maxCount="3"
:previewFullImage="true" :showProgress="false" @on-success="onSuccess" @on-remove="onRemove" />
fileList: [
{
url: 'https://cdn.uviewui.com/uview/album/1.jpg'
},
{
url: 'https://cdn.uviewui.com/uview/album/2.jpg'
}
],
// 图片上传地址
uploadURL() {
return 'http://112.2.52.60:10000/bcz/app/test/api/personnelInfo/uploadPersonnelImage'
},
// 删除图片
onRemove(index) {
this.fileList.splice(index, 1)
},
// 新增图片
onSuccess(event, index, lists) {
// 解决上传时,多显示的bug
lists[index] = {
"url": data.data,
"error": false,
"progress": 100
};
// 放到数组里
this.fileList.push({
url: event.data
})
},
5.3 自定义封装
插件地址:
在static文件夹下 新建文件 video-icon.svg
<svg width="24" height="24" xmlns="http://www.w3.org/2000/svg" fill-rule="evenodd" clip-rule="evenodd"><path d="M24 23h-24v-21h24v21zm-20-1v-4h-3v4h3zm15 0v-19h-14v19h14zm4 0v-4h-3v4h3zm-6-9.5l-9 5v-10l9 5zm3 .5v4h3v-4h-3zm-16 4v-4h-3v4h3zm5-1.2l5.941-3.3-5.941-3.3v6.6zm11-7.8v4h3v-4h-3zm-16 4v-4h-3v4h3zm16-9v4h3v-4h-3zm-16 4v-4h-3v4h3z"/></svg>
在components 文件夹下 新建 htz-image-upload
<template>
<view class="htz-image-upload-list">
<view class="htz-image-upload-Item" v-for="(item,index) in uploadLists" :key="index">
<view class="htz-image-upload-Item-video" v-if="isVideo(item)">
<!-- #ifndef APP-PLUS -->
<video :disabled="false" :controls="false" :src="getFileUrl(item)">
<cover-view class="htz-image-upload-Item-video-fixed" @click="previewVideo(getFileUrl(item))">
</cover-view>
<cover-view class="htz-image-upload-Item-del-cover" v-if="remove && previewVideoSrc==''"
@click="imgDel(index)">×</cover-view>
</video>
<!-- #endif -->
<!-- #ifdef APP-PLUS -->
<view class="htz-image-upload-Item-video-fixed" @click="previewVideo(getFileUrl(item))"></view>
<image class="htz-image-upload-Item-video-app-poster" mode="widthFix" :src="appVideoPoster"></image>
<!-- #endif -->
</view>
<image v-else :src="getFileUrl(item)" @click="imgPreview(getFileUrl(item))"></image>
<view class="htz-image-upload-Item-del" v-if="remove" @click="imgDel(index)">×</view>
</view>
<view class="htz-image-upload-Item htz-image-upload-Item-add" v-if="uploadLists.length<max && add"
@click="chooseFile">
+
</view>
<view class="preview-full" v-if="previewVideoSrc!=''">
<video :autoplay="true" :src="previewVideoSrc" :show-fullscreen-btn="false">
<cover-view class="preview-full-close" @click="previewVideoClose"> ×
</cover-view>
</video>
</view>
<!-- -->
</view>
</template>
<style>
.ceshi {
width: 100%;
height: 100%;
position: relative;
top: 0;
left: 0;
bottom: 0;
right: 0;
background-color: #FFFFFF;
color: #2C405A;
opacity: 0.5;
z-index: 100;
}
</style>
<script>
export default {
name: 'htz-image-upload',
props: {
max: {
//展示图片最大值
type: Number,
default: 1,
},
chooseNum: {
//选择图片数
type: Number,
default: 9,
},
name: {
//发到后台的文件参数名
type: String,
default: 'file',
},
dataType: {
//v-model的数据结构类型
type