value和list
這兩個都可以給一個draggable注入數據源:
/*value注入數據源*/
<draggable v-model="list" ></draggable>
export default {
data() {
return {
list:[{
name:'aaa',id:1,
},{
name:'bbb',id:2,
}]
};
}
}
/*list注入數據源頭*/
<draggable :list="list" ></draggable>
export default {
data() {
return {
list:[{
name:'aaa',id:1,
},{
name:'bbb',id:2,
}]
};
}
}
它們的區別是:value注入的,如果發生了拖拽,value的數據並不會跟着變化,list注入的,則會發生變化。
也就是說value注入的,后續有無變化都和數據體沒關系,它用於只需要展示拖拽效果的地方;list注入的,數據體和當前頁面上的屬性是保持一致的,頁面上的順序變了,內部數組對應的結構體數組的順序也會重新排列,和顯示保持一致。
注意,它們不能同時出現,只能二選一。
ghost-class和handle
ghost指的在拖拽體原本位置占坑的那個元素:

ghost-class就是給占坑元素設置樣式:
<draggable ghost-class="ghost" > </draggable>
<style scoped>
.ghost {
opacity: 0.5;
background: #c8ebfb;
}
</style>
handle是拖拽的把手,表示拖拽元素指定可拖拽的部分:

正常情況下拖拽元素的整體都是可拖拽的,加了handle之后,只能指定的地方可以拖拽了,其他地方不能進行拖拽:
<draggable tag="ul" :list="list" class="list-group" handle=".handle">
<li class="list-group-item" v-for="(element, idx) in list" :key="element.name" >
<i class="fa fa-align-justify handle"></i>
<span class="text">{{ element.name }} </span>
<input type="text" class="form-control" v-model="element.text" />
<i class="fa fa-times close" @click="removeAt(idx)"></i>
</li>
</draggable>
tag和componentData
對於一些特定的原生組合標簽,例如ul,li或者table,tr還有tr,td之類的,可以指定一個tag,讓draggable替換成指定的標簽:
<draggable v-model="list" tag="tbody">
<tr v-for="item in list" :key="item.name">
<td scope="row">{{ item.id }}</td>
<td>{{ item.name }}</td>
<td>{{ item.sport }}</td>
</tr>
</draggable>
例如上面的draggable就會被替換成table。
componentData和tag類似,但是是對於那種組合組件的,例如在ElementUI中的折疊面邊,el-collapse和el-collapse-item就是這種組合關系:
<el-collapse v-model="activeNames" @change="handleChange">
<el-collapse-item title="一致性 Consistency" name="1">
<div>與現實生活一致:與現實生活的流程、邏輯保持一致,遵循用戶習慣的語言和概念;</div>
<div>在界面中一致:所有的元素和結構需保持一致,比如:設計樣式、圖標和文本、元素的位置等。</div>
</el-collapse-item>
<el-collapse-item title="反饋 Feedback" name="2">
<div>控制反饋:通過界面樣式和交互動效讓用戶可以清晰的感知自己的操作;</div>
<div>頁面反饋:操作后,通過頁面元素的變化清晰地展現當前狀態。</div>
</el-collapse-item>
</el-collapse>
對於上面那種情況,如果要轉成vuedraggable的話,首先要設置tag,但是那些el-collapse上的數據怎么辦呢?就要通過component-data配置了:
<draggable tag="el-collapse" :list="list" :component-data="collapseComponentData" >
<el-collapse-item v-for="item in list" :key="item.id" :title="item.title" :name="item.id" >
<div v-for="(lign, idx) in item.text" :key="idx">{{ lign }}</div>
</el-collapse-item>
</draggable>
<script>
export default {
name: "third-party",
display: "Third party",
order: 10,
components: {
draggable
},
data() {
return {
list: [
{
title: "Consistency",
id: 1,
text: [
"Consistent with real life: in line with the process and logic of real life, and comply with languages and habits that the users are used to;",
"Consistent within interface: all elements should be consistent, such as: design style, icons and texts, position of elements, etc."
]
},
{
title: "Feedback",
id: 2,
text: [
"Operation feedback: enable the users to clearly perceive their operations by style updates and interactive effects;",
"Visual feedback: reflect current state by updating or rearranging elements of the page."
]
}
],
activeNames: [1],
collapseComponentData: {
on: {
change: this.inputChanged
},
props: {
value: this.activeNames
}
}
};
},
methods: {
inputChanged(val) {
this.activeNames = val;
}
}
};
</script>
上面代碼中的collapseComponentData就是將原來el-collapse上傳遞數據的部分抽離出來了,包括事件(on),屬性(prop,attr)的設置。
group和clone
group一般的用法是用來區分拖拽組的,group名稱相同的拖拽組可以互相拖放:
<draggable class="list-group" :list="list1" group="people" >
<div class="list-group-item" v-for="(element, index) in list1" :key="element.name" >
{{ element.name }} {{ index }}
</div>
</draggable>
<draggable class="list-group" :list="list2" group="people" >
<div class="list-group-item" v-for="(element, index) in list2" :key="element.name" >
{{ element.name }} {{ index }}
</div>
</draggable>
互相拖放的一般效果如下:

group屬性還有更詳細的配置,例如:group="{name:'abc',pull:'clone',put:false}"。
put參數比較簡單,是用來控制別的地方內容是否可以拖拽到自己這邊來。如果設置為false,那么就表示別的地方的內容無法拖拽到自己這邊來。
pull參數控制的是從當前拽走,放在另外一個地方的行為。默認情況下(設置為true)是你拽到另外一個地方去,當前列表中就會少一個,對方列表多一個。如果設置為'clone',那么當前列表不會減少,同時對方列表多了一個。
當然你甚至可以配置一個:clone='func',用來控制放入對方列表的內容,我們看一個復雜一點的例子:
<draggable class="list-group" :list="list1" :group="{name:'people',pull:pullFunction,put:false}" :clone='clone'>
<div class="list-group-item" v-for="(element, index) in list1" :key="element.name" >
{{ element.name }} {{ index }}
</div>
</draggable>
<draggable class="list-group" :list="list2" group="people" >
<div class="list-group-item" v-for="(element, index) in list2" :key="element.name" >
{{ element.name }} {{ index }}
</div>
</draggable>
export default {
methods: {
clone: function(el) {
return {
name: el.name + " cloned"
};
},
pullFunction() {
return Math.random()*10%2 ? "clone" : true;
},
}
};
上面的代碼中,pull設置為true還是'clone'是隨機的(pullFunction)。如果設置的true,那么就是當前少一個,對方多一個;如果是'clone',同時:clone='func',那么就會用調用你自定義的clone方法,當前不少,對方多一個。
transition-group和animation
vuedraggable中的動畫主要分成兩類,一類是交換過程的動畫:

上圖我們可以看到,拖拽元素每經過一個內容項,它就會發生動畫移動的效果,這個主要是通過animation的設置:
<draggable class="list-group" :list="list1" :animation='200'>
<transition-group>
<div class="list-group-item" v-for="(element, index) in list1" :key="element.name" >
{{ element.name }} {{ index }}
</div>
</transition-group>
</draggable>
還有一種就是只有交換的雙方才有動畫:

這種和上面的不一樣,這種交換過程中沒有動畫,但是只是最后真正交換的時候才有動畫,這種需要加個class就好了:
<draggable class="list-group" :list="list1" >
<transition-group name='flip-list'>
<div class="list-group-item" v-for="(element, index) in list1" :key="element.name" >
{{ element.name }} {{ index }}
</div>
</transition-group>
</draggable>
<style>
.flip-list-move {
transition: transform 0.5s;
}
</style>
給transition-group添加一個name屬性ABC,然后增加一個ABC-move的樣式類就好了
