• uniuadmin后台管理系统|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',  100, fixed: true}, // 索引序号
                    {prop: 'title', label: '标题', align: 'left',  '350'},
                    {prop: 'num', label: '搜索量', align: 'center',  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',  80, fixed: true}, // 多选
                    {type: 'index', align: 'center',  80, fixed: true}, // 索引序号
                    {prop: 'author', label: '作者', align: 'center',  120},
                    {prop: 'title', label: '标题', align: 'left',  350},
                    {slot: 'image', label: '图片', align: 'center',  120},
                    {slot: 'switch', label: '推荐', align: 'center',  100},
                    {slot: 'tags', label: '标签', align: 'center',  100},
                    {slot: 'progress', label: '热度', align: 'center',  150},
                    {prop: 'date', label: '发布时间', align: 'left',  300}, // 时间
                    {slot: 'btns', label: '操作', align: 'center',  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短视频直播项目

    uni-app+uviewUI仿抖音小视频:https://www.cnblogs.com/xiaoyan2017/p/15312146.html

  • 相关阅读:
    [CF845G]Shortest Path Problem?
    [洛谷P4149][IOI2011]Race
    [洛谷P4178]Tree
    [AtCoder AGC27A]Candy Distribution Again
    [洛谷P3806]【模板】点分治1
    [洛谷P2634][国家集训队]聪聪可可
    [CF280C]Game on Tree
    [洛谷P3338][ZJOI2014]力
    [CF438D]The Child and Sequence
    [CF609E]Minimum spanning tree for each edge
  • 原文地址:https://www.cnblogs.com/xiaoyan2017/p/15836112.html
Copyright © 2020-2023  润新知