前端vue3——实现二次元人物拼图校验

news2024/9/25 17:02:43

文章目录

    • ⭐前言
    • ⭐vue3拖拽实现拼图
      • 💖 思路分解
      • 💖 布局结构
      • 💖 拖拽函数
      • 💖 校验函数
      • 💖 inscode整体代码
    • ⭐运行效果
      • 💖 随机顺序
      • 💖 拖拽中
      • 💖 校验失败
      • 💖 校验通过
    • ⭐总结
    • ⭐结束

yma16-logo

⭐前言

大家好,我是yma16,本文分享关于 前端vue3——实现二次元人物拼图校验。
vue3系列相关文章:
vue3 + fastapi 实现选择目录所有文件自定义上传到服务器
前端vue2、vue3去掉url路由“ # ”号——nginx配置
csdn新星计划vue3+ts+antd赛道——利用inscode搭建vue3(ts)+antd前端模板
认识vite_vue3 初始化项目到打包
python_selenuim获取csdn新星赛道选手所在城市用echarts地图显示
让大模型分析csdn文章质量 —— 提取csdn博客评论在文心一言分析评论区内容
前端vue3——html2canvas给网站截图生成宣传海报
拖拽相关文章
前端——html拖拽原理

前端html拖拽原理
HTML 拖拽的基本原理是通过鼠标事件和 DOM 操作来实现的。

一般来说,拖拽操作包括三个阶段:

  1. 鼠标按下事件:当用户按下鼠标左键时,触发鼠标按下事件。在该事件处理函数中,首先需要记录下被拖拽元素的相关信息,比如该元素的位置、大小和初始鼠标点击位置等。

  2. 鼠标移动事件:当用户按下鼠标左键时并拖动鼠标时,触发鼠标移动事件。在该事件处理函数中,需要根据鼠标当前位置和拖拽元素的初始位置,计算出该元素要被移动的距离,并在 DOM 中更新该元素的位置。

  3. 鼠标松开事件:当用户松开鼠标左键时,触发鼠标松开事件。在该事件处理函数中,需要清除拖拽元素的相关信息,比如初始鼠标点击位置等。

在以上三个阶段中,需要使用的 DOM 操作包括:

  1. 获取 DOM 元素:可以使用 document.getElementById() 或 document.querySelector() 等方法来获取需要拖拽的元素。

  2. 更新元素位置:可以使用元素的 style 属性来修改元素的位置,比如设置元素的 left 和 top 属性。

  3. 创建新元素:可以使用 document.createElement() 方法来创建新的 DOM 元素。

通过以上鼠标事件和 DOM 操作的组合,可以实现基本的 HTML 拖拽功能。

⭐vue3拖拽实现拼图

使用vue3和原生的html drag 实现片的拖拽

💖 思路分解

  1. 拆分图片为4宫格样式
  2. 定义拖拽的样式div对应图片的4宫格
  3. 定义拖拽的div元素,背景图片使用图片拆分的素材
  4. 给元素定义序号
  5. 校验最终的元素序号,判断是否拼图成功

拆分图片
split-image

💖 布局结构

才有左右布局
左侧:拖拽来源区域
右侧:拖拽放入区域
template布局

<template>
    <div class="container-drag">
        <div style="width: 100%;text-align:center;margin: 10px;">
            <a-button type="primary" class="random-button" @click="randomDragOrder">随机顺序</a-button>
        </div>
        <div class="container-drag-box">
            <div class="container-drag-left">
                <!-- <> -->
                <div v-for="item in state.dragConfig.sourceArray" :key="item.id" class="drag-item-box"
                    :id="state.dragConfig.sourceDomPrefix + '-' + item.id">
                    <div class="drag-item" draggable="true" :id="state.dragConfig.dragDomPrefix + '-' + item.id">
                        <!-- 拖拽对象 data-order 校验排序用 -->
                        <img :src="item.src" width="280" height="280" :data-order="item.id" />
                    </div>
                </div>
            </div>

            <div class="container-drag-right" id="target-box-id">
                <!-- 目标对象 data-order 校验排序用-->
                <div v-for="item in state.dragConfig.sourceArray" :key="item" class="target-item-box dropzone"
                    :id="state.dragConfig.targetDomPrefix + '-' + item.id" :data-order="item.id">

                </div>
            </div>
        </div>
        <div style="width: 100%;text-align:center">
            <a-button type="primary" @click="confirmImg">
                确定
            </a-button>
        </div>
    </div>
</template>

css配置

<style>
.container-drag {

    min-width: 800px;
}

.random-button {
    margin: 5px;
    cursor: pointer;
}

.container-drag-box {
    display: flex;
    justify-content: space-between;
}

.container-drag-left {
    width: 800px;

}

.container-drag-right {
    width: 600px;
    height: 600px;
    margin: 0;
}

.drag-item-box {
    display: inline-block;
    margin: 2px;
    padding: 0;
    width: 280px;
    height: 280px;
    border: 1px solid rgb(24, 144, 255);
    overflow: hidden;

}


.target-item-box {
    display: inline-block;
    width: 280px;
    height: 280px;
    border: 1px solid rgb(255, 255, 255);
    box-sizing: border-box;
    overflow: hidden;
    margin-right: 5px;
    margin-bottom: 0;
    margin-top: 0;
}

/* 拖拽对象 */
.drag-item {
    margin: 0;
    text-align: center;
    cursor: pointer;
}

/* 拖拽中 */
.dragging {
    opacity: .5;
}

/* 悬浮上方 */
.dragover {
    background: rgba(0,255,0,.5);
}
</style>

布局效果
box-left

💖 拖拽函数

拖拽对象配置方法drag,dragstart,dragend
放入区域配置方法drop,dragover,dragleave,dragenter

// 拖拽对象
const drag = (event) => {
    console.log("dragging", event);
}

const dragStart = (event) => {
    // 保存被拖动元素的引用
    state.dragConfig.dragTarget = event.target;
    // 设置为半透明
    event.target.classList.add("dragging");
}

const dragEnd = (event) => {
    // 拖动结束,重置透明度
    event.target.classList.remove("dragging");
}

// 目标对象

const dragOver = (event) => {
    // 阻止默认行为以允许放置
    event.preventDefault();
}

const dragLeave = (event) => {
    // 在可拖动元素离开潜在放置目标元素时重置该目标的背景
    if (event.target.classList.contains("dropzone")) {
        event.target.classList.remove("dragover");
    }
}

const dragEnter = (event) => {
    // 在可拖动元素进入潜在的放置目标时高亮显示该目标
    if (event.target.classList.contains("dropzone")) {
        event.target.classList.add("dragover");
    }
}

const drop = (event) => {
    // 阻止默认行为(会作为某些元素的链接打开)
    event.preventDefault();
    // 将被拖动元素移动到选定的目标元素中
    if (event.target.classList.contains("dropzone")) {
        event.target.classList.remove("dragover");
        // 删除自身
        state.dragConfig.dragTarget.parentNode.removeChild(state.dragConfig.dragTarget);
        // 添加元素
        event.target.appendChild(state.dragConfig.dragTarget);
    }
}

const initDragAction = (sourceElement) => {
    if (!sourceElement) {
        return
    }
    /* 在放置拖拽对象上触发的事件 */
    sourceElement.addEventListener("drag", drag);

    sourceElement.addEventListener("dragstart", dragStart);

    sourceElement.addEventListener("dragend", dragEnd);
}

const initTargetAction = (targetElement) => {
    if (!targetElement) {
        return
    }
    /* 在放置目标对象上触发的事件 */

    targetElement.addEventListener(
        "dragover",
        dragOver,
        false,
    );

    targetElement.addEventListener("dragenter", dragEnter);

    targetElement.addEventListener("dragleave", dragLeave);

    targetElement.addEventListener("drop", drop);
}

💖 校验函数

遍历dom节点获取自定义的data-order属性进行校验

// 校验
const confirmImg = () => {
    const rightDom = document.getElementById('target-box-id')
    console.log('rightDom', rightDom)
    const rightDomChildNodes = rightDom.childNodes
    console.log('rightDomChildNodes', rightDomChildNodes)
    if (rightDomChildNodes.length) {
        // childNodes会出现空文本节点
        for (let i = 0, length = rightDomChildNodes.length; i < length; ++i) {
            console.log('childNodes', rightDomChildNodes[i])
            if (rightDomChildNodes[i].nodeType !== 1) {
                // 跳过文本节点
                continue
            }
            else if (rightDomChildNodes[i].hasChildNodes) {
                console.log('childNodes attr', rightDomChildNodes[i])
                const currentDataOrder = rightDomChildNodes[i].getAttribute('data-order')
                const imgDataOrder = rightDomChildNodes[i].getElementsByTagName('img')[0].getAttribute('data-order')
                console.log('currentDataOrder', currentDataOrder)
                console.log('imgDataOrder', imgDataOrder)
                if (currentDataOrder !== imgDataOrder) {
                    return message.warn('拼图位置错误:\t第' + currentDataOrder+'张图片')
                }
            }
            else {
                return message.warn('没有完成拼图,请拖拽图片')
            }
        }
    }
    else {
        return message.warn('没有完成拼图,请拖拽图片')
    }
    return '恭喜你完成拼图'
}

💖 inscode整体代码

完整的vue代码

<template>
    <div class="container-drag">
        <div style="width: 100%;text-align:center;margin: 10px;">
            <a-button type="primary" class="random-button" @click="randomDragOrder">随机顺序</a-button>
        </div>
        <div class="container-drag-box">
            <div class="container-drag-left">
                <!-- <> -->
                <div v-for="item in state.dragConfig.sourceArray" :key="item.id" class="drag-item-box"
                    :id="state.dragConfig.sourceDomPrefix + '-' + item.id">
                    <div class="drag-item" draggable="true" :id="state.dragConfig.dragDomPrefix + '-' + item.id">
                        <!-- 拖拽对象 data-order 校验排序用 -->
                        <img :src="item.src" width="280" height="280" :data-order="item.id" />
                    </div>
                </div>
            </div>

            <div class="container-drag-right" id="target-box-id">
                <!-- 目标对象 data-order 校验排序用-->
                <div v-for="item in state.dragConfig.sourceArray" :key="item" class="target-item-box dropzone"
                    :id="state.dragConfig.targetDomPrefix + '-' + item.id" :data-order="item.id">

                </div>
            </div>
        </div>
        <div style="width: 100%;text-align:center">
            <a-button type="primary" @click="confirmImg">
                确定
            </a-button>
        </div>
    </div>
</template>

<script setup>
import { reactive, onMounted } from 'vue'
import { message } from 'ant-design-vue'
const state = reactive({
    dragConfig: {
        sourceDomPrefix: 'source-item',
        targetDomPrefix: 'target-item',
        dragDomPrefix: 'drag-item',
        dragTarget: null,
        sourceImg: '/img/imageSource.png',
        sourceArray: [{
            id: 1,
            src: '/img/image1.png'
        },
        {
            id: 2,
            src: '/img/image2.png'
        },
        {
            id: 3,
            src: '/img/image3.png'
        },
        {
            id: 4,
            src: '/img/image4.png'
        },
        ]
    }
})
// 数组随机顺序
const randomDragOrder = () => {
    const sourceArray = [...state.dragConfig.sourceArray]
    sourceArray.sort(() => Math.random() - 0.5);
    state.dragConfig.sourceArray = sourceArray
}

// 拖拽对象
const drag = (event) => {
    console.log("dragging", event);
}

const dragStart = (event) => {
    // 保存被拖动元素的引用
    state.dragConfig.dragTarget = event.target;
    // 设置为半透明
    event.target.classList.add("dragging");
}

const dragEnd = (event) => {
    // 拖动结束,重置透明度
    event.target.classList.remove("dragging");
}

// 目标对象

const dragOver = (event) => {
    // 阻止默认行为以允许放置
    event.preventDefault();
}

const dragLeave = (event) => {
    // 在可拖动元素离开潜在放置目标元素时重置该目标的背景
    if (event.target.classList.contains("dropzone")) {
        event.target.classList.remove("dragover");
    }
}

const dragEnter = (event) => {
    // 在可拖动元素进入潜在的放置目标时高亮显示该目标
    if (event.target.classList.contains("dropzone")) {
        event.target.classList.add("dragover");
    }
}

const drop = (event) => {
    // 阻止默认行为(会作为某些元素的链接打开)
    event.preventDefault();
    // 将被拖动元素移动到选定的目标元素中
    if (event.target.classList.contains("dropzone")) {
        event.target.classList.remove("dragover");
        // 删除自身
        state.dragConfig.dragTarget.parentNode.removeChild(state.dragConfig.dragTarget);
        // 添加元素
        event.target.appendChild(state.dragConfig.dragTarget);
    }
}

const initDragAction = (sourceElement) => {
    if (!sourceElement) {
        return
    }
    /* 在放置拖拽对象上触发的事件 */
    sourceElement.addEventListener("drag", drag);

    sourceElement.addEventListener("dragstart", dragStart);

    sourceElement.addEventListener("dragend", dragEnd);
}

const initTargetAction = (targetElement) => {
    if (!targetElement) {
        return
    }
    /* 在放置目标对象上触发的事件 */

    targetElement.addEventListener(
        "dragover",
        dragOver,
        false,
    );

    targetElement.addEventListener("dragenter", dragEnter);

    targetElement.addEventListener("dragleave", dragLeave);

    targetElement.addEventListener("drop", drop);
}

// 校验
const confirmImg = () => {
    const rightDom = document.getElementById('target-box-id')
    console.log('rightDom', rightDom)
    const rightDomChildNodes = rightDom.childNodes
    console.log('rightDomChildNodes', rightDomChildNodes)
    if (rightDomChildNodes.length) {
        // childNodes会出现空文本节点
        for (let i = 0, length = rightDomChildNodes.length; i < length; ++i) {
            console.log('childNodes', rightDomChildNodes[i])
            if (rightDomChildNodes[i].nodeType !== 1) {
                // 跳过文本节点
                continue
            }
            else if (rightDomChildNodes[i].hasChildNodes) {
                console.log('childNodes attr', rightDomChildNodes[i])
                const currentDataOrder = rightDomChildNodes[i].getAttribute('data-order')
                const imgDataOrder = rightDomChildNodes[i].getElementsByTagName('img')[0].getAttribute('data-order')
                console.log('currentDataOrder', currentDataOrder)
                console.log('imgDataOrder', imgDataOrder)
                if (currentDataOrder !== imgDataOrder) {
                    return message.warn('拼图位置错误:\t第' + currentDataOrder+'张图片')
                }
            }
            else {
                return message.warn('没有完成拼图,请拖拽图片')
            }
        }
    }
    else {
        return message.warn('没有完成拼图,请拖拽图片')
    }
    return '恭喜你完成拼图'
}

// 生命周期
onMounted(() => {
    // 拖拽对象
    const dragArr = state.dragConfig.sourceArray.map(item => {
        return state.dragConfig.dragDomPrefix + '-' + item.id
    })
    dragArr.forEach(id => {
        initDragAction(document.getElementById(id))
    })


    // 目标对象
    const sourceArr = state.dragConfig.sourceArray.map(item => {
        return state.dragConfig.sourceDomPrefix + '-' + item.id
    })
    sourceArr.forEach(id => {
        initTargetAction(document.getElementById(id))
    })

    const targetArr = state.dragConfig.sourceArray.map(item => {
        return state.dragConfig.targetDomPrefix + '-' + item.id
    })
    targetArr.forEach(id => {
        initTargetAction(document.getElementById(id))
    })
})

</script>

<style>
.container-drag {

    min-width: 800px;
}

.random-button {
    margin: 5px;
    cursor: pointer;
}

.container-drag-box {
    display: flex;
    justify-content: space-between;
}

.container-drag-left {
    width: 800px;

}

.container-drag-right {
    width: 600px;
    height: 600px;
    margin: 0;
}

.drag-item-box {
    display: inline-block;
    margin: 2px;
    padding: 0;
    width: 280px;
    height: 280px;
    border: 1px solid rgb(255, 255, 255);
    overflow: hidden;

}


.target-item-box {
    display: inline-block;
    width: 280px;
    height: 280px;
    border: 1px solid rgb(255, 255, 255);
    box-sizing: border-box;
    overflow: hidden;
    margin-right: 5px;
    margin-bottom: 0;
    margin-top: 0;
}

/* 拖拽对象 */
.drag-item {
    margin: 0;
    text-align: center;
    cursor: pointer;
}

/* 拖拽中 */
.dragging {
    opacity: .5;
}

/* 悬浮上方 */
.dragover {
    background: rgba(0,255,0,.5);
}
</style>

代码放在inscode vue3项目在线运行

⭐运行效果

💖 随机顺序

random

💖 拖拽中

draging

💖 校验失败

verrify-error

💖 校验通过

verrify-success
拖拽过程截图

drag-process

⭐总结

拼图校验总结:

1.校验的顺序可以用元素的attribute传递位置顺序进行标记
2.拖拽对象的函数使用 拖拽对象配置方法drag,dragstart,dragend 放入区域配置方法drop,dragover,dragleave,dragenter

拖拽总结:

在HTML中,拖放(drag and
drop)是一种用户界面交互的特定形式,其中用户可以拖动元素或数据并将其放置在另一个位置。以下是HTML拖放的一些总结:

  1. 拖放可用于各种用途,例如重新排序列表,将文本或文件拖动到另一个应用程序中,或从文件资源管理器将文件拖动到Web页面中。
  2. 在HTML中,拖放API由一些事件组成,包括dragstart、dragenter、dragover、dragleave、drop和dragend。
  3. 通过使用HTML data属性,可以将数据附加到拖动事件,并在放置事件中访问它们。
  4. 通过使用CSS,可以为用户拖动时显示的元素创建自定义外观。
  5. 在JavaScript中,可以使用dragEvent对象来访问有关拖动和放置事件的详细信息,例如拖动元素的位置和放置元素的位置。
  6. 可以使用HTML5的拖放API创建复杂的拖放交互,例如可拖动的图形和对象,将元素沿路径拖动等。

⭐结束

本文分享到这结束,如有错误或者不足之处欢迎指出!
cute-img

👍 点赞,是我创作的动力!
⭐️ 收藏,是我努力的方向!
✏️ 评论,是我进步的财富!
💖 感谢你的阅读!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1310320.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【LeetCode:2132. 用邮票贴满网格图 | 二维前缀和 + 二维差分和】

&#x1f680; 算法题 &#x1f680; &#x1f332; 算法刷题专栏 | 面试必备算法 | 面试高频算法 &#x1f340; &#x1f332; 越难的东西,越要努力坚持&#xff0c;因为它具有很高的价值&#xff0c;算法就是这样✨ &#x1f332; 作者简介&#xff1a;硕风和炜&#xff0c;…

【Java8系列08】Java8中reducing妙用

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…

内网穿透的应用-如何在群辉7.2中使用Docker安装并远程访问本地网心云容器魔方管理界面

文章目录 1. 拉取容器魔方镜像2. 运行容器魔方3. 本地访问容器魔方4. 群辉安装Cpolar5. 配置容器魔方远程地址6. 远程访问测试7. 固定公网地址 本文主要介绍如何在群辉7.2版本中使用Docker安装容器魔方&#xff0c;并结合Cpolar内网穿透工具实现远程访问本地网心云容器魔方界面…

kernel32.dll动态链接库报错解决方法,详细解析kernel32.dll文件修复

在使用计算机过程中&#xff0c;你可能会遇到各种各样的错误消息。其中一个常见的错误是“找不到kernel32.dll”或类似的错误。这个错误消息通常会出现在运行某些程序时&#xff0c;可能会导致程序无法正常工作&#xff0c;甚至无法启动。那么&#xff0c;kernel32.dll到底是什…

UE5 C++(一)— 入门介绍

这里写目录标题 创建项目UBT和UHT介绍UnrealBuildTool&#xff08;UBT&#xff09;UnrealHeadTool&#xff08;UHT&#xff09; UEC主要的头文件介绍UEC各个宏的作用 创建项目 创建一个名为DEMO的UE5项目工程&#xff1a; 创建完成之后&#xff1a; 这里我使用的是VSCODE开…

计算机网络课程设计【Python实现】

一、网络聊天程序的设计与实现 1、实验目的 使用Socket编程&#xff0c;了解Socket通信的原理&#xff0c;会使用Socket进行简单的网络编程&#xff0c;并在此基础上编写聊天程序&#xff0c;运行服务器端和客户端&#xff0c;实现多个客户端通过服务器端进行通信。 2、总体设…

mybatis与oracle数据库jdbcType类型对应关系

之前都是百度上搜的&#xff0c;各种对应的都有&#xff0c;总觉得有问题&#xff0c;最后直接通过跑代码查看了一下对应关系&#xff0c;我用的oracle是19c。 常见的对应关系如下 oracle类型jdbcTypeVARCHAR2JdbcType.VARCHARNVARCHARJdbcType.NVARCHARCHARJdbcType.CHARCLOB…

阅读代码的记录

1-utils_metrics.py用在train.py中做指标衡量&#xff0c;现在想在推理&#xff08;predict.py&#xff09;的时候衡量一下指标 2-调研眼睛部位的单独分割。 https://blog.csdn.net/qq_40234695/article/details/88633094 衡量图像语义分割准确率主要有三种方法&#xff1a; …

CS106L2023 and CS106B 环境配置(详细教程)

1.问题&#xff1a; &#xff08;1&#xff09;CS106L 运行./setup.sh 脚本时出错 &#xff08;windows 请下载git&#xff0c;在git bash 打开运行&#xff09; &#xff08;2&#xff09;CS106B&#xff0c;QT构建 构建错误&#xff1a;一般构建错误&#xff0c;例如 Erro…

QT学习(0):qmake和编译

一、编译和链接 1.预处理 预处理是使用预处理器工具&#xff08;系统在编译过程中调用的预先编写的程序&#xff09;执行的 C 编译过程的第一步。C程序中所有以#符号开头的语句都会被预处理器处理&#xff0c;它将我们的程序文件转换为没有#语句的中间文件。 删除注释宏扩展…

【TC3xx】GETH

目录 一、RGMII 二、SMI接口 三、TC3xx MCAL 3.1 MCU 3.2 Port 3.3 DMA 3.4 中断配置 3.5 ETH 3.6 集成 一、RGMII TC3xx支持MII/RMII/RGMII三种以太网数据通信接口。其中RGMII经常用于MAC和MAC之间&#xff0c;或MAC与PHY之间的通信&#xff0c;RGMII的带宽可以是10M…

对于初学者来说,从哪些方面开始学习 Java 编程比较好?

对于初学者来说&#xff0c;从哪些方面开始学习 Java 编程比较好&#xff1f; 在开始前我有一些资料&#xff0c;是我根据自己从业十年经验&#xff0c;熬夜搞了几个通宵&#xff0c;精心整理了一份「Java的资料从专业入门到高级教程工具包」&#xff0c;点个关注&#xff0c;全…

vue2-安装elementUI时警告

警告内容&#xff1a;npm WARN deprecated core-js2.6.12: core-js<3.23.3 is no longer maintained and not recommended for usage due to the number of issues. Because of the V8 engine whims, feature detection in old core-js versions could cause a slowdown up …

机器学习可重复性危机下,创建复杂数据系统的挑战

文章目录 一、前言二、主要内容三、总结 &#x1f349; CSDN 叶庭云&#xff1a;https://yetingyun.blog.csdn.net/ 一、前言 数据科学系统已成为众多研究领域的关键性工具&#xff0c;其开发者群体呈现出多元化的背景特征。在过去十年中&#xff0c;尽管数据科学与机器学习的强…

OpenSSL的源码在哪里下载?

官方网站去下载&#xff0c;网址&#xff1a; https://www.openssl.org/source/ 比较老的版本的下载页面地址&#xff1a; https://www.openssl.org/source/old/ 由于某面板的OpenSSL模块的安装配置语句如下&#xff1a; --with-openssl/root/rpmbuild/BUILD/openssl-1.0.2u所…

TreeSelect 树型选择控件 编辑回显时所选的值与展开后的数据不对应 解决方案

一、业务场景&#xff1a; 最近在使用Vue框架和antd-vue组件库的时候&#xff0c;发现在做编辑回显时** TreeSelect 树型选择控件** 组件的选中的值能拿到&#xff0c;但是在下拉列表的回显位置有偏差。为了大家后面遇到和我一样的问题&#xff0c;给大家分享一下 二、bug信息…

商城免费搭建之java鸿鹄云商 java电子商务商城 Spring Cloud+Spring Boot+mybatis+MQ+VR全景+b2b2c

鸿鹄云商 SAAS云产品概述 1. 涉及平台 平台管理、商家端&#xff08;PC端、手机端&#xff09;、买家平台&#xff08;H5/公众号、小程序、APP端&#xff08;IOS/Android&#xff09;、微服务平台&#xff08;业务服务&#xff09; 2. 核心架构 Spring Cloud、Spring Boot、My…

el-tooltip 修改全局的样式 (默认的太丑了)

默认的是黑色的框 话不多说,上代码 : .atooltip.el-tooltip__popper[x-placement^"top"] .popper__arrow {border-top-color: #fff;color: #999;box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1); } .atooltip.el-tooltip__popper[x-placement^"top"] .popp…

kotlin 基础概览

继承类/实现接口 继承类和实现接口都是用的 : &#xff0c;如果类中没有构造器 ( constructor )&#xff0c;需要在父类类名后面加上 () &#xff1a; class MainActivity : BaseActivity(), View.OnClickListener 空安全设计 Kotlin 中的类型分为「可空类型」和「不可空类型」…

嵌入式培训-数据结构-day23-线性表

线性表 线性表是包含若干数据元素的一个线性序列 记为&#xff1a; L(a0, ...... ai-1, ai, ai1 ...... an-1) L为表名&#xff0c;ai (0≤i≤n-1)为数据元素&#xff1b; n为表长,n>0 时&#xff0c;线性表L为非空表&#xff0c;否则为空表。 线性表L可用二元组形式描述…