亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

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

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
91精品国产91久久久久久不卡| 91夜夜未满十八勿入爽爽影院| 精品久久久久久中文字幕大豆网| 久久精品国产久精国产思思| 午夜精品久久久久久久99热| 国产综合在线观看视频| 久久久91精品国产一区不卡| 中文字幕成人在线| 日韩暖暖在线视频| 久久露脸国产精品| 日韩在线视频一区| 精品国产精品三级精品av网址| 这里只有精品视频在线| 日韩中文字幕第一页| 26uuu亚洲伊人春色| 国产精品永久免费视频| 91精品久久久久久久久中文字幕| 日韩欧亚中文在线| 国产精品中文字幕久久久| 蜜臀久久99精品久久久无需会员| 日本精品一区二区三区在线播放视频| 夜夜躁日日躁狠狠久久88av| 日韩国产激情在线| 久久频这里精品99香蕉| 一区二区三区四区精品| 欧美日韩国产成人在线观看| 欧美成人高清视频| 日韩高清电影免费观看完整版| 国产精品视频免费在线观看| 日韩视频中文字幕| 亚洲欧美日韩一区二区在线| 伊人av综合网| 91亚洲精品在线观看| 国产中文字幕亚洲| 亚洲精美色品网站| 成人精品网站在线观看| 日本精品在线视频| 欧美激情欧美激情| 久久精品成人动漫| 久久久视频免费观看| 国产成人亚洲综合91精品| 日韩福利视频在线观看| 日韩电影中文字幕一区| 国产精品一区二区三区免费视频| 成人免费在线视频网址| 亚州国产精品久久久| 欧美成人午夜激情在线| 日韩精品一区二区视频| 日本免费一区二区三区视频观看| 亚洲人av在线影院| 久久免费国产精品1| 亚洲性生活视频在线观看| 亚洲最大福利视频网站| 中文字幕日韩av综合精品| 国产成人精品av| 久久在线免费观看视频| 亚洲国产精品国自产拍av秋霞| 国产精品2018| 久久久久久久久久久免费| 91社区国产高清| 亚洲欧美综合精品久久成人| 欧美韩日一区二区| 国产日韩专区在线| 欧美自拍视频在线观看| 成人福利在线视频| 国产视频精品自拍| 国产在线观看91精品一区| 国产成人一区二区三区电影| 欧美超级乱淫片喷水| 日韩高清有码在线| 国内精品久久久久影院优| 欧美成人剧情片在线观看| 国产精品一二三在线| 亚洲一区二区三区在线免费观看| 国产精欧美一区二区三区| 国产精品成人av在线| 5252色成人免费视频| 在线亚洲国产精品网| 91成人天堂久久成人| 国产成人精品av| 韩国精品美女www爽爽爽视频| 久久久97精品| 国产精品久久久久7777婷婷| 精品女厕一区二区三区| 中文字幕av一区中文字幕天堂| 国产精品aaa| 亚洲国产精久久久久久久| 欧美日本在线视频中文字字幕| 欧美精品少妇videofree| 黑人与娇小精品av专区| 日韩网站免费观看高清| 国产91久久婷婷一区二区| 久久久www成人免费精品| 久久91亚洲精品中文字幕奶水| 91精品国产综合久久香蕉的用户体验| 国产精品久久婷婷六月丁香| 日韩视频免费看| 亚洲国产精品va在看黑人| 国模视频一区二区| 精品一区电影国产| 国产成人午夜视频网址| 国产精品久久久久久久久久99| 久久偷看各类女兵18女厕嘘嘘| 91久久久久久久一区二区| 亚洲国产另类 国产精品国产免费| 粉嫩老牛aⅴ一区二区三区| 亚洲精品国产精品国自产在线| 97色在线视频| 久久亚洲精品成人| 久久久女女女女999久久| 2018日韩中文字幕| 55夜色66夜色国产精品视频| 色与欲影视天天看综合网| 久久久久久免费精品| 久久天天躁日日躁| 中文字幕一区电影| 亚洲日韩欧美视频| 欧美性猛交视频| 色黄久久久久久| 亚洲欧美一区二区精品久久久| 亚洲欧洲国产伦综合| 亚洲成人在线视频播放| 国产精品普通话| 国产网站欧美日韩免费精品在线观看| 国产ts人妖一区二区三区| 国产一区二区香蕉| 黄色一区二区在线| 亚洲欧洲偷拍精品| 亚洲视频电影图片偷拍一区| 91九色国产社区在线观看| 懂色av影视一区二区三区| 一区二区中文字幕| 日韩亚洲精品电影| 成人写真福利网| 亚洲男人的天堂网站| 国产亚洲精品久久久久久777| 亚洲日本成人网| 最近2019中文免费高清视频观看www99| 国产精品在线看| 国产综合在线视频| 55夜色66夜色国产精品视频| 欧美激情久久久久| 国产suv精品一区二区| 久久久成人精品| 久久成年人视频| 久久久电影免费观看完整版| 亚洲sss综合天堂久久| 一本大道久久加勒比香蕉| 欧美激情在线观看视频| 国产精品爽黄69天堂a| 欧美整片在线观看| 高跟丝袜一区二区三区| 成人黄色免费片| 夜夜嗨av一区二区三区免费区| 国产精品揄拍一区二区| 91在线视频一区| 一色桃子一区二区| 九九热最新视频//这里只有精品| 亚洲男人av在线| 久久影视电视剧免费网站| 国产精品99免视看9| 疯狂做受xxxx高潮欧美日本| 成人深夜直播免费观看| 色偷偷av一区二区三区|