最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

基于vue-draggable 實現三級拖動排序效果

 更新時間:2020年01月10日 10:56:30   作者:慢慢慢慢慢  
這篇文章主要介紹了基于vue-draggable 實現三級拖動排序效果,本文通過實例代碼給大家介紹的非常詳細,具有一定的參考借鑒價值,需要的朋友可以參考下

vue-draggable

之前項目中需要用到拖動排序,就去網上找資料,本來最開始是想用jquery-ui里的拖動的,后面發(fā)現不符合我的預期也不知道能不能跟vue.js兼容,后面我試過了,單個的可以但是層級太多就不一樣了。

廢話少說直接上代碼

先看數據結構,和頁面的呈現,等會再來上代碼。

這就是三層結構渲染出來的圖。那個海錨一樣的東西是可以點擊的,點擊后會出現當前類型所帶的產品。等會會說的

我們現在來看下我實現后的拖動效果,如下

所有父類型里面的產品拖動如下

控制臺的打印

好了,放了那么多圖,數據結構也發(fā)了。接下來我們來上代碼和思路。

先上html的代碼,這里我的頁面是jsp,但是不影響html兼容,項目中途接手,很古老的jsp我也沒辦法


<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<c:set var="ctx" value="${pageContext.request.contextPath}"/>
<link rel="stylesheet" href="${ctx}/res/ifw/plugins/datatables/dataTables.bootstrap.css" rel="external nofollow" />
<style>
 [v-cloak] {
 display: none;
 }
 .flip-list-move {
 transition: transform 0.5s;
 }
 .handle {
 float: right;
 padding-top: 2px;
 padding-bottom: 8px;
 }
 .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>
<div id="vueSort" class="box box-darkness">
 <div class="box-header with-border">
 <h3 class="box-title">排序</h3>
 <div class="box-tools pull-right">
  <button type="button" class="btn btn-box-tool" data-widget="collapse"><i class="fa fa-minus"></i>
  </button>
 </div>
 </div>
 <div class="box-body" style="position: relative">
 <div class="col-md-3">
  <ul id="main-nav1" class="nav nav-tabs nav-stacked">
  <draggable class="list-group" tag="ul" v-model="listProductType":move="getdata" @update="datadragEnd">
   <transition-group type="transition" :name="'flip-list'">
   <li class="list-group-item" v-for="(element,index) in listProductType" :key="element.id">
    <a :href="'#'+forId(element.uuid)" rel="external nofollow" rel="external nofollow" rel="external nofollow" class="nav-header collapsed" data-toggle="collapse"><i
     v-show="element.productList.length>0"
     aria-hidden="true"
     :class="{'fa fa-anchor':isActive,'glyphicon glyphicon-pushpin':!isActive}"
     @click="submenu"></i></a>
    {{element.name}}
    <i class="fa fa-align-justify handle" v-show="element.productTypes.length>0"
    @click="showLeve2(index)"></i>
    <template v-if="element.productList.length>0">
    <ur :id="forId(element.uuid)" class="nav nav-list collapse secondmenu">
     <draggable class="list-group" tag="ul":move="getdata" v-model="element.productList"
      @update="datadragEnds">
     <transition-group type="transition" :name="'flip-list'">
   <li class="list-group-item" v-for="e in element.productList" :key="e.id">
    <a> {{e.name}}</a>
   </li>
   </transition-group>
  </draggable>
  </ur>
  </template>
  </li>
  </transition-group>
  </draggable>
  </ul>
 </div>
 <div class="col-md-3" v-show="one.productTypes.length>0&&showOne">
  <span><h3 style="color: red">--->>>{{one.name}}</h3></span>
  <ul id="main-nav2" class="nav nav-tabs nav-stacked">
  <draggable class="list-group" tag="ul" v-model="one.productTypes" :move="getdata"@update="datadragEnd">
   <transition-group type="transition" :name="'flip-list'">
   <li class="list-group-item" v-for="(element,index) in one.productTypes" :key="element.id">
    <a :href="'#'+forId(element.uuid)" rel="external nofollow" rel="external nofollow" rel="external nofollow" class="nav-header collapsed" data-toggle="collapse"><i
     v-show="element.productList.length>0"
     aria-hidden="true"
     :class="{'fa fa-anchor':isActive,'glyphicon glyphicon-pushpin':!isActive}"
     @click="submenu"></i></a>
    {{element.name}}
    <i class="fa fa-align-justify handle" v-show="element.productTypes.length>0"
    @click="showLeve3(index)"></i>
    <template v-if="element.productList.length>0">
    <ur :id="forId(element.uuid)" class="nav nav-list collapse secondmenu">
     <draggable class="list-group" tag="ul":move="getdata" v-model="element.productList"
      @update="datadragEnds">
     <transition-group type="transition" :name="'flip-list'">
   <li class="list-group-item" v-for="e in element.productList" :key="e.id">
    <a> {{e.name}}</a>
   </li>
   </transition-group>
  </draggable>
  </ur>
  </template>
  </li>
  </transition-group>
  </draggable>
  </ul>
 </div>
 <div class="col-md-3" v-show="two.productTypes.length>0&&showTwo">
  <span><h3 style="color: red">--->>>{{two.name}}</h3></span>
  <ul id="main-nav3" class="nav nav-tabs nav-stacked">
  <draggable class="list-group" tag="ul" v-model="two.productTypes":move="getdata" @update="datadragEnd">
   <transition-group type="transition" :name="'flip-list'">
   <li class="list-group-item" v-for="(element,index) in two.productTypes" :key="element.id">
    <a :href="'#'+forId(element.uuid)" rel="external nofollow" rel="external nofollow" rel="external nofollow" class="nav-header collapsed" data-toggle="collapse"><i
     v-show="element.productList.length>0"
     aria-hidden="true"
     :class="{'fa fa-anchor':isActive,'glyphicon glyphicon-pushpin':!isActive}"
     @click="submenu"></i></a>
    {{element.name}}
    <template v-if="element.productList.length>0">
    <ur :id="forId(element.uuid)" class="nav nav-list collapse secondmenu">
     <draggable class="list-group":move="getdata" tag="ul" v-model="element.productList"
      @update="datadragEnds">
     <transition-group type="transition" :name="'flip-list'">
   <li class="list-group-item" v-for="e in element.productList" :key="e.id">
    <a> {{e.name}}</a>
   </li>
   </transition-group>
  </draggable>
  </ur>
  </template>
  </li>
  </transition-group>
  </draggable>
  </ul>
 </div>
 </div>
 <div class="box-footer">
 <button type="button" class="btn btn-darkness pull-right" id="doSearch"
  style="margin-left: 20px;"@click="save">保存
 </button>
 <button type="button" class="btn btn-default pull-right" @click="reset" id="resetSearch">重置</button>
 </div>
</div>
<script type="text/javascript" src="${ctx}/res/js/vue/vue.js"></script>
<!-- CDNJS :: Sortable (https://cdnjs.com/) -->
<script src="${ctx}/res/js/vue/Sortable.min.js"></script>
<!-- CDNJS :: Vue.Draggable (https://cdnjs.com/) -->
<script src="${ctx}/res/js/vue/vuedraggable.umd.min.js"></script>
<script type="text/javascript" src="${ctx}/res/js/sort/combinationSort.js"></script>

接下來是js。


Vue.component('vue-draggable', vuedraggable)
var vm = new Vue({
 el: '#vueSort',
 data: {
 isActive: true,
 queryObject: {},
 listProductType: [],
 showSon: false,
 index: 0,
 one: {productTypes: []},
 two: {productTypes: []},
 showOne: false,
 showTwo: false
 },
 methods: {
 init: function () {
  var _this = this;
  $.ajax({
  url: '../../mt/combinationSort/sortingData',
  data: null,
  type: 'POST',
  contentType: "application/json",
  dataType: 'json',
  success: function (data) {
   if (data.success = true) {
   if (data.dataObject.length == 0) {
    Util.alert('通知', '異常數據', 'info');
    return;
   }
   _this.listProductType = data.dataObject;
   }
   console.log(data)
  }
  })
 },
 reset: function () {
  var _this = this;
  _this.listProductType = _this.listProductType.sort((one, two) => {
  return one.displaySeq - two.displaySeq;
 })
  ;
  for (var i in _this.listProductType) {
  //排序產品類型
  _this.listProductType[i].productTypes = _this.listProductType[i].productTypes.sort((one, two) => {
   return one.displaySeq - two.displaySeq;
  })
  ;
  //排序產品
  _this.listProductType[i].productList = _this.listProductType[i].productList.sort((one, two) => {
   return one.displaySeq - two.displaySeq;
  })
  ;
  for (var a in _this.listProductType[i].productTypes) {
   _this.listProductType[i].productTypes[a].productTypes = _this.listProductType[i].productTypes[a].productTypes.sort((one, two) => {
   return one.displaySeq - two.displaySeq;
  })
   ;
   _this.listProductType[i].productTypes[a].productList = _this.listProductType[i].productTypes[a].productList.sort((one, two) => {
   return one.displaySeq - two.displaySeq;
  })
   ;
   for (var c in _this.listProductType[i].productTypes[a].productTypes) {
   _this.listProductType[i].productTypes[a].productTypes[c].productList = _this.listProductType[i].productTypes[a].productTypes[c].productList.sort((one, two) => {
    return one.displaySeq - two.displaySeq;
   })
   ;
   }
  }
  }
 },
 datadragEnd: function (evt) {
  console.log('拖動前的索引:' + evt.oldIndex);
  console.log('拖動后的索引:' + evt.newIndex);
  var obj = evt.item;
  obj.style.backgroundColor = '#fff';
 },
 submenu: function () {
  var _this = this;
  if (_this.isActive) _this.isActive = false;
  else _this.isActive = true;
  if (_this.showSon) _this.showSon = false;
  else _this.showSon = true;
 },
 datadragEnds: function (evt) {
  console.log('拖動前的索引:' + evt.oldIndex);
  console.log('拖動后的索引:' + evt.newIndex);
  var obj = evt.item;
  obj.style.backgroundColor = '#fff';
 },
 forId: function (index) {
  return "uuid_" + index
 },
 
 showLeve2: function (index) {
  var _this = this;
  _this.index = index;
  // if (_this.one.productTypes.length > 0) _this.one.productTypes = [];
  // else
  _this.one = _this.listProductType[index];
  console.log(_this.one)
  if (_this.showOne) {
  _this.showOne = false;
  _this.showTwo = false;
  }
  else _this.showOne = true;
 },
 showLeve3: function (index) {
  var _this = this;
  // if (_this.two.productTypes.length > 0) _this.two.productTypes = [];
  // else
  _this.two = _this.listProductType[_this.index].productTypes[index];
  console.log(_this.two.productTypes)
  if (_this.showTwo) _this.showTwo = false;
  else _this.showTwo = true;
 },
 getdata: function (event) {
  console.log("下來了");
  var obj = event.dragged;
  obj.style.backgroundColor = '#11cc17';
 },
 save: function () {
  var _this = this;
  Util.confirm('提示', '您確定要保存排序嗎?', function (isOk) {
  if (isOk) {
   console.log(_this.listProductType);
   $.ajax({
   type: "post",
   url: "../../mt/combinationSort/saveSortingData",
   data: {list: JSON.stringify(_this.listProductType)},
   success: function (json) {
    console.log(json);
   }
   });
   Util.alert("提示", '保存成功', 'info');
  }
  }, 'info');
 
 }
 },
 created: function () {
 var _this = this;
 _this.init();
 // _this.heartbeat();
 }
});

最重要的是這幾行代碼

然后是使用vue把vuedraggable模塊引入,上面圖最下面的js是我剛剛發(fā)過的代碼文件。

Vue.component('vue-draggable', vuedraggable)

這句話顯得尤為重要。注冊成vue的組件,雖然它本身就是vue的一個組件了。

當然最后我們會進行排序后的順序的保存。這里就不得不說vue的雙向綁定了,你對象只要在頁面改變位置,在內存地址里的位置順序也會被改變的,所有我們只需要再次將整個對象回傳就行。后臺去解析保存,當然這種方式我覺得會很繁瑣。比如:我貼個獲取數據的代碼

/**
 * 獲取排序數據
 * * @param merchantId
 * @return
 */
 public List<SortProductTypeVo> treeSorting(Long merchantId) {
 //獲取所有的連接項
 List<ProductTypeRef> typeRefList = productTypeRefService.findAll();
 //獲取所有的產品
 Map<Long, ProductVo> productList = productService.sortFindProduct(merchantId).stream().collect(
  Collectors.toMap(w -> w.getId(), w -> w));
 //最上級父級
 List<SortProductTypeVo> parentList = byParentProduct(merchantId, 0);
 //平均未分類
 List<SortProductTypeVo> typeList = byParentProduct(merchantId, 1);
 //
 //獲取產品類型和產品關聯
 Map<Long, List<ProductTypeRef>> parentIdChildrenMap = typeRefList.stream().filter(productTypeRef -> productTypeRef.getProductTypeId() != null).collect(Collectors.groupingBy(ProductTypeRef::getProductTypeId));
 parentList.forEach(p -> {
  //篩選第二級菜單
  List<SortProductTypeVo> districtsOne = typeList.stream().filter(sortProductTypeVo -> sortProductTypeVo.getParentTypeId().equals(p.getId())).collect(Collectors.toList());
  districtsOne.forEach(a -> {
  //第三層菜單
  List<SortProductTypeVo> districtsTwo = typeList.stream().filter(productType -> productType.getParentTypeId().equals(a.getId())).collect(Collectors.toList());
  districtsTwo.stream().forEach(d -> {
   //獲取產品和產品類型之間的連接關系
   List<ProductTypeRef> l = parentIdChildrenMap.getOrDefault(d.getId(), new ArrayList<>());
   //排序產品關聯就相當于產品排序
   l.sort((q, b) -> Integer.compare(q.getDisplaySeq(), b.getDisplaySeq()));
   //根據排序產品關聯去找到產品
   d.setProductList(l.stream().map(e -> {
   ProductVo products = productList.get(e.getProductId());
   if (null != products) products.setDisplaySeq(e.getDisplaySeq());
   return products;
   }).collect(Collectors.toList()).stream().filter(s -> s != null).collect(Collectors.toList()));//數組中過濾空的產品
//   d.setProductTypeRefs(parentIdChildrenMap.getOrDefault(d.getId(), new ArrayList<>()));
  });
  List<ProductTypeRef> l = parentIdChildrenMap.getOrDefault(a.getId(), new ArrayList<>());
  l.sort((q, b) -> Integer.compare(q.getDisplaySeq(), b.getDisplaySeq()));
  a.setProductList(l.stream().map(c -> {
   ProductVo products = productList.get(c.getProductId());
   if (null != products) products.setDisplaySeq(c.getDisplaySeq());
   return products;
  }).collect(Collectors.toList()).stream().filter(s -> s != null).collect(Collectors.toList()));
  districtsTwo.sort((q, b) -> Integer.compare(q.getDisplaySeq(), b.getDisplaySeq()));
  a.setProductTypes(districtsTwo);
//  a.setProductTypeRefs(parentIdChildrenMap.getOrDefault(a.getId(), new ArrayList<>()));
  });
  List<ProductTypeRef> l = parentIdChildrenMap.getOrDefault(p.getId(), new ArrayList<>());
  l.sort((q, b) -> Integer.compare(q.getDisplaySeq(), b.getDisplaySeq()));
  p.setProductList(l.stream().map(a -> {
  ProductVo products = productList.get(a.getProductId());
  if (null != products) products.setDisplaySeq(a.getDisplaySeq());
  return products;
  }).collect(Collectors.toList()).stream().filter(s -> s != null).collect(Collectors.toList()));
//  p.setProductTypeRefs(parentIdChildrenMap.getOrDefault(p.getId(), new ArrayList<>()));
  districtsOne.sort((q, b) -> Integer.compare(q.getDisplaySeq(), b.getDisplaySeq()));
  p.setProductTypes(districtsOne);
 });
 parentList.sort((q, b) -> Integer.compare(q.getDisplaySeq(), b.getDisplaySeq()));
 return parentList;
 }

jdk8語法,可能還有需要改進的地方。反正目前來說,功能是實現了。

其實本來想代碼一點點講解的,奈何實在是有事。

關于怎么讓3級菜單組件相互拖動,你只需要在父級相互拖動這里就能找到答案,

加上這個屬性就行,理論上。我沒試過,因為我懶,hhhh

總結

以上所述是小編給大家介紹的基于vue-draggable 實現三級拖動排序效果,希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時回復大家的。在此也非常感謝大家對腳本之家網站的支持!
如果你覺得本文對你有幫助,歡迎轉載,煩請注明出處,謝謝!

相關文章

  • Vue使用axios圖片上傳遇到的問題

    Vue使用axios圖片上傳遇到的問題

    后端寫個上傳圖片的接口可不是很簡單,只需要讓這個字段限制為圖片格式,后臺做個保存的邏輯就完事了,前端處理還要牽扯到請求頭,數據格式的處理等等問題,按照老傳統(tǒng)把圖片按照字符串往接口put發(fā)現返回的全是400錯誤,直到我知道了前端的FormData方法!
    2021-05-05
  • vue中配置mint-ui報css錯誤問題的解決方法

    vue中配置mint-ui報css錯誤問題的解決方法

    本篇文章主要介紹了vue中配置mint-ui報css錯誤問題的解決方法,非常具有實用價值,需要的朋友可以參考下
    2017-10-10
  • 解決vite項目Uncaught Syntaxerror:Unexpected token>vue項目上線白屏問題

    解決vite項目Uncaught Syntaxerror:Unexpected token>vue項

    這篇文章主要介紹了解決vite項目Uncaught Syntaxerror:Unexpected token>vue項目上線白屏問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-03-03
  • 詳解基于webpack和vue.js搭建開發(fā)環(huán)境

    詳解基于webpack和vue.js搭建開發(fā)環(huán)境

    本篇文章主要介紹了詳解基于webpack和vue.js搭建開發(fā)環(huán)境 ,小編覺得挺不錯的,現在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-04-04
  • Vue中created與mounted的區(qū)別淺析

    Vue中created與mounted的區(qū)別淺析

    在使用vue框架的過程中,我們經常需要給一些數據做一些初始化處理,這時候我們常用的就是在created與mounted選項中作出處理,這篇文章主要給大家介紹了關于Vue中created與mounted區(qū)別的相關資料,其中部分知識點可能是我們日常工作會見到或用到的,需要的朋友可以參考下
    2022-06-06
  • vue項目同時兼容pc和移動端的解決方式

    vue項目同時兼容pc和移動端的解決方式

    我們經常在項目中會有支持pc與手機端需求,下面這篇文章主要給大家介紹了關于vue項目同時兼容pc和移動端的解決方式,文中通過代碼介紹的非常詳細,需要的朋友可以參考下
    2023-10-10
  • vue實現商品列表的無限加載思路和步驟詳解

    vue實現商品列表的無限加載思路和步驟詳解

    這篇文章主要介紹了vue實現商品列表的無限加載思路和步驟詳解,基礎思路是觸底條件滿足之后 page++,拉取下一頁數據,結合實例代碼給大家介紹的非常詳細,需要的朋友可以參考下,
    2024-06-06
  • Vue中設置登錄驗證攔截功能的思路詳解

    Vue中設置登錄驗證攔截功能的思路詳解

    今天在做vue和springboot交互的一個項目的時候,想要基于前端實現一些只有登錄驗證之后才能訪問某些頁面的操作,所以在這里總結一下實現該功能的一個解決方案
    2021-10-10
  • vue element動態(tài)渲染、移除表單并添加驗證的實現

    vue element動態(tài)渲染、移除表單并添加驗證的實現

    這篇文章主要介紹了vue element動態(tài)渲染、移除表單并添加驗證的實現,小編覺得挺不錯的,現在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2019-01-01
  • vue選項卡切換登錄方式小案例

    vue選項卡切換登錄方式小案例

    這篇文章主要為大家詳細介紹了vue選項卡切換登錄方式小案例,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2019-09-09

最新評論

迁安市| 石柱| 横峰县| 兴仁县| 丹江口市| 抚松县| 织金县| 孙吴县| 宝坻区| 绥阳县| 准格尔旗| 突泉县| 东平县| 永登县| 贺州市| 长白| 闽清县| 迭部县| 鱼台县| 黔南| 乾安县| 济源市| 石泉县| 库伦旗| 屏南县| 合川市| 九江市| 马鞍山市| 龙门县| 灵武市| 乌拉特后旗| 夏津县| 崇义县| 六安市| 江阴市| 双鸭山市| 辛集市| 丰原市| 西宁市| 仁寿县| 蕲春县|