国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > JavaScript > 正文

基于vue實現一個禪道主頁拖拽效果

2019-11-19 11:27:34
字體:
來源:轉載
供稿:網友

效果圖如下所示:

源碼地址

bb兩句

最近在做一個基于vue的后臺管理項目。平時項目進度統計就在上禪道上進行。so~ 然后領導就感覺這個拖拽效果還行,能不能加到咱們項目里面。 既然領導發話,那就開干。。

所有技術:vue + vuedraggable

拖動的實現基于 vuedraggable 的插件開發

主頁為兩欄流式布局,每一個組件可以在上下拖動,也可以左右拖動。

基本步驟

布局

這塊布局為最為普通的兩欄布局,這里采用flex布局。左邊自適應,右邊為固定寬。

.layout-container { display: flex; .left { flex: 1; margin-right: 40px; } .right { width: 550px; }} 

拖拽實現

這里使用 vuedraggable 插件。需要在組件里面引入使用。 draggable 相當于拖拽容器,這塊很明顯需要兩個拖拽的容器。所以分別在 .left .right 中添加兩個拖拽容器。在默認情況下,這里已經可以進行拖拽了。插件的效果還是很強大。

<div class="layout-container">  <!--左欄--> <div class="left">  <draggable   v-bind="dragOptions"   class="list-group"   :list="item"  >   // ... 拖拽元素或組件  </draggable>  </div>  <!--右欄--> <div class="right">  <draggable   v-bind="dragOptions"   class="list-group"   :list="item"  >   // ... 拖拽元素或組件  </draggable> </div></div><script>import draggable from "vuedraggable";export default { components: {draggable}, computed: { dragOptions() {  return {  animation: 30,  handle: ".drag-handle",  group: "description",  ghostClass: "ghost",  chosenClass: "sortable",  forceFallback: true  }; } }};</script>

但是, 和我想要的效果還是相差一點。

左右拖動 與 僅標題欄拖動

這塊只需要配置相關的配置項就可以比較簡單。 左右拖動需要給拖拽容器指定相同的 group 屬性。指定標題元素拖動需要配置 handle 為可拖動元素的選擇器名稱。

下面簡單介紹下常用的配置項:

  • disabled :boolean 定義是否此sortable對象是否可用,為true時sortable對象不能拖放排序等功能,為false時為可以進行排序,相當于一個開關;
  • group : 用處是為了設置可以拖放容器時使用,若兩個容器該配置項相同,則可以相互拖動;
  • animation :number 單位:ms,定義排序動畫的時間;
  • handle :selector 格式為簡單css選擇器的字符串,使列表單元中符合選擇器的元素成為拖動的手柄,只有按住拖動手柄才能使列表單元進行拖動;
  • filter :selector 格式為簡單css選擇器的字符串,定義哪些列表單元不能進行拖放,可設置為多個選擇器,中間用“,”分隔;
  • draggable :selector 格式為簡單css選擇器的字符串,定義哪些列表單元可以進行拖放
  • ghostClass :selector 格式為簡單css選擇器的字符串,當拖動列表單元時會生成一個副本作為影子單元來模擬被拖動單元排序的情況,此配置項就是來給這個影子單元添加一個class,我們可以通過這種方式來給影子元素進行編輯樣式;
  • chosenClass :selector 格式為簡單css選擇器的字符串,當選中列表單元時會給該單元增加一個class;
  • forceFallback :boolean 如果設置為true時,將不使用原生的html5的拖放,可以修改一些拖放中元素的樣式等;
  • fallbackClass :string 當forceFallback設置為true時,拖放過程中鼠標附著單元的樣式;

采用相關配置如下:

computed: { dragOptions() {  return {  animation: 30,  handle: ".drag-handle",  group: "description",  ghostClass: "ghost",  chosenClass: "sortable",  forceFallback: true  }; } }

拖動時樣式調整

在拖動的時候,我們需要做三個事情。拖動時,拖動元素只顯示標題欄,兩欄內列表只顯示標題元素以及將要移動的位置變灰。

1.拖動元素只顯示標題欄: 在默認情況下,會開啟 html5 元素的拖動效果。這里明顯不需要。 forceFallback 改為 false 則可以關閉 html5 的默認效果。順便通過 chosenClass: "sortable" 修改拖動元素class 類名。直接用css進行隱藏

.sortable { .component-box { display: none; height: 0; }}

2.兩欄內列表只顯示標題元素 這里我借助兩個事件實現。

  • onStart:function 列表單元拖動開始的回調函數
  • onEnd:function 列表單元拖放結束后的回調函數
<div class="layout-container" :class="{drag:dragging}"> //...</div>data() { return {  dragging: false };},methods: { onStart() {  this.dragging = true; }, onEnd() {  this.dragging = false; } }.drag { .component-box { display: none; }}

在開始拖動的時候給 .layout-container 添加 .drag 的 class 名。拖動結束時,移除class名。

將要移動的位置變灰

這里需要用到上面 ghostClass: "ghost" 配置項。并添加相應的css。

.ghost { .drag-handle { background: rgb(129, 168, 187); }}

好了基本已經實現了。。。

展示動態組件

接下來就是數據的動態展示了。 這里需要vue中的動態組件了。。附上官方文檔連接點擊查看。

然后里面每個拖動的元素的內容都寫成組件,搭配動態組件實現自由拖動。

// 將所用組件引入import { timeline, calendar, welcome, carousel, imgs, KonList} from "@/components/DragComponents";components: { draggable, timeline, calendar, welcome, carousel, imgs, KonList}

配合 v-for 對數據進行循環,然后進行動態展示。

<component :is="element.name"/>

這塊涉及到數據格式相關的,可以直接看文末的代碼。。。 這里就就不展開說了。。

數據保持

在拖動結束后,我們需要將拖動的順序緩存在前端,當下次進入后,可以繼續使用拖動后的數據。

// 獲取新的布局 getLayout() {  let myLayout = JSON.parse(window.localStorage.getItem("kon"));  if (!myLayout || Object.keys(myLayout).length === 0)  myLayout = this.layout;  const newLayout = {};  for (const side in myLayout) {  newLayout[side] = myLayout[side].map(i => {   return this.componentList.find(c => c.id === i);  });  }  this.mainData = newLayout;},// 設置新的布局setLayout() { const res = {}; for (const side in this.mainData) {  const item = this.mainData[side].map(i => i.id);  res[side]=item; } window.localStorage.setItem("kon", JSON.stringify(res));}

這樣我只需要在 mounted 中獲取新的布局。。

mounted() { this.getLayout(); }

在拖動結束后,設置新的布局

onEnd() {  this.dragging = false;  this.setLayout();}

在項目中,還是建議配合后端進行用戶布局的數據存儲,每次拖動后將新的布局數據請求接口保存在數據庫,同時存入緩存中。當再次進入頁面的時候,讀取緩存中的數據,沒有的話請求后端的接口拿到用戶的布局,然后再次存入緩存中。有的話直接讀取緩存中的數據。

最后說兩句

其實上面的效果也不是特別難,簡單花點時間,看看相關文檔,就能做出來,,記錄在掘金上面,只是想和大家分享我的思路。同時希望和大家一起交流,一起進步。


生活不易,大家加油

附上源碼: 項目地址

<template> <div :class="{drag:dragging}">  <div class="layout-container">   <div :class="key" v-for="(item, key) in mainData" :key="key">    <draggable     v-bind="dragOptions"     class="list-group"     :list="item"     @end="onEnd"     @start="onStart"    >     <transition-group name="list">      <div class="list-group-item" v-for="(element, index) in item" :key="index">       <div class="drag-handle">{{ element.title }}</div>       <div class="component-box">        <component :is="element.name"/>       </div>      </div>     </transition-group>    </draggable>   </div>  </div> </div></template><script>import draggable from "vuedraggable";import { timeline, calendar, welcome, carousel, imgs, KonList} from "@/components/DragComponents";export default { components: {  draggable,  timeline,  calendar,  welcome,  carousel,  imgs,  KonList }, data() {  return {   dragging: false,   componentList: [    { name: "KonList", title: "追番地址", id: "5" },    { name: "imgs", title: "五月最強新番", id: "4" },    { name: "timeline", title: "日程組件", id: "2" },    { name: "carousel", title: "走馬燈組件", id: "1" },    { name: "calendar", title: "日歷組件", id: "3" }   ],   layout: {    left: ["5", "4"],    right: ["2", "1", "3"]   },   mainData: {}  }; }, computed: {  dragOptions() {   return {    animation: 30,    handle: ".drag-handle",    group: "description",    ghostClass: "ghost",    chosenClass: "sortable",    forceFallback: true   };  } }, mounted() {  this.getLayout(); }, methods: {  onStart() {   this.dragging = true;  },  onEnd() {   this.dragging = false;   this.setLayout();  },  getLayout() {   let myLayout = JSON.parse(window.localStorage.getItem("kon"));   if (!myLayout || Object.keys(myLayout).length === 0)    myLayout = this.layout;   const newLayout = {};   for (const side in myLayout) {    newLayout[side] = myLayout[side].map(i => {     return this.componentList.find(c => c.id === i);    });   }   this.mainData = newLayout;  },  setLayout() {   const res = {};   for (const side in this.mainData) {    const item = this.mainData[side].map(i => i.id);    res[side]=item;   }   window.localStorage.setItem("kon", JSON.stringify(res));  } }};</script><style lang="scss" scoped>.layout-container { height: 100%; display: flex; .left {  flex: 1;  margin-right: 40px; } .right {  width: 550px; } .list-group-item {  margin-bottom: 20px;  border-radius: 6px;  overflow: hidden;  background: #fff; } .component-box {  padding: 20px; } .drag-handle {  cursor: move;  height: 40px;  line-height: 40px;  color: #fff;  font-weight: 700;  font-size: 16px;  padding: 0 20px;  background: #6cf; }}.drag { .component-box {  display: none; }}.list-enter-active { transition: all .3s linear;}.list-enter,.list-leave-to { opacity: .5;}.sortable { .component-box {  display: none;  height: 0; }}.list-group { > span {  display: block;  min-height: 20px; }}.ghost { .drag-handle {  background: rgb(129, 168, 187); }}</style>

總結

以上所述是小編給大家介紹的基于vue實現一個禪道主頁拖拽效果,希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時回復大家的。在此也非常感謝大家對武林網網站的支持!
如果你覺得本文對你有幫助,歡迎轉載,煩請注明出處,謝謝!

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 安国市| 全椒县| 瓦房店市| 咸宁市| 威宁| 内乡县| 涟源市| 宜川县| 射洪县| 晋宁县| 乐昌市| 勃利县| 舟山市| 洛扎县| 方城县| 喀喇沁旗| 新晃| 东宁县| 许昌县| 儋州市| 日土县| 湟中县| 鱼台县| 蒲城县| 刚察县| 白玉县| 班戈县| 阿拉善右旗| 通道| 卫辉市| 庆安县| 依安县| 磐安县| 南京市| 正定县| 屯门区| 贵州省| 贵州省| 南雄市| 江山市| 西宁市|