当前位置: 首页 > article >正文

web vue 滑动选择 n宫格选中 九宫格选中

页面动态布局经常性要交给客户来操作,他们按时他们的习惯在同一个屏幕内显示若干个子视图,尤其是在医学影像领域对于影像的同屏显示目视对比显的更为重要。

来看看如下的用户体验:

 设计为最多支持5行6列页面展示后,右侧的布局则动态跟随来显示更多影像图像,在目视范围内则可以做出更多读片等判断操作。

下面来给出实现代码。

首先给出页面代码,因页面较为复杂,这里只给核心处的代码,你只需要重点关注el-popover组件位置的使用即可:

<div class="layout-view flex-row jc-center" v-for="layItem in layoutSeriTools"
    :key="layItem.icon" :class="{ 'tool-item-hl': layItem.selected }"
    @click="seriesLayoutAction(layItem)">
    <el-image v-if="layItem.tag != 4" class="layout-item" :src="layItem.icon"></el-image>
    <el-popover ref="boxPopover_0" v-else class="layout-item" popper-class="pop-grid-view" placement="right-start"
        trigger="hover">
        <div class="v-box-view" @mouseleave="leaveBoxAction(0)">
            <div class="v-box-item-view" :class="{ 'hili-box': ibox.selected }"
                v-for="(ibox, ixIndex) in layItem.child" :key="ixIndex"
                @mouseenter="hoverBoxAction(0, ibox)" @click="boxClickAction(0)"></div>
        </div>
        <el-image slot="reference" class="layout-item" :src="layItem.icon"></el-image>
    </el-popover>
    <el-image v-if="layItem.tag == 4" class="down-view"
        :src="require('@/assets/images/downArrow.png')"></el-image>
</div>

我使用的elmentUI,其主题默认是白色,我根据页面修改了组件的样式:你想改就改,不改就忽略。

<style lang="scss" scoped>
.dropdown-menu-view {
    background: #222;
    background-color: #222;
    border: 2px solid #343434;
}


.dropdown-menu-item-view {
    color: white;

    &:hover {
        background-color: rgba(2, 134, 240, 0.2);
        color: white;
    }
}
</style>


<style>
.popperView.el-select-dropdown {
    border: 2px solid #343434;
}


.popperView .el-select-dropdown__list {
    background-color: #222;
}

/* 自定义选中的选项背景色 */
.popperView .el-select-dropdown__item.selected {
    background-color: rgba(2, 134, 240, 0.2);
    color: white;
}

/* 自定义鼠标悬停的选项背景色 */
.popperView .el-select-dropdown__item:hover {
    background-color: #ecf5ff;
}

.popperView .el-select-dropdown__item {
    background-color: transparent;

    &:hover {
        background-color: rgba(2, 134, 240, 0.2);
        color: white;
    }
}

.el-popper[x-placement^=top] .popper__arrow::after {
    border-top-color: #343434;
}

.el-popper[x-placement^=top] .popper__arrow {
    border-top-color: #343434;
}

.el-popper[x-placement^=bottom] .popper__arrow::after {
    border-bottom-color: #343434;
}

.el-popper[x-placement^=bottom] .popper__arrow {
    border-bottom-color: #343434;
}


.el-popper[x-placement^=right] .popper__arrow {
    border-right-color: #343434;
}

.el-popper[x-placement^=right] .popper__arrow::after {
    border-right-color: #343434 !important;
}

.pop-grid-view.el-popper {
    background: #1a1a1a;
    background-color: #1a1a1a;
    border: 3px solid #343434;
    padding: 0px;
    border-radius: 0px;
}
</style>

 

数据定义,元素从左到右均在数组中定义,只有最后一个元素时,才会显示自定义宫格功能,所以,数据仍然定义在其child中,注意其他元素并没有child。

layoutSeriTools: [{
    tag: 0,
    icon: require("@/assets/images/layout-1.png"),
    title: '',
    selected: true,
    toolsId: ''
}, {
    tag: 1,
    icon: require("@/assets/images/layout-2.png"),
    title: '',
    selected: false,
    toolsId: ''
}, {
    tag: 2,
    icon: require("@/assets/images/layout-3.png"),
    title: '',
    selected: false,
    toolsId: ''
}, {
    tag: 3,
    icon: require("@/assets/images/layout-4.png"),
    title: '',
    selected: false,
    toolsId: ''
}, {
    tag: 4,
    icon: require("@/assets/images/layout-5.png"),
    title: '',
    selected: false,
    toolsId: '',
    child: []
}],

 给最后一个元素塞入5行6列的数据,因为VUE本身就是MVVM,即我们好数据,对数据进行直接操作时,页面则会动态渲染。我们不可能愚蠢的去手动一个一个塞!所以这里使用for循环来塞。cols代表第几列,rows代码第几行,通过求商、求余来控制方格的元数据。

let boxItem = aForm.layoutSeriTools.filter(p => p.tag == 4)[0]
for (let i = 0; i < 30; i++) {
    let e = {
        selected: false,
        cols: i % 6,
        rows: parseInt(i / 6)
    }

    boxItem.child.push(e)
}

通过上面的代码就已经可以正常的弹出定义的行列显示,现在添加业务数据的控制逻辑:

 鼠标滑动到哪格中,小于这个格元数据的行、列则选中,否则不选中!这个方法则是核心!

hoverBoxAction(tag, item) {
    let list = tag == 0 ? this.layoutSeriTools.filter(p => p.tag == 4)[0].child : this.layoutPicTools.filter(p => p.tag == 4)[0].child
    let row = item.rows
    let col = item.cols
    list.forEach(m => {
        m.notClearn = false
        m.selected = m.cols <= col && m.rows <= row
    });
},
boxClickAction(tag) {
    let tList = tag == 0 ? this.layoutSeriTools:this.layoutPicTools
    let list = tList.filter(p => p.tag == 4)[0].child
    let nList = list.filter(p => p.selected == true)
    nList.forEach(m => {
        m.notClearn = true
    });
    tList.filter(p=>p.selected == true).firstObject().selected = false
    tList.filter(p=>p.tag == 4).firstObject().selected = true
    this.$refs[`boxPopover_${tag}`][0].doClose()
},
leaveBoxAction(tag) {
    //别有用意,不要随便改时间,只是为了动画同步
    setTimeout(() => {
        let list = tag == 0 ? this.layoutSeriTools.filter(p => p.tag == 4)[0].child : this.layoutPicTools.filter(p => p.tag == 4)[0].child
        list.forEach(m => {
            if (!m.notClearn) {
                m.selected = false
            }
        });
    }, 300);
}

祝你使用丝滑!若有疑问,请发表评论或者私信沟通。 


http://www.kler.cn/a/421358.html

相关文章:

  • 【Linux篇】权限管理 - 用户与组权限详解
  • 构建自己的docker的ftp镜像
  • Linux 网卡收包流程如下
  • Spring Cloud Alibaba(六)
  • 【案例教程】python生物信息多组学大数据深度挖掘与论文整理技巧实践技术应用
  • GEOBench-VLM:专为地理空间任务设计的视觉-语言模型基准测试数据集
  • Python办公——openpyxl处理Excel每个sheet每行 修改为软雅黑9号剧中+边框线
  • 三十二:HTTP 协议的基本认证
  • Linux中的 tail 命令
  • 2024.12.3总结
  • MATLAB 离散点构建凸包,计算面积周长(88)
  • jmeter 压测常用静默参数解释应用
  • 速盾:高防 CDN 中高级缓存有什么用?
  • 普中51单片机——LED流水灯模块
  • 【实战场景】PageHelper分页插件,total总数不一致问题
  • 【jvm】什么是垃圾
  • jmeter如何导出中文版的测试报告?
  • Python中的函数参数
  • Kotlin的object修饰符定义类似Java的静态类/静态方法
  • bfs--acwing
  • 利用HTML5获取店铺商品详情:打造现代化电商平台的新篇章
  • 系统规划与管理师历年综合知识真题重点知识点
  • Oracle DB的并发控制
  • Win10+Ubuntu20.04双系统重装Ubuntu22.04单系统
  • LeetCode - #150 逆波兰表达式求值
  • Linux 中Shell快捷键