uni-uadmin后台管理系统|uniapp+uView跨端后台框架实例
基于uniapp+uview+uni-ui跨平台手机端后台管理系统UniappUAdmin。
uniapp-uadmin 基于uni-app+uView+uniUI研发的跨端手机后台管理系统项目。全新的毛玻璃视觉UI界面,内置了图表、自定义表格、表单、瀑布流及图文编辑器等业务模块,动态权限管理,错误页处理,支持编译至H5+小程序+APP端。
如上图:编译到H5+APP+小程序端效果
◆ 技术栈
- 编码器:HbuilderX3.3.5
- 框架技术:vue.js+uniapp+vuex+mockjs
- UI组件库:uView-ui+uni-ui
- 弹窗组件:ua-popup(基于uni-app跨端弹框组件)
- 表格组件:ua-table(基于uni-app封装的多功能表格)
- 自定义组件:uaDock全新的dock风格tabbar组件
- 图表组件:u-charts图表库
- 模拟数据:mock.js
◆ 功能特色
✅ 全新替代tabbar动态毛玻璃菜单Dock
✅ 支持动态权限管理、错误页处理
✅ 内置多图表组件、表格、表单、瀑布流列表及富文本编辑器
✅ 支持编译h5+APP+小程序端
◆ 目录结构
整个项目采用标准的模糊化结构开发方式,所有表格数据使用mock.js模拟。
◆ 公共模板UAPage
<!-- 公共页面模板 --> <template> <view class="ua__pageview flexbox flex-col" :style="{'--SKIN': $store.state.skin, 'background': bgcolor, 'color': color}"> <slot name="header" /> <!-- //主容器 --> <view class="ua__scrollview flex1"> <slot /> </view> <!-- //底部 --> <slot name="footer" /> <!-- //dock菜单 --> <ua-dock v-if="dock && dock != 'false'" @click="handleDockClick" /> <!-- //函数式弹框 --> <ua-popup ref="uapopup" /> <!-- //换肤弹框模板 --> <ua-popup v-model="isVisibleSkin" position="right"> <Skin /> </ua-popup> </view> </template>
项目中顶部导航条及弹窗组件,使用自定义组件实现,之前有分享过相关的介绍文章。
https://www.cnblogs.com/xiaoyan2017/p/14978408.html
https://www.cnblogs.com/xiaoyan2017/p/14993445.html
◆ uniapp毛玻璃模糊视觉Dock
项目中的底部dock菜单采用了背景模糊化效果,替代了系统tabbar组件。可左右丝滑滚动,图标支持iconfont和图片,另外还支持badge圆点数字提示。选项支持切换tabbar页面,跳转新页面,可定制化选项。
<!-- //底部dock菜单 --> <template> <view class="ua__dockbar"> <scroll-view class="ua__dock-scroll ua__filter" :class="platform" scroll-x :style="{'background': bgcolor}"> <view class="ua__dock-wrap"> <!-- Tab菜单项 --> <block v-for="(item, index) in menu" :key="index"> <view v-if="item.type == 'divider'" class="ua__dock-divider"></view> <view v-else class="ua__dock-item" :class="currentTabIndex == index ? 'cur' : ''" @click="switchTab(index, item)"> <text v-if="item.icon" class="iconfont nvuefont" :class="item.icon">{{item.icon}}</text> <image v-if="item.img" :src="item.img" class="iconimg" :style="{'font-size': item.iconSize}" /> <text v-if="item.badge" class="ua__badge ua__dock-badge">{{item.badge}}</text> <text v-if="item.dot" class="ua__badge-dot ua__dock-badgeDot"></text> </view> </block> </view> </scroll-view> </view> </template>
组件props支持如下参数配置
props: { // 当前索引 current: { type: [Number, String], default: 0 }, // 背景色 bgcolor: { type: String, default: null }, /** * [ 菜单选项 ] type 菜单类型 type: 'tab'支持uni.switchTab切换 type: 'divider'分割线 path 菜单页面地址 icon 菜单图标-iconfont图标 img 菜单图片 color 菜单图标颜色 title 标题 badge 圆点数字 dot 小红点 */ menu: { type: Array, default: () => [ /* Tab菜单 */ { type: 'tab', path: '/pages/index/index', icon: `\ue619`, color: '#2979ff', title: '首页', }, { type: 'tab', path: '/pages/component/index', icon: 'icon-component', color: '#17c956', title: '组件', badge: 5, }, { type: 'tab', path: '/pages/permission/index', icon: 'icon-auth', color: '#f44336', title: '权限管理', }, { type: 'tab', path: '/pages/setting/index', icon: 'icon-wo', color: '#8d1cff', title: '设置', dot: true, }, { path: '/pages/error/404', img: require('@/static/mac/keychain.png'), title: '错误页面', }, { type: 'divider' }, /* Nav菜单 */ { img: require('@/static/logo.png'), title: 'github', }, { img: 'https://www.uviewui.com/common/logo.png', title: 'gitee', }, { img: require('@/static/mac/colorsync.png'), title: '皮肤', }, { img: require('@/static/mac/info.png'), title: '关于', }, { type: 'divider' }, { img: require('@/static/mac/bin.png'), title: '回收站', badge: 12, }, ] }, },
点击每一个选项切换页面
// Tab切换 switchTab(index, item) { if(item.path) { let type = item.type == 'tab' ? 'switchTab' : 'navigateTo' uni[type]({ url: item.path, }) }else { if(item.type == 'tab') { this.currentTabIndex = index } } this.$emit('click', index) }
◆ uniapp自定义表格组件
这一次项目一大亮点,uniapp多功能自定义表格组件。网上也有很多uniapp表格组件,比较简陋、功能性并不好。于是就自研了这款ua-table表格组件。
ua-table 一款支持全选、单选,列宽/居中及可左右、上下滑动固定表头及列,支持点击行返回行数据,返回单选及多选行列数据,自定义slot插槽等功能。
使用非常之简单,只需如下方式调用即可。
<ua-table :columns="columns" headerBgColor="#eee" :headerBold="true" stripe padding="5px 0" :data="data.list" height="450rpx" > </ua-table>
<script> import Mock from 'mockjs' export default { data() { return { columns: [ {type: 'index', align: 'center', width: 100, fixed: true}, // 索引序号 {prop: 'title', label: '标题', align: 'left', width: '350'}, {prop: 'num', label: '搜索量', align: 'center', width: 120}, ], data: Mock.mock({ total: 100, page: 1, pagesize: 10, 'list|10': [ { id: '@id()', title: '@ctitle(10, 20)', num: '@integer(1000,10000)' } ] }), } } } </script>
支持自定义插槽,则可通过如下方式使用。
<ua-table :columns="columns" headerBgColor="#eee" :headerBold="true" :stripe="true" :data="data.list" @row-click="handleRowClick" @select="handleCheck" height="750rpx" style="border:1px solid #eee" > <template #default="{row, col, index}"> <block v-if="col.slot == 'image'"> <u-image :src="row.image" :lazy-load="true" height="100rpx" width="100rpx" @click="previewImage(row.image)" /> </block> <block v-if="col.slot == 'switch'"> <u-switch v-model="row.switch" inactive-color="#fff" :size="36"></u-switch> </block> <block v-if="col.slot == 'tags'"> <u-tag :text="row.tags" bg-color="#607d8b" color="#fff" mode="dark" size="mini" /> </block> <block v-if="col.slot == 'progress'"> <u-line-progress active-color="#1fb925" :percent="row.progress" :show-percent="false" :height="16"></u-line-progress> </block> <block v-if="col.slot == 'btns'"> <view class="ua__link success" @click.stop="handleFormEdit(row)">编辑</view> <view class="ua__link error" @click.stop="handleDel(row, index)">删除</view> </block> </template> </ua-table>
<script> import Mock from 'mockjs' export default { data() { return { columns: [ {type: 'selection', align: 'center', width: 80, fixed: true}, // 多选 {type: 'index', align: 'center', width: 80, fixed: true}, // 索引序号 {prop: 'author', label: '作者', align: 'center', width: 120}, {prop: 'title', label: '标题', align: 'left', width: 350}, {slot: 'image', label: '图片', align: 'center', width: 120}, {slot: 'switch', label: '推荐', align: 'center', width: 100}, {slot: 'tags', label: '标签', align: 'center', width: 100}, {slot: 'progress', label: '热度', align: 'center', width: 150}, {prop: 'date', label: '发布时间', align: 'left', width: 300}, // 时间 {slot: 'btns', label: '操作', align: 'center', width: 150, fixed: 'right'}, // 操作 ], data: Mock.mock({ total: 100, page: 1, pagesize: 10, 'list|30': [ { id: '@id()', author: '@cname()', title: '@ctitle(10, 20)', image: 'https://picsum.photos/400/400?random=' + '@guid()', switch: '@boolean()', 'tags|1': ['admin', 'test', 'dev'], progress: '@integer(30, 90)', date: '@datetime()' } ] }), } } } </script>
注意:自定义插槽,需要将字段属性改为slot: xxx
当初开发这款表格组件遇到最大的一个问题就是,在小程序端slot不支持动态:name,明明这样就可以完美实现动态slot功能
<slot :name="col.slot" :row="row" :col="col" :index="rIndex" />
在小程序端怎么都没反应,还报错一大推。万般无奈,最后只能采用这种兼容写法。
<block v-if="col.slot"><slot :row="row" :col="col" :index="rIndex" /></block>
如果大家有更好的解决方法,欢迎留言一起交流学习。
Okay,以上就是今天的分享,后续还会分享一些最新实例项目,希望可以喜欢哈~~
最后附上两个最新原创uniapp+vue3实战项目案例