Sortable.js:功能强大的JavaScript 拖拽库

news2024/9/21 4:22:23

原文地址:Sortable.js:功能强大的JavaScript 拖拽库

一、介绍

Sortable.js一个功能强大的JavaScript 拖拽库!!!用于在网页上创建可拖放和可排序的元素。它提供了简单而强大的 API,使开发人员能够轻松地实现拖放功能,并允许用户通过拖放来重新排序列表、网格和其他元素。

主要有以下特性:

  • 兼容性好:支持触屏设备和大部分浏览器,支持现代浏览器,并提供了对旧版浏览器的向后兼容性;
  • 简单:简单的API,方便使用,通过简单的HTML 结构和 JavaScript API,可以快速实现拖放排序功能;
  • 原生:基于原生HTML5中的拖放API;
  • CSS框架兼容性:支持所有的css框架,像Bootstrap;
  • 零依赖:不依赖Jquery等其他框架;
  • SPA支持良好:支持多种框架(angular、vue、react等);
  • 高度可定制:通过配置选项和回调函数,可以自定义拖放行为和排序效果;
  • 交互性:除了基本的拖放功能外,SortableJS 还提供了丰富的交互性选项,如拖放动画、排序同步等; 社区支持:
  • SortableJS有一个活跃的开发者社区,为使用该库的开发者提供支持、插件和示例。

二、安装

1、npm安装

npm install sortablejs --save

2、bower安装

bower install --save sortablejs

3、script引入

<script src="../../js/Sortable.min.js"></script>

三、配置项

const sortable = new Sortable(el, {
     // or { name: "...", pull: [true, false, 'clone', array], put: [true, false, array] }
    group: "name", 
    // boolean 定义是否列表单元是否可以在列表容器内进行拖拽排序
    sort: true,  
     // number 定义鼠标选中列表单元可以开始拖动的延迟时间;
    delay: 0,
    // px,在取消延迟拖动事件之前,点应该移动多少像素
    touchStartThreshold: 0, 
    // boolean 定义是否此sortable对象是否可用,为true时sortable对象不能拖放排序等功能,为false时为可以进行排序,相当于一个开关;
    disabled: false, 
    // @see Store
    store: null, 
     // ms, number 单位:ms,定义排序动画的时间
    animation: 150, 
    // 制作动画。默认为null,https://easings.net/。
    easing: "cubic-bezier(1, 0, 0, 1)",
     // 格式为简单css选择器的字符串,使列表单元中符合选择器的元素成为拖动的手柄,只有按住拖动手柄才能使列表单元进行拖动
    handle: ".my-handle", 
    // 过滤器,不需要进行拖动的元素
    filter: ".ignore-elements", 
    //  在触发过滤器`filter`的时候调用`event.preventDefault()`
    preventOnFilter: true, 
     // 允许拖拽的项目类名
    draggable: ".item", 
     // drop placeholder的css类名
    ghostClass: "sortable-ghost", 
     // 被选中项的css 类名
    chosenClass: "sortable-chosen", 
     // 正在被拖拽中的css类名
    dragClass: "sortable-drag", 
    dataIdAttr: 'data-id',
    // 交换区的阈值
    swapThreshold: 1,
    // 如果设置为 true,将始终使用反向交换区
    invertSwap: false, 
    // 反向交换阈值,默认情况下将设置为swapThreshold 值
    invertedSwapThreshold: 1, 
    // 拖拽方向 (默认情况下会自动判断方向)
    direction: 'horizontal', 
    // 忽略 HTML5拖拽行为,强制回调进行
    forceFallback: false,  
    // 当使用forceFallback的时候,被复制的dom的css类名
    fallbackClass: "sortable-fallback",  
    // 将cloned DOM 元素挂到body元素上。
    fallbackOnBody: false,  
     // 以像素为单位指定鼠标在被视为拖动之前应移动的距离。
    fallbackTolerance: 0,
    // 是否启用滚动,值为true或者HTMLElement
    scroll: true,
    // 自定义滚动
    scrollFn: function(offsetX, offsetY, originalEvent, touchEvt, hoverTargetEl) { ... }, 
    // 鼠标必须离边缘多近才能开始滚动,单位 px
    scrollSensitivity: 30, 
     // 滚动速度,px
    scrollSpeed: 10,
    // 将自动滚动应用于所有父元素,以便更轻松地移动
    bubbleScroll: true, 
    dragoverBubble: false,
    // 删除不显示的克隆元素,而不是仅仅隐藏它
    removeCloneOnHide: true, 
    // 拖动时鼠标必须与空可排序项的距离(以像素为单位),以便将拖动元素插入到该可排序项中, 设置为0禁用此功能。
    emptyInsertThreshold: 5,

    setData: function (/** DataTransfer */dataTransfer, /** HTMLElement*/dragEl) {
        dataTransfer.setData('Text', dragEl.textContent); // `dataTransfer` object of HTML5 DragEvent
    },

    // 元素被选中
    onChoose: function (/**Event*/evt) {
        evt.oldIndex;  // element index within parent
    },

    // 元素未被选中的时候(从选中到未选中)
    onUnchoose: function(/**Event*/evt) {
        // same properties as onEnd
    },

    // 开始拖拽的时候
    onStart: function (/**Event*/evt) {
        evt.oldIndex;  // element index within parent
    },

    // 结束拖拽
    onEnd: function (/**Event*/evt) {
        var itemEl = evt.item;  // dragged HTMLElement
        evt.to;    // target list
        evt.from;  // previous list
        evt.oldIndex;  // element's old index within old parent
        evt.newIndex;  // element's new index within new parent
        evt.clone // the clone element
        evt.pullMode;  // when item is in another sortable: `"clone"` if cloning, `true` if moving
    },

    // 元素从一个列表拖拽到另一个列表
    onAdd: function (/**Event*/evt) {
        // same properties as onEnd
    },

    // 列表内元素顺序更新的时候触发
    onUpdate: function (/**Event*/evt) {
        // same properties as onEnd
    },

    // 列表的任何更改都会触发
    onSort: function (/**Event*/evt) {
        // same properties as onEnd
    },

    // 元素从列表中移除进入另一个列表
    onRemove: function (/**Event*/evt) {
        // same properties as onEnd
    },

    // 试图拖拽一个filtered的元素
    onFilter: function (/**Event*/evt) {
        var itemEl = evt.item;  // HTMLElement receiving the `mousedown|tapstart` event.
    },

    // 拖拽移动的时候
    onMove: function (/**Event*/evt, /**Event*/originalEvent) {
        // Example: https://jsbin.com/nawahef/edit?js,output
        evt.dragged; // dragged HTMLElement
        evt.draggedRect; // DOMRect {left, top, right, bottom}
        evt.related; // HTMLElement on which have guided
        evt.relatedRect; // DOMRect
        evt.willInsertAfter; // Boolean that is true if Sortable will insert drag element after target by default
        originalEvent.clientY; // mouse position
        // return false; — for cancel
        // return -1; — insert before target
        // return 1; — insert after target
    },

    // clone一个元素的时候触发
    onClone: function (/**Event*/evt) {
        var origEl = evt.item;
        var cloneEl = evt.clone;
    },

    // 拖拽元素改变位置的时候
    onChange: function(/**Event*/evt) {
        evt.newIndex // most likely why this event is used is to get the dragging element's current index
        // same properties as onEnd
    }
});                    

1.属性

(1)group:string or object

  • string:命名,个人建议用元素id就行,用处是为了设置可以拖放容器时使用,在array中的put的设置中再做介绍。
  • object:{name,pull,put}。
    name:同string的方法。
    pull:pull用来定义从这个列表容器移动出去的设置,true/false/‘clone’/function。true:列表容器内的列表单元可以被移出;false:列表容器内的列表单元不可以被移出;‘clone’:列表单元移出,移动的为该元素的副本;function:用来进行pull的函数判断,可以进行复杂逻辑,在函数中return false/true来判断是否移出。
    put:put用来定义往这个列表容器放置列表单元的的设置,true/false/[‘foo’,‘bar’]/function。true:列表容器可以从其他列表容器内放入列表单元;false:与true相反; [‘foo’,‘bar’]:这个可以是一个字符串或者是字符串的数组,代表的是group配置项里定义的name值; function:用来进行put的函数判断,可以进行复杂逻辑,在函数中return false/true来判断是否放入。

(2)sort:boolean 定义是否列表单元是否可以在列表容器内进行拖拽排序;

(3)delay:number 定义鼠标选中列表单元可以开始拖动的延迟时间;

(4)disabled:boolean 定义是否此sortable对象是否可用,为true时sortable对象不能拖放排序等功能,为false时为可以进行排序,相当于一个开关;

(5)animation:number 单位:ms,定义排序动画的时间;

(6)handle:selector 格式为简单css选择器的字符串,使列表单元中符合选择器的元素成为拖动的手柄,只有按住拖动手柄才能使列表单元进行拖动;

**(7)filter:**selector 格式为简单css选择器的字符串,定义哪些列表单元不能进行拖放,可设置为多个选择器,中间用“,”分隔;

(8)draggable:selector 格式为简单css选择器的字符串,定义哪些列表单元可以进行拖放

(9)ghostClass:selector 格式为简单css选择器的字符串,当拖动列表单元时会生成一个副本作为影子单元来模拟被拖动单元排序的情况,此配置项就是来给这个影子单元添加一个class,我们可以通过这种方式来给影子元素进行编辑样式;

(10)chosenClass:selector 格式为简单css选择器的字符串,当选中列表单元时会给该单元增加一个class;

(11)forceFallback:boolean 如果设置为true时,将不使用原生的html5的拖放,可以修改一些拖放中元素的样式等;

(12)fallbackClass:string 当forceFallback设置为true时,拖放过程中鼠标附着单元的样式;

(13)scroll:boolean 默认为true,当排序的容器是个可滚动的区域,拖放可以引起区域滚动。

2.事件

onChoose:function 列表单元被选中的回调函数

onStart:function 列表单元拖动开始的回调函数

onEnd:function 列表单元拖放结束后的回调函数

onAdd:function 列表单元添加到本列表容器的回调函数

onUpdate:function 列表单元在列表容器中的排序发生变化后的回调函数

onRemove:function 列表元素移到另一个列表容器的回调函数

onFilter:function 试图选中一个被filter过滤的列表单元的回调函数

onMove:function 当移动列表单元在一个列表容器中或者多个列表容器中的回调函数

onClone:function 当创建一个列表单元副本的时候的回调函数

3.事件对象

事件对象在各个函数中略有不同,可通过输出对象查看对象的属性,下面简单列举几个:

to:HTMLElement–移动到列表容器

from:HTMLElement–来源的列表容器

item:HTMLElement–被移动的列表单元

clone:HTMLElement–副本的列表单元

oldIndex:number/undefined–在列表容器中的原序号

newIndex:number/undefined–在列表容器中的新序号

4.方法

option(name[,value])
获得或者设置项参数,使用方法类似于jQuery用法,没有第二个参数为获得option中第一个参数所对应的值,有第二个参数时,将重新赋给第一个参数所对应的值;

closest
没理解

toArray()
序列化可排序的列表单元的data-id(可通过配置项中dataIdAttr修改)放入一个数组,并返回这个数组中

sort()
通过自定义列表单元的data-id的数组对列表单元进行排序

save()
destroy()

四、实战应用

1.Vue先把数据渲染到页面上;

2.利用sortablejs操作真实dom,得到列表,sortablejs 核心就是操作真实dom,这时候由于vue本身数据未更新,所以也不会触发dom的重新渲染,这就导致了vue里面的数据与真实dom的数据是对不上的,所以有了第3步;

3.利用sortablejs的onEnd方法把数据变化映射到真实的vue的数据源list上,实现拖拽时dom变化是对应的。

环境如下:
在这里插入图片描述

1、简单列表拖拽

<script setup lang="ts">
import Sortable from 'sortablejs'
import { ref, onMounted, nextTick } from 'vue';

const sortableRef = ref(null)
const list = [
  {
    name: 'item1'
  },
  {
    name: 'item2'
  },
  {
    name: 'item3'
  },
  {
    name: 'item4'
  },
  {
    name: 'item5'
  },
  {
    name: 'item6'
  }
]

const initSortable = () => {
  new Sortable(sortableRef.value, {
      delay: 10,
      animation: 150,
      // 如果有不想排序的,在这里按照class匹配的方式写出即可
      filter: '.demo-title',
      // 需要拖拽的标签的class,强烈推荐写
      draggable: '.demo-item',
      // drop placeholder的css类名
      ghostClass: 'blue-background-class'
  });
}

onMounted(() => {
  nextTick(() => {
    initSortable()
  })
})
</script>

<template>
  <ul ref="sortableRef" class="demo">
    <li class="demo-title">Demo</li>
    <li class="demo-item" v-for="item in list" :key="item.name">{{ item.name }}</li>
  </ul>
</template>

<style lang="scss" scoped>
.demo {
  list-style: none;
  width: 40%;
  margin: 200px auto 0;
  .demo-title {
    text-align: center;
    font-weight: 600;
    font-size: 16px;
  }
  .demo-item {
    border: 1px solid red;
    margin: 10px 0;
    padding: 10px 0;
    text-align: center;
  }
}
.blue-background-class {
  background-color: #1890ff;
}
</style>

效果如下:
在这里插入图片描述

2、多列表相互拖拽

<script setup lang="ts">
import Sortable from 'sortablejs'
import { ref, onMounted, nextTick } from 'vue';

const demo1Ref = ref(null)
const demo2Ref = ref(null)

const initSortable = () => {
  new Sortable(demo1Ref.value, {
    // 相互拖拽列表的组名必须一样
    group: 'shared',
    delay: 10,
    animation: 150,
    // 需要拖拽的标签的class,强烈推荐写
    // 拖拽元素的类名一样,否则其它列表拖过来的不能在当前列表拖动
    draggable: '.demo-item'
  });

  new Sortable(demo2Ref.value, {
    // 相互拖拽列表的组名必须一样
    group: 'shared',
    delay: 10,
    animation: 150,
    // 需要拖拽的标签的class,强烈推荐写
    // 拖拽元素的类名一样,否则其它列表拖过来的不能在当前列表拖动
    draggable: '.demo-item'
  });
}

onMounted(() => {
  nextTick(() => {
    initSortable()
  })
})
</script>

<template>
  <div class="demo-container">
    <ul ref="demo1Ref" class="demo">
      <li class="demo-item demo1-item" v-for="item in 6" :key="'demo1'+item">item{{ item }}</li>
    </ul>
    <ul ref="demo2Ref" class="demo">
      <li class="demo-item demo2-item" v-for="item in 6" :key="'demo2'+item">item{{ item }}</li>
    </ul>
  </div>
</template>

<style lang="scss" scoped>
.demo-container {
  display: flex;
  justify-content: space-between;
  width: 1000px;
  .demo {
    list-style: none;
    width: 48%;
    .demo-item {
      margin: 10px 0;
      padding: 10px 0;
      text-align: center;
    }
    .demo1-item {
      background-color: #5ac8fa;
    }
    .demo2-item {
      background-color: #c0ca33;
    }
  }
}
</style>        

效果如下:
图片

3、克隆(通过拖拽复制节点)

new Sortable(demo1Ref.value, {
  group: {
    name: 'shared',
    pull: 'clone' // To clone: set pull to 'clone'
  },
  delay: 10,
  animation: 150,
  // 需要拖拽的标签的class,强烈推荐写
  // 拖拽元素的类名一样,否则其它列表拖过来的不能在当前列表拖动
  draggable: '.demo-item'
});

new Sortable(demo2Ref.value, {
  group: {
    name: 'shared',
    pull: 'clone' // To clone: set pull to 'clone'
  },
  delay: 10,
  animation: 150,
  // 需要拖拽的标签的class,强烈推荐写
  // 拖拽元素的类名一样,否则其它列表拖过来的不能在当前列表拖动
  draggable: '.demo-item'
});

效果如下:

图片
4、禁止sorting

坐标的列表无法进行排序,因为设置了禁止sort,但是你还是可以从左边拖拽到右边。

new Sortable(demo1Ref.value, {
  group: {
    name: 'shared',
    pull: 'clone',
    put: false // 不允许拖拽进这个列表
  },
  sort: false, // 设为false,禁止sort
  delay: 10,
  animation: 150,
  // 需要拖拽的标签的class,强烈推荐写
  // 拖拽元素的类名一样,否则其它列表拖过来的不能在当前列表拖动
  draggable: '.demo-item'
});

new Sortable(demo2Ref.value, {
  group: 'shared',
  delay: 10,
  animation: 150,
  // 需要拖拽的标签的class,强烈推荐写
  // 拖拽元素的类名一样,否则其它列表拖过来的不能在当前列表拖动
  draggable: '.demo-item'
});

效果如下:

在这里插入图片描述

5、Handle

使列表单元中符合选择器的元素成为拖动的手柄,只有按住拖动手柄才能使列表单元进行拖动。在面代码中只有按住白色方块才能拖动元素。

<script setup lang="ts">
import Sortable from 'sortablejs'
import { ref, onMounted, nextTick } from 'vue';

const sortableRef = ref(null)

const initSortable = () => {
  new Sortable(sortableRef.value, {
    handle: '.handle-draggabel',
    animation: 150,
  });
}

onMounted(() => {
  nextTick(() => {
    initSortable()
  })
})
</script>

<template>
  <ul ref="sortableRef" class="demo">
    <li class="demo-item" v-for="item in 6" :key="item">
      <span class="handle-draggabel"></span>
      <span>item{{ item }}</span>
    </li>
  </ul>
</template>

<style lang="scss" scoped>
.demo {
  list-style: none;
  width: 40%;
  .demo-item {
    background-color: #1890ff;
    margin: 10px 0;
    padding: 10px 0;
    color: #fff;
    text-align: center;
    .handle-draggabel {
      display: inline-block;
      width: 14px;
      height: 14px;
      background-color: #fff;
      margin-right: 10px;
      cursor: pointer;
    }
  }
}
</style>

效果如下:

图片

五、总结

除了基本的拖放功能外,SortableJS 还提供了许多额外的功能和选项,例如拖放动画、排序同步、多选模式等。这些功能可以帮助您创建更加丰富和用户友好的交互体验。

SortableJS 的社区非常活跃,许多开发者使用该库并为其贡献插件和示例。这意味着您可以找到许多现成的解决方案和资源,以帮助您解决在开发中遇到的问题。

总的来说,SortableJS 是一个强大、灵活且易于使用的 JavaScript 库,适用于各种类型的拖放排序需求。无论是简单的列表排序还是复杂的交互式应用程序,SortableJS 都能够帮助您快速实现所需的功能。如果您正在寻找一个可靠的拖放库来增强您的网页或应用程序的交互性,SortableJS 是一个值得考虑的选择。

文档地址:http://www.sortablejs.com/index.html

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

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

相关文章

广联达Linkworks DataExchange.ashx XXE漏洞复现

0x01 产品简介 广联达 LinkWorks(也称为 GlinkLink 或 GTP-LinkWorks)是广联达公司(Glodon)开发的一种BIM(建筑信息模型)协同平台。广联达是中国领先的数字建造技术提供商之一,专注于为建筑、工程和建筑设计行业提供数字化解决方案。 0x02 漏洞概述 广联达 LinkWorks …

如何使用HadSky搭配内网穿透工具搭建本地论坛并发布至公网可远程访问

目录 前言 1. 网站搭建 1.1 网页下载和安装 1.2 网页测试 1.3 cpolar的安装和注册 2. 本地网页发布 2.1 Cpolar临时数据隧道 2.2 Cpolar稳定隧道&#xff08;云端设置&#xff09; 2.3 Cpolar稳定隧道&#xff08;本地设置&#xff09; 2.4 公网访问测试 总结 前言 …

影视仓最新配置接口2024tvbox源配置地址

影视仓是在TVBox开源代码基础上开发的优质版本&#xff0c;安装后需要配置接口才能正常使用。影视仓"内置版"是开发者做的资源内置化修改版本&#xff0c;不用自行设置接口&#xff0c;安装后即可使用。 影视仓的接口配置方法与TVBOX一样&#xff0c;区别在于影视仓…

算法第十四天-删除有序数组中的重复项

删除有序数组中的重复项 题目要求 解题思路 双指针 左指针确定不重复值&#xff0c;右指针遍历数组 代码 class Solution:def removeDuplicates(self, nums: List[int]) -> int:left0for right in range(1,len(nums)):if nums[left] ! nums[right]:left 1nums[left] nu…

快速指南:原型图的基础知识解析

什么是原型图 一般来说&#xff0c;原型图是指用于呈现软件产品功能界面、交互设计和逻辑过程的设计项目。您还可以将原型图理解为软件的草图&#xff0c;可以通过原型图清楚地说明软件的功能、几个界面、每个功能的功能以及每个界面的流通关系。 原型图中的组成内容不是固定…

Java知识点:泛型、类加载器、内部类、可变参数

文章目录 1、this关键字2、泛型2.1 泛型介绍2.2 泛型分类定义2.2.1 泛型类2.2.2 泛型方法2.2.3 泛型接口 2.3 泛型通配符 3、可变参数4、日志4.1 使用步骤4.2 日志级别4.3 配置文件 5、类加载器5.1 类加载器5.2 类加载的完整过程5.2.1 类加载时机5.2.2 类加载过程 5.3 类加载的…

密码学:一文读懂非对称加密算法 DH、RSA

文章目录 前言非对称加密算法的由来非对称加密算法的家谱1.基于因子分解难题2.基于离散对数难题 密钥交换算法-DH密钥交换算法-DH的通信模型初始化DH算法密钥对甲方构建DH算法本地密钥乙方构建DH算法本地密钥DH算法加密消息传递 典型非对称加密算法-RSARSA的通信模型RSA特有的的…

消除代码冗长神器 - Lombok | @EqualsAndHashCode/@ToString注解详解

🤷 场景 Java 中所有对象的父类都是 Object 类,而 Object 类中会有默认的 equals/hashCode/toString 方法,但是有时候,这些方法需要子类去 Override。 😎 IDE 解决方案 很多 IDE 中内置了生成 equals、hashCode、toString 的功能,下面以 IDEA 为例。在类中,按 Alt …

使用openssl 生成pfx格式证书时报错:unable to load certificates

问题现象包如下&#xff1a; 之前在centos上使用openssl部署证书服务器以及颁发证书的时候遇到的问题&#xff0c;在进行个人证书生成之后需要形成pfx格式证书&#xff0c;结果过程中报错了。网上类似资料比较少&#xff0c;做个记录。 生成pfx格式证书的命令&#xff1a; o…

2022年多元统计分析期末试题

2023年多元统计分析期末试题 1.试论述系统聚类、动态聚类和有序聚类的异同之处。 2、设 X {X} X~ N 3 {N_3} N3​(μ&#xff0c;Σ)&#xff0c;其中 X {X} X ~ ( X 1 {X_1} X1​, X 2 {X_2} X2​, X 3 {X_3} X3​)&#xff0c;μ (1,-2,3)‘&#xff0c;Σ [ 1 1 1 1 3 2…

猫长期吃猫粮好吗?主食冻干猫粮那种好吃又健康

许多铲屎官可能认为&#xff0c;只需给猫咪喂食猫粮就足够了。然而&#xff0c;猫咪实际上是肉食动物&#xff0c;对蛋白质的需求非常高。冻干猫粮采用低温真空干燥处理技术&#xff0c;将鲜肉经过预冻、升华、解析三个过程&#xff0c;去除水分的同时保持蛋白质等营养物质不变…

C++模板——(2)函数模板的声明和使用

归纳编程学习的感悟&#xff0c; 记录奋斗路上的点滴&#xff0c; 希望能帮到一样刻苦的你&#xff01; 如有不足欢迎指正&#xff01; 共同学习交流&#xff01; &#x1f30e;欢迎各位→点赞 &#x1f44d; 收藏⭐ 留言​&#x1f4dd; 勤奋&#xff0c;机会&#xff0c;&am…

小狗避障Scratch-第14届蓝桥杯Scratch省赛真题第4题

4. 小狗避障&#xff08;60分&#xff09; 评判标准&#xff1a; 5分&#xff1a;满足"具体要求"中的1&#xff09;&#xff1b; 5分&#xff1a;满足"具体要求"中的2&#xff09;&#xff1b; 10分&#xff1a;满足"具体要求"中的3&#xff…

程序员必知!迭代器模式的实战应用与案例分析

迭代器模式提供了遍历聚合对象中各元素的方法&#xff0c;通过它无需了解其底层结构&#xff0c;例如&#xff0c;在电商平台商品列表中统计销售额时&#xff0c;可通过迭代器简化遍历过程&#xff0c;加总每个商品销售额&#xff0c;此模式使代码更简洁、易维护&#xff0c;且…

LeetCode-移动零(283)

题目描述&#xff1a; 给定一个数组 nums&#xff0c;编写一个函数将所有 0 移动到数组的末尾&#xff0c;同时保持非零元素的相对顺序。 请注意 &#xff0c;必须在不复制数组的情况下原地对数组进行操作。 思路&#xff1a; 这里的思路跟以前做过的去重复数字的思路有点像&…

整合事务,名词,概念

mysql实例(instance): MySQL是单进程多线程&#xff0c;也就是说MySQL实例在系 统上表现就是一个服务进程&#xff0c;即进程,就是我们在自己电脑布了一个mysql实例(服务),然后我们在代码中就可以通过配上mysql实例的地址,就能连上自己电脑上的这mysql实例. 数据库database: …

Vue框架底层

一、前端框架的由来 1、服务端渲染 sequenceDiagram 浏览器->>服务器: https://www.bilibili.com/ Note right of 服务器: 组装页面(服务端渲染) 服务器->>-浏览器: 完整页面2、前后端分离 sequenceDiagram 浏览器->>服务器: https://www.bilibili.com/ 服务…

Linux文件系统和日志分析

一、inode表结构 1. inode表 inode号在同一个设备上是唯一的。 inode号是有限资源&#xff0c;它的大小和磁盘大小有关。 访问文件的基本流程 根据文件夹的文件名和inode号的关系找到对应的inode表&#xff0c;再根据inode表&#xff08;属主 属组&#xff09;当中的指针找到磁…

毛概笔记。

一、 毛泽东思想是马中化的第一果&#xff0c;是关于搞革命&#xff0c;搞改造&#xff0c;搞建设的理论。 二、新民主主义革命 新民主主义革命的三大法宝&#xff1a;1.统一战线 2. 武装斗争 3.党的建设 政治纲领 经济纲领 文化纲领 乱世造英雄 三、社会主义改造理论&#xff…

多类指针式仪表自动读数系统的LabVIEW开发应用案例

多类指针式仪表自动读数系统的LabVIEW开发应用案例 工业环境中&#xff0c;多类指针式仪表的自动读数一直是一个具有挑战性的问题。本案例旨在展示如何使用LabVIEW开发一个高度智能化的多类指针式仪表自动读数系统&#xff0c;以应对复杂的工业环境。通过结合图像处理技术和深…