中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

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

發布時間:2020-09-04 15:11:04 來源:腳本之家 閱讀:353 作者:禾寸 欄目:web開發

效果圖如下所示:

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

源碼地址

bb兩句

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

所有技術:vue + vuedraggable

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

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

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

基本步驟

布局

這塊布局為最為普通的兩欄布局,這里采用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實現一個禪道主頁拖拽效果

展示動態組件

接下來就是數據的動態展示了。 這里需要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();
}

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

最后說兩句

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

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

生活不易,大家加油

附上源碼: 項目地址

<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實現一個禪道主頁拖拽效果,希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時回復大家的。在此也非常感謝大家對億速云網站的支持!
如果你覺得本文對你有幫助,歡迎轉載,煩請注明出處,謝謝!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

含山县| 咸阳市| 都兰县| 渝北区| 霍州市| 河西区| 宾川县| 迭部县| 剑川县| 荆门市| 沈阳市| 巴马| 项城市| 文水县| 贵阳市| 巴南区| 康平县| 黄梅县| 抚宁县| 廉江市| 祥云县| 青铜峡市| 平阳县| 嘉禾县| 宜章县| 田阳县| 南溪县| 江永县| 浦城县| 南昌市| 佳木斯市| 黑山县| 皮山县| 五指山市| 贵阳市| 松滋市| 昆山市| 册亨县| 常州市| 沐川县| 穆棱市|