原创研发uniapp+vue3手机端后台管理|vue3+uniapp+pinia跨端后台OA系统模板UniVue3Admin。实现了自定义手机OA栅格磁贴引擎、多屏滑动管理、自定义桌面小部件、辅助触控悬浮球等功能。支持编译到H5+小程序端+App端。
vue3+uniapp+pinia跨端仿ios桌面OA管理系统
运行h5/小程序端/App端效果
使用HbuilderX4.15开发工具,采用vue3 setup语法。
技术栈
- 编辑器:HbuilderX 4.15
- 技术框架:uniapp+vue3+pinia2+vite5.x
- UI组件库:uni-ui+uv-ui(uniapp vue3组件库)
- 弹框组件:uv3-popup(基于uniapp+vue3自定义弹框组件)
- 表格组件:uv3-table(基于uniapp+vue3增强版表格)
- 图表组件:qiun-data-charts
- 模拟数据:mockjs(用于自定义表格模拟数据)
- 缓存技术:pinia-plugin-unistorage
- 支持编译:h5+小程序端+app端
项目结构图
整个项目采用全新原创的栅格磁贴引擎系统。
App.vue模板
<script setup>
import { provide } from 'vue'
import { onLaunch, onShow, onHide, onPageNotFound } from '@dcloudio/uni-app'
import { authStore } from '@/pinia/modules/auth'
const authState = authStore()
onLaunch(() => {
console.log('App Launch')
if(!authState.authorization) {
uni.redirectTo({
url: '/pages/auth/launch'
})
}
initSystemInfo()
})
onShow(() => {
console.log('App Show')
})
onHide(() => {
console.log('App Hide')
})
onPageNotFound((e) => {
console.warn('Route Error:', `${e.path}`)
})
// 获取系统设备信息
const initSystemInfo = () => {
uni.getSystemInfo({
success: (e) => {
// 获取手机状态栏高度
let statusBar = e.statusBarHeight
let customBar
// #ifndef MP
customBar = statusBar + (e.platform == 'android' ? 50 : 45)
// #endif
// #ifdef MP-WEIXIN
// 获取胶囊按钮的布局位置信息
let menu = wx.getMenuButtonBoundingClientRect()
// 导航栏高度 = 胶囊下距离 + 胶囊上距离 - 状态栏高度
customBar = menu.bottom + menu.top - statusBar
// #endif
// #ifdef MP-ALIPAY
customBar = statusBar + e.titleBarHeight
// #endif
// 由于globalData在vue3 setup存在兼容性问题,改为provide/inject替代
provide('globalData', {
statusBarH: statusBar,
customBarH: customBar,
screenWidth: e.screenWidth,
screenHeight: e.screenHeight,
platform: e.platform
})
}
})
}
</script>
<style>
/* #ifndef APP-NVUE */
@import 'static/fonts/iconfont.css';
/* #endif */
</style>
<style lang="scss">
@import 'styles/reset.scss';
@import 'styles/layout.scss';
</style>
main.js入口配置
/**
* 入口文件 main.js
*/
import { createSSRApp } from 'vue'
import App from './App'
// 引入pinia状态管理
import pinia from '@/pinia'
export function createApp() {
const app = createSSRApp(App)
app.use(pinia)
return {
app,
pinia
}
}
采用全新的滑屏数字解锁模式。
该项目前后开发了差不多一个月的时间,已经正式的完结了。
公共模板
<script setup>
import { ref } from 'vue'
import { appStore } from '@/pinia/modules/app'
const appState = appStore()
// #ifdef MP-WEIXIN
defineOptions({
/**
* 解决小程序class、id透传问题(vue3写法)
* manifest.json中配置mergeVirtualHostAttributes: true, 在微信小程序平台不生效,组件外部传入的class没有挂到组件根节点上
* https://github.com/dcloudio/uni-ui/issues/753
*/
options: { virtualHost: true }
})
// #endif
const props = defineProps({
showBackground: { type: [Boolean, String], default: true },
})
// 自定义变量(桌面图标)
const deskVariable = ref({
'--icon-radius': '15px', // 圆角
'--icon-size': '118rpx', // 图标尺寸
'--icon-gap-col': '25px', // 水平间距
'--icon-gap-row': '45px', // 垂直间距
'--icon-labelSize': '12px', // 标签文字大小
'--icon-labelColor': '#fff', // 标签颜色
'--icon-fit': 'contain', // 图标自适应模式
})
</script>
<template>
<view class="uv3__container flexbox flex-col flex1" :style="deskVariable">
<!-- 顶部插槽 -->
<slot name="header" />
<!-- 内容区 -->
<view class="uv3__scrollview flex1">
<slot />
</view>
<!-- 底部插槽 -->
<slot name="footer" />
<!-- 背景图(修复小程序不支持background背景图) -->
<image v-if="showBackground" class="fixwxbg" :src="appState.config.skin || '/static/skin/theme.png'" mode="scaleToFill" />
</view>
</template>
桌面desk布局
<!-- 桌面模板 -->
<script setup>
import { ref } from 'vue'
import Desk from './components/desk.vue'
import Dock from './components/dock.vue'
import Touch from './components/touch.vue'
</script>
<template>
<uv3-layout>
<!-- 桌面菜单 -->
<Desk />
<template #footer>
<!-- 底部导航 -->
<Dock />
</template>
<!-- 悬浮球(辅助触控) -->
<Touch />
</uv3-layout>
</template>
栅格布局引擎
桌面图标配置
/**
* label 图标标题
* imgico 图标(本地或网络图片) 当type: 'icon'则为uni-icons图标名,当type: 'widget'则为自定义小部件标识名
* type 图标类型(icon | widget) icon为uni-icons图标、widget为自定义小部件
* path 跳转路由页面
* link 跳转外部链接
* hideLabel 是否隐藏图标标题
* background 自定义图标背景色
* size 栅格磁贴布局(16种) 1x1 1x2 1x3 1x4、2x1 2x2 2x3 2x4、3x1 3x2 3x3 3x4、4x1 4x2 4x3 4x4
* onClick 点击图标回调函数 * children 二级菜单
*/
<template>
<swiper
class="uv3__deskmenu"
:indicator-dots="true"
indicator-color="rgba(255,255,255,.5)"
indicator-active-color="#fff"
>
<swiper-item v-for="(mitem, mindex) in deskMenu" :key="mindex">
<view class="uv3__gridwrap">
<view v-for="(item, index) in mitem.list" :key="index" class="uv3__gridwrap-item" @click="handleClickDeskMenu(item)">
<!-- 图标 -->
<view class="ico" :style="{'background': item.background}">
<!-- 二级菜单 -->
<template v-if="Array.isArray(item.children)">
<view class="uv3__gridwrap-thumb">
...
</view>
</template>
<template v-else>
<template v-if="item.type == 'widget'">
<!-- 自定义部件 -->
<component :is="item.imgico" />
</template>
<template v-else>
<!-- 自定义图标 -->
...
</template>
</template>
</view>
<!-- 标签 -->
<view v-if="!item.hideLabel" class="label clamp2">{{item.label}}</view>
</view>
</view>
</swiper-item>
</swiper>
<!-- 桌面二级菜单弹窗 -->
<Popup v-model="deskPopupVisible">
<view class="uv3__deskpopup">
...
</view>
</Popup>
...
</template>
Okay,综上就是uniapp+vue3实战开发手机端后台OA系统的一些知识分享,希望对大家有些帮助~
https://ask.dcloud.net.cn/article/41065
作者:xiaoyan2017
链接: https://segmentfault.com/a/1190000044899693
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
1 个评论
要回复文章请先登录或注册
x***@126.com (作者)