项目搭建

  • vue-cli
  • element-ui
  • vuedraggable

    vuedraggable 拖拽组件使用

    vuedraggable 是基于Sortable.js 的 vue 组件库,没有 jQuery 依赖,可以实现视图和数据模型同步更新,并且拥有丰富的 API

src/components/ 目录下新建 Draggable.vue

  1. <template>
  2. <draggable
  3. class="list-group"
  4. tag="ul"
  5. v-model="list"
  6. v-bind="{
  7. animation: 200,
  8. group: 'description',
  9. disabled: false,
  10. ghostClass: 'ghost'
  11. }"
  12. >
  13. <li class="list-group-item" v-for="element in list" :key="element.order">
  14. {{ element.name }}
  15. </li>
  16. </draggable>
  17. </template>
  18. <script>
  19. import Draggable from 'vuedraggable';
  20. const message = [
  21. 'vue.draggable',
  22. 'draggable',
  23. 'component',
  24. 'for',
  25. 'vue.js 2.0',
  26. 'based',
  27. 'on',
  28. 'Sortablejs',
  29. ];
  30. export default {
  31. components: {
  32. Draggable,
  33. },
  34. data() {
  35. return {
  36. list: message.map((name, index) => {
  37. return { name, order: index + 1 };
  38. }),
  39. };
  40. },
  41. };
  42. </script>
  43. <style lang="scss">
  44. .ghost {
  45. opacity: 0.5;
  46. background: #c8ebfb;
  47. }
  48. .list-group {
  49. min-height: 20px;
  50. list-style: none;
  51. }
  52. .list-group-item {
  53. cursor: move;
  54. height: 30px;
  55. line-height: 30px;
  56. border: 1px solid #ccc;
  57. }
  58. </style>

tag=”ul” 用来指定 draggable 组件渲染出来的 html 标签。
v-model 绑定列表可拖动元素,通常与内部元素 v-for 引用的数组相同。
v-bind 绑定组件的配置项,与 Sortable.js 的配置项相同,下面具体讲解:

  • group:string or object
    • string:命名,用处是为了设置可以拖放容器时使用
    • 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 来判断是否放入
  • animation: number 单位:ms,定义动画的时间;
  • disabled: boolean 定义此 sortable 对象是否可用,为 true 时 sortable 对象不能拖放排序等功能,为 false 时为可以进行排序,相当于一个开关;
  • ghostClass:selector 格式为简单 css 选择器的字符串,当拖动列表元素时会生成一个副本作为影子元素来模拟被拖动元素排序的情况,此配置项就是来给这个影子元素添加一个 class,我们可以通过这种方式来给影子元素进行编辑样式;
  • sort: boolean 定义是否列表元素是否可以在列表容器内进行拖拽排序;
  • delay: number 定义鼠标选中列表元素可以开始拖动的延迟时间;
  • handle: selector 格式为简单 css 选择器的字符串,使列表元素中符合选择器的元素成为拖动的手柄,只有按住拖动手柄才能使列表元素进行拖动;
  • filter: selector 格式为简单 css 选择器的字符串,定义哪些列表元素不能进行拖放,可设置为多个选择器,中间用“,”分隔
  • draggable:selector 格式为简单 css 选择器的字符串,定义哪些列表元素可以进行拖放
  • chosenClass:selector 格式为简单 css 选择器的字符串,当选中列表元素时会给该元素增加一个 class;
  • forceFallback:boolean 如果设置为 true 时,将不使用原生的 html5 的拖放,可以修改一些拖放中元素的样式等;
  • fallbackClass:string 当 forceFallback 设置为 true 时,拖放过程中鼠标附着元素的样式;
  • scroll:boolean 默认为 true,当排序的容器是个可滚动的区域,拖放可以引起区域滚动

修改 src/App.vue

  1. <template>
  2. <div id="app">
  3. <draggable></draggable>
  4. </div>
  5. </template>
  6. <script>
  7. import Draggable from './components/Draggable';
  8. export default {
  9. name: 'app',
  10. components: {
  11. Draggable,
  12. },
  13. };
  14. </script>

src/components/ 目录下新建 DraggableAdvance.vue

  1. <template>
  2. <el-row :gutter="50">
  3. <el-col :span="6">
  4. <h3>Draggable 1</h3>
  5. <draggable
  6. class="list-group"
  7. tag="ul"
  8. v-model="list1"
  9. v-bind="dragOptions"
  10. >
  11. <li class="list-group-item" v-for="element in list1" :key="element.id">
  12. {{ element.name }}
  13. </li>
  14. </draggable>
  15. </el-col>
  16. <el-col :span="6">
  17. <h3>Draggable 2</h3>
  18. <draggable
  19. class="list-group"
  20. tag="ul"
  21. v-model="list2"
  22. v-bind="dragOptions"
  23. >
  24. <li class="list-group-item" v-for="element in list2" :key="element.id">
  25. {{ element.name }}
  26. </li>
  27. </draggable>
  28. </el-col>
  29. <el-col :span="6">
  30. <h3>List 1</h3>
  31. <pre style="text-align: start;background: #f3f3f3;">
  32. {{JSON.stringify(list1, null, 2)}}</pre
  33. >
  34. </el-col>
  35. <el-col :span="6">
  36. <h3>List 2</h3>
  37. <pre style="text-align: start;background: #f3f3f3;">
  38. {{JSON.stringify(list2, null, 2)}}</pre
  39. >
  40. </el-col>
  41. </el-row>
  42. </template>
  43. <script>
  44. import Draggable from 'vuedraggable';
  45. export default {
  46. components: {
  47. Draggable,
  48. },
  49. data() {
  50. return {
  51. list1: [
  52. { name: 'Jesus', id: 1 },
  53. { name: 'Paul', id: 2 },
  54. { name: 'Peter', id: 3 },
  55. ],
  56. list2: [
  57. { name: 'Luc', id: 5 },
  58. { name: 'Thomas', id: 6 },
  59. { name: 'John', id: 7 },
  60. ],
  61. dragOptions: {
  62. animation: 200,
  63. group: 'people',
  64. disabled: false,
  65. ghostClass: 'ghost',
  66. },
  67. };
  68. },
  69. };
  70. </script>
  71. <style lang="scss">
  72. .ghost {
  73. opacity: 0.5;
  74. background: #c8ebfb;
  75. }
  76. .list-group {
  77. min-height: 20px;
  78. list-style: none;
  79. }
  80. .list-group-item {
  81. cursor: move;
  82. height: 30px;
  83. line-height: 30px;
  84. border: 1px solid #ccc;
  85. }
  86. </style>

修改 src/App.vue

  1. <template>
  2. <div id="app">
  3. <draggable-advance></draggable-advance>
  4. </div>
  5. </template>
  6. <script>
  7. import DraggableAdvance from './components/DraggableAdvance';
  8. export default {
  9. name: 'app',
  10. components: {
  11. DraggableAdvance,
  12. },
  13. };
  14. </script>

接下来我们让左边元素保持不变,拖拽到右边的时候自动添加一项,修改第一个拖拽组件的配置项,让其数组不会随着拖动而改变:
修改 DraggableAdvance.vue

  1. <template>
  2. <el-row :gutter="50">
  3. <el-col :span="6">
  4. <h3>Draggable 1</h3>
  5. <draggable
  6. class="list-group"
  7. tag="ul"
  8. v-model="list1"
  9. v-bind="dragOptions1"
  10. >
  11. <li class="list-group-item" v-for="element in list1" :key="element.id">
  12. {{ element.name }}
  13. </li>
  14. </draggable>
  15. </el-col>
  16. <el-col :span="6">
  17. <h3>Draggable 2</h3>
  18. <draggable
  19. class="list-group"
  20. tag="ul"
  21. v-model="list2"
  22. v-bind="dragOptions2"
  23. >
  24. <li class="list-group-item" v-for="element in list2" :key="element.id">
  25. {{ element.name }}
  26. </li>
  27. </draggable>
  28. </el-col>
  29. ...
  30. </el-row>
  31. </template>
  32. <script>
  33. import Draggable from 'vuedraggable';
  34. export default {
  35. components: {
  36. Draggable,
  37. },
  38. data() {
  39. return {
  40. // ...
  41. dragOptions1: {
  42. animation: 200,
  43. group: { name: 'people', pull: 'clone', put: false }, // 配置项
  44. disabled: false,
  45. ghostClass: 'ghost',
  46. },
  47. dragOptions2: {
  48. animation: 200,
  49. group: 'people',
  50. disabled: false,
  51. ghostClass: 'ghost',
  52. },
  53. };
  54. },
  55. };
  56. </script>

拖拽组件提供了如下事件:

  • onChoose:列表元素被选中的回调函数
  • onStart:列表元素拖动开始的回调函数
  • onEnd:列表元素拖放结束后的回调函数
  • onAdd:列表元素添加到本列表容器的回调函数
  • onUpdate:列表元素在列表容器中的排序发生变化后的回调函数
  • onRemove:列表元素移到另一个列表容器的回调函数
  • onFilter:试图选中一个被 filter 过滤的列表元素的回调函数
  • onMove:当移动列表元素在一个列表容器中或者多个列表容器中的回调函数
  • onClone:当创建一个列表元素副本的时候的回调函数

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

  • to:HTMLElement—移动到列表容器
  • from:HTMLElement—来源的列表容器
  • item:HTMLElement—被移动的列表元素
  • clone:HTMLElement—副本的列表元素
  • oldIndex:number/undefined—在列表容器中的原序号
  • newIndex:number/undefined—在列表容器中的新序号

打包

  1. "scripts": {
  2. "build-bundle": "vue-cli-service build --target lib --name FormMaking src/components/Container.vue"
  3. },

在 package.json 中修改配置信息,先来看看 package.json 中的配置项
必须带有的字段:

  • name :包名(全部小写,没有空格,可以使用下划线或者横线)
  • version: 版本

其他内容:

  • author:作者信息
  • main:程序入口文件,一般都是 index.js
  • description:描述信息,有助于搜索
  • keywords: 关键字,有助于在人们使用 npm search 搜索时发现你的项目
  • scripts:支持的脚本,默认是一个空的 test
  • license:默认是 MIT
  • bugs:当前项目的一些错误信息,如果有的话
  • dependencies:在生产环境中需要用到的依赖
  • devDependencies:在开发、测试环境中用到的依赖
  • repository:代码仓库
    1. {
    2. "name": "form-making-course",
    3. "version": "0.1.0",
    4. "description": "form-making表单设计器课程",
    5. "private": false,
    6. "main": "dist/FormMaking.common.js"
    7. }