Vue.Draggable學(xué)習(xí)總結(jié)

Draggable為基于Sortable.js的vue組件峦耘,用以實現(xiàn)拖拽功能。

特性

支持觸摸設(shè)備
支持拖拽和選擇文本
支持智能滾動
支持不同列表之間的拖拽
不以jQuery為基礎(chǔ)
和視圖模型同步刷新
和vue2的國度動畫兼容
支持撤銷操作
當需要完全控制時旅薄,可以拋出所有變化
可以和現(xiàn)有的UI組件兼容

安裝

npm install vuedraggable

引入

import draggable from 'vuedraggable'

官方例子:
hello.vue

<template>
  <div class="fluid container">
    <div class="form-group form-group-lg panel panel-default">
      <div class="panel-heading">
        <h3 class="panel-title">Sortable control</h3>
      </div>
      <div class="panel-body">
        <div class="checkbox">
          <label><input type="checkbox" v-model="editable">Enable drag and drop</label>
        </div>
        <button type="button" class="btn btn-default" @click="orderList">Sort by original order</button>
      </div>
    </div>

    <div class="col-md-3">
      <draggable class="list-group" element="ul" v-model="list" :options="dragOptions" :move="onMove" @start="isDragging=true" @end="isDragging=false">
        <transition-group type="transition" :name="'flip-list'">
          <li class="list-group-item" v-for="element in list" :key="element.order">
            <i :class="element.fixed? 'fa fa-anchor' : 'glyphicon glyphicon-pushpin'" @click=" element.fixed=! element.fixed" aria-hidden="true"></i>
            {{element.name}}
            <span class="badge">{{element.order}}</span>
          </li>
        </transition-group>
      </draggable>
    </div>

    <div class="col-md-3">
      <draggable element="span" v-model="list2" :options="dragOptions" :move="onMove">
        <transition-group name="no" class="list-group" tag="ul">
          <li class="list-group-item" v-for="element in list2" :key="element.order">
            <i :class="element.fixed? 'fa fa-anchor' : 'glyphicon glyphicon-pushpin'" @click=" element.fixed=! element.fixed" aria-hidden="true"></i>
            {{element.name}}
            <span class="badge">{{element.order}}</span>
          </li>
        </transition-group>
      </draggable>
    </div>

    <div class="list-group col-md-3">
      <pre>{{listString}}</pre>
    </div>
    <div class="list-group col-md-3">
      <pre>{{list2String}}</pre>
    </div>
  </div>
</template>

<script>
import draggable from "vuedraggable";
const message = [
  "vue.draggable",
  "draggable",
  "component",
  "for",
  "vue.js 2.0",
  "based",
  "on",
  "Sortablejs"
];

export default {
  name: "hello",
  components: {
    draggable
  },
  data() {
    return {
      list: message.map((name, index) => {
        return { name, order: index + 1, fixed: false };
      }),
      list2: [],
      editable: true,
      isDragging: false,
      delayedDragging: false
    };
  },
  methods: {
    orderList() {
      this.list = this.list.sort((one, two) => {
        return one.order - two.order;
      });
    },
    onMove({ relatedContext, draggedContext }) {
      const relatedElement = relatedContext.element;
      const draggedElement = draggedContext.element;
      return (
        (!relatedElement || !relatedElement.fixed) && !draggedElement.fixed
      );
    }
  },
  computed: {
    dragOptions() {
      return {
        animation: 0,
        group: "description",
        disabled: !this.editable,
        ghostClass: "ghost"
      };
    },
    listString() {
      return JSON.stringify(this.list, null, 2);
    },
    list2String() {
      return JSON.stringify(this.list2, null, 2);
    }
  },
  watch: {
    isDragging(newValue) {
      if (newValue) {
        this.delayedDragging = true;
        return;
      }
      this.$nextTick(() => {
        this.delayedDragging = false;
      });
    }
  }
};
</script>

<style>
.flip-list-move {
  transition: transform 0.5s;
}

.no-move {
  transition: transform 0s;
}

.ghost {
  opacity: 0.5;
  background: #c8ebfb;
}

.list-group {
  min-height: 20px;
}

.list-group-item {
  cursor: move;
}

.list-group-item i {
  cursor: pointer;
}
</style>

main.js

import Vue from "vue";
import App from "./App.vue";
import "bootstrap/dist/css/bootstrap.css";
import "font-awesome/less/font-awesome.less";

Vue.config.productionTip = false;

new Vue({
  render: h => h(App)
}).$mount("#app");

屬性和方法說明

屬性

value

Array辅髓,非必須,默認為null

用于實現(xiàn)拖拽的list少梁,通常和內(nèi)部v-for循環(huán)的數(shù)組為同一數(shù)組洛口。
最好使用vuex來實現(xiàn)傳入。
不是直接使用凯沪,而是通過v-model引入第焰。

<draggable v-model="myArray">
list

Array,非必須妨马,默認為null

就是value的替代品挺举。
和v-model不能共用
從表現(xiàn)上沒有看出不同

element

String杀赢,默認div

就是<draggable>標簽在渲染后展現(xiàn)出來的標簽類型
也是包含拖動列表和插槽的外部標簽
可以用來兼容UI組件

options

Object

配置項
group: string or array 分組用的,同一組的不同list可以相互拖動
sort: boolean 定義是否可以拖拽
delay:number 定義鼠標選中列表單元可以開始拖動的延遲時間
touchStartThreshold:number (不清楚)
disabled: boolean 定義是否此sortable對象是否可用湘纵,為true時sortable對象不能拖放排序等功能
store:
animation: umber 單位:ms 動畫時間
handle: selector 格式為簡單css選擇器的字符串脂崔,使列表單元中符合選擇器的元素成為拖動的手柄,只有按住拖動手柄才能使列表單元進行拖動
filter: selector 格式為簡單css選擇器的字符串梧喷,定義哪些列表單元不能進行拖放脱篙,可設(shè)置為多個選擇器,中間用“伤柄,”分隔
preventOnFilter: 當拖動filter時是否觸發(fā)event.preventDefault()默認觸發(fā)
draggable: selector 格式為簡單css選擇器的字符串绊困,定義哪些列表單元可以進行拖放
ghostClass: selector 格式為簡單css選擇器的字符串,當拖動列表單元時會生成一個副本作為影子單元來模擬被拖動單元排序的情況适刀,此配置項就是來給這個影子單元添加一個class秤朗,我們可以通過這種方式來給影子元素進行編輯樣式
chosenClass: selector 格式為簡單css選擇器的字符串,目標被選中時添加
dragClass:selector 格式為簡單css選擇器的字符串笔喉,目標拖動過程中添加
forceFallback: boolean 如果設(shè)置為true時取视,將不使用原生的html5的拖放,可以修改一些拖放中元素的樣式等
fallbackClass: string 當forceFallback設(shè)置為true時常挚,拖放過程中鼠標附著單元的樣式
dataIdAttr: data-id
scroll:boolean當排序的容器是個可滾動的區(qū)域作谭,拖放可以引起區(qū)域滾動
scrollFn:function(offsetX, offsetY, originalEvent, touchEvt, hoverTargetEl) { … } 用于自定義滾動條的適配
scrollSensitivity: number 就是鼠標靠近邊緣多遠開始滾動默認30
scrollSpeed: number 滾動速度

函數(shù)配置

setData: 設(shè)置值時的回調(diào)函數(shù)
onChoose: 選擇單元時的回調(diào)函數(shù)
onStart: 開始拖動時的回調(diào)函數(shù)
onEnd: 拖動結(jié)束時的回調(diào)函數(shù)
onAdd: 添加單元時的回調(diào)函數(shù)
onUpdate: 排序發(fā)生變化時的回調(diào)函數(shù)
onRemove: 單元被移動到另一個列表時的回調(diào)函數(shù)
onFilter: 嘗試選擇一個被filter過濾的單元的回調(diào)函數(shù)
onMove: 移動單元時的回調(diào)函數(shù)
onClone: clone時的回調(diào)函數(shù)
以上函數(shù)對象的屬性:
to: 移動到的列表的容器
from:來源列表容器
item: 被移動的單元
clone: 副本的單元
oldIndex:移動前的序號
newIndex:移動后的序號

clone

function,默認值: 無處理

這一項要配合著options的group項的pull項處理,當pull:'clone時的拖拽的回調(diào)函數(shù)’
就是克隆的意思奄毡。
可以理解為正常的拖拽變成了復(fù)制折欠。
當為true時克隆

move

function,默認值:null

就是拖拽項時調(diào)用的函數(shù)
用來確定拖拽是否生效
返回null時可以生效
可以通過函數(shù)判斷
有一個參數(shù):evt
evt為object
draggedContext: 被拖拽元素的上下文
index:拖拽元素的指針
element: 拖拽數(shù)據(jù)本身
futureIndex: 拖動后的index
relatedContext: 拖入?yún)^(qū)域的上下文
index: 目標元素的index
element:目標數(shù)據(jù)本身
list: 拖入的列表
component:目標組件

<draggable element="ul" v-model="list" :move='allow'>
...
methods: {
  allow(evt) {
    console.log(evt.draggedContext.index)
    console.log(evt.draggedContext.element)
    console.log(evt.draggedContext.futureIndex)
    console.log(evt.relatedContext.index)
    console.log(evt.relatedContext.element)
    console.log(evt.relatedContext.list)
    console.log(evt.relatedContext.component)
    return (evt.draggedContext.element.name!== 'b')
  }
}

componentData

Object,默認值:null

用來結(jié)合UI組件的,可以理解為代理了UI組件的定制信息
包含兩項:props和on
props用來代理UI組件需要綁定的屬性(:)
on用來代理UI組件需要綁定的事件(@)

<draggable element="el-collapse" :list="list" :component-data="getComponentData()">
  <el-collapse-item v-for="e in list" :title="e.title" :name="e.name" :key="e.name">
    <div>{{e.description}}</div>
   </el-collapse-item>
</draggable>
methods: {
  handleChange() {
    console.log('changed');
  },
  inputChanged(value) {
    this.activeNames = value;
  },
  getComponentData() {
    return {
      on: {
        change: this.handleChange,
        input: this.inputChanged
      },
      props: {
        value: this.activeNames
      }
    };
  }
}

事件

有以下幾種
start, add, remove, update, end, choose, sort, filter, clone

參數(shù)帶有如下屬性:

add: 包含被添加到列表的元素
newIndex: 添加后的新索引
element: 被添加的元素
removed: 從列表中移除的元素
oldIndex: 移除前的索引
element: 被移除的元素
moved:內(nèi)部移動的
newIndex: 改變后的索引
oldIndex: 改變前的索引
element: 被移動的元素
插槽
提供一個footer插槽吼过,在排序列表之下锐秦。
永遠位于最下方。

<draggable v-model="myArray" :options="{draggable:'.item'}">
    <div v-for="element in myArray" :key="element.id" class="item">
        {{element.name}}
    </div>
    <button slot="footer" @click="addPeople">Add</button>
</draggable>
500575091.jpg
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末盗忱,一起剝皮案震驚了整個濱河市酱床,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌趟佃,老刑警劉巖扇谣,帶你破解...
    沈念sama閱讀 217,185評論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異闲昭,居然都是意外死亡罐寨,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,652評論 3 393
  • 文/潘曉璐 我一進店門汤纸,熙熙樓的掌柜王于貴愁眉苦臉地迎上來衩茸,“玉大人,你說我怎么就攤上這事±愦龋” “怎么了幔烛?”我有些...
    開封第一講書人閱讀 163,524評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長囊蓝。 經(jīng)常有香客問我饿悬,道長,這世上最難降的妖魔是什么聚霜? 我笑而不...
    開封第一講書人閱讀 58,339評論 1 293
  • 正文 為了忘掉前任狡恬,我火速辦了婚禮,結(jié)果婚禮上蝎宇,老公的妹妹穿的比我還像新娘弟劲。我一直安慰自己,他們只是感情好姥芥,可當我...
    茶點故事閱讀 67,387評論 6 391
  • 文/花漫 我一把揭開白布兔乞。 她就那樣靜靜地躺著,像睡著了一般凉唐。 火紅的嫁衣襯著肌膚如雪庸追。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,287評論 1 301
  • 那天台囱,我揣著相機與錄音淡溯,去河邊找鬼。 笑死簿训,一個胖子當著我的面吹牛咱娶,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播煎楣,決...
    沈念sama閱讀 40,130評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼豺总,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了择懂?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,985評論 0 275
  • 序言:老撾萬榮一對情侶失蹤另玖,失蹤者是張志新(化名)和其女友劉穎困曙,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體谦去,經(jīng)...
    沈念sama閱讀 45,420評論 1 313
  • 正文 獨居荒郊野嶺守林人離奇死亡慷丽,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,617評論 3 334
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了鳄哭。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片要糊。...
    茶點故事閱讀 39,779評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖妆丘,靈堂內(nèi)的尸體忽然破棺而出锄俄,到底是詐尸還是另有隱情局劲,我是刑警寧澤,帶...
    沈念sama閱讀 35,477評論 5 345
  • 正文 年R本政府宣布奶赠,位于F島的核電站鱼填,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏毅戈。R本人自食惡果不足惜苹丸,卻給世界環(huán)境...
    茶點故事閱讀 41,088評論 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望苇经。 院中可真熱鬧赘理,春花似錦、人聲如沸扇单。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,716評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽令花。三九已至阻桅,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間兼都,已是汗流浹背嫂沉。 一陣腳步聲響...
    開封第一講書人閱讀 32,857評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留扮碧,地道東北人趟章。 一個月前我還...
    沈念sama閱讀 47,876評論 2 370
  • 正文 我出身青樓,卻偏偏與公主長得像慎王,于是被迫代替她去往敵國和親蚓土。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 44,700評論 2 354