欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

vue中el-table和jsplumb實現(xiàn)連線功能

 更新時間:2023年07月20日 16:01:50   作者:愛踢球的程序員  
本文主要介紹了el-table和jsplumb實現(xiàn)連線功能,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧

前言

最近在開發(fā)中遇到了一個需求,是將兩組樹形結(jié)構(gòu)的數(shù)據(jù)通過連線進行關(guān)聯(lián)映射。what?連線功能?還是兩組樹形結(jié)構(gòu)???讓我頭疼的并非連線而是對樹形結(jié)構(gòu)的展示,我需要一個能夠清晰的展示樹形結(jié)構(gòu)的關(guān)系和每條數(shù)據(jù)里的詳細數(shù)據(jù)的組件,就這樣el-table走進了我的視野里。

準備工作

所用插件: "element-plus" + "jsplumb"npm install 就完事

第一步: 定義靜態(tài)數(shù)據(jù)并顯示table組件

新建一個line.vue文件,定義一個id為container的div標簽,在這個標簽內(nèi)放入兩個el-table,并根據(jù)定義的靜態(tài)數(shù)據(jù)進行基礎(chǔ)的配置。需要注意的是el-table當(dāng) row 中包含 children 字段時,被視為樹形數(shù)據(jù)。 渲染嵌套數(shù)據(jù)需要 prop 的 row-key。具體見下面代碼:

<template>
  <div class="line">
    <div id="container" style="display: flex; justify-content: space-between; position: relative">
      <el-table
        ref="leftTable"
        :data="leftTreeData"
        style="width: 40%; margin-bottom: 20px; display: inline-block;"
        row-key="id"
        border
        default-expand-all
      >
        <el-table-column prop="name" label="姓名"/>
        <el-table-column prop="gender" label="性別"/>
        <el-table-column prop="age" label="年齡"/>
      </el-table>
      <el-table
        ref="rightTable"
        :data="rightTreeData"
        style="width: 40%; margin-bottom: 20px; display: inline-block;"
        row-key="id"
        border
        default-expand-all
      >
        <el-table-column prop="name" label="姓名"/>
        <el-table-column prop="gender" label="性別"/>
        <el-table-column prop="age" label="年齡"/>
      </el-table>
    </div>
  </div>
</template>
<script setup>
  import { ref } from 'vue'
  // 左側(cè)靜態(tài)數(shù)據(jù)
  const leftData = ref([
    {id: 1, name: '張三', gender: '男', age: 23, parentId: null, hasChild: true},
    {id: 2, name: '李四', gender: '男', age: 22, parentId: null, hasChild: false},
    {id: 3, name: '坤坤', gender: '女', age: 24, parentId: 1, hasChild: true},
    {id: 4, name: '小黑子', gender: '男', age: 25, parentId: 3, hasChild: false},
  ]);
  const leftTreeData = ref([
    {
      id: 1, name: '張三', gender: '男', age: 23, parentId: null, children: [
        {id: 3, name: '坤坤', gender: '女', age: 24, parentId: 1, children: [
            {id: 4, name: '小黑子', gender: '男', age: 25, parentId: 3},
          ]
        },
      ]
    },
    {id: 2, name: '李四', gender: '男', age: 22, parentId: null},
  ]);
  // 右側(cè)靜態(tài)數(shù)據(jù)
  const rightData = ref([
    {id: 5, name: '柯潔', gender: '男', age: 23, parentId: null, hasChild: true},
    {id: 6, name: '戰(zhàn)鷹', gender: '女', age: 30, parentId: 5, hasChild: false},
    {id: 7, name: '唱跳', gender: '男', age: 24, parentId: null, hasChild: false},
    {id: 8, name: 'rap', gender: '男', age: 25, parentId: null, hasChild: false},
  ]);
  const rightTreeData = ref([
    {id: 5, name: '柯潔', gender: '男', age: 23, parentId: null, children: [
        {id: 6, name: '戰(zhàn)鷹', gender: '女', age: 30, parentId: 6},
      ]
    },
    {id: 7, name: '唱跳', gender: '男', age: 24, parentId: null},
    {id: 8, name: 'rap', gender: '男', age: 25, parentId: null},
  ]);
  const leftTable = ref(null);
  const rightTable = ref(null);
</script>

image.png

第二步: 初始化jsPlumb并設(shè)置可以連線的元素

引入jsplumb 并創(chuàng)建jsplumb實例,實例中大部分的配置主要是對箭頭的樣式配置,具體參數(shù)信息可以查看官網(wǎng)。

import { jsPlumb } from 'jsplumb'
let instance = null;
function init() {  
  instance = jsPlumb.getInstance({  
    Connector: "Straight", //連接線形狀 Bezier: 貝塞爾曲線 Flowchart: 具有90度轉(zhuǎn)折點的流程線 StateMachine: 狀態(tài)機 Straight: 直線  
    PaintStyle: { strokeWidth: 3, stroke: "#dfbee7" }, //連接線樣式  
    Endpoint: ["Blank", { radius: 1 }], //端點  
    anchor: 'Right',  
    // 繪制箭頭  
    Overlays: [['Arrow', { width: 12, length: 12, location: 1 }]],  
    EndpointStyle: { fill: "#000000" }, //端點樣式  
    Container: "container", //目標容器id  
    ListStyle: {  
      endpoint: ["Rectangle", { width: 30, height: 30 }],  
    },  
  });  
}

由于業(yè)務(wù)的需求是只能從左側(cè)的數(shù)據(jù)連接到右側(cè)的數(shù)據(jù),并且有子項的那一行不能進行連接操作,所以我這邊要將左側(cè)的每行數(shù)據(jù)設(shè)置為起點右側(cè)為終點并過濾那些有子項的行,而設(shè)置起點和終點需要拿到對應(yīng)的元素或者標識,這時我們就需要給el-tablerow設(shè)置class名

<template>  
  <div class="line">  
    <div id="container" style="display: flex; justify-content: space-between; position: relative">  
      <el-table  
        ref="leftTable"  
        :data="leftTreeData"  
        :row-class-name="({row}) => `leftRow Id-${row.id}`"  
        style="width: 40%; margin-bottom: 20px; display: inline-block;"  
        row-key="id"  
        border  
        default-expand-all  
      >  
        <el-table-column prop="name" label="姓名"/>  
        <el-table-column prop="gender" label="性別"/>  
        <el-table-column prop="age" label="年齡"/>  
      </el-table>  
      <el-table  
        ref="rightTable"  
        :data="rightTreeData"  
        :row-class-name="({row}) => `rightRow Id-${row.id}`"  
        style="width: 40%; margin-bottom: 20px; display: inline-block;"  
        row-key="id"  
        border  
        default-expand-all  
      >  
        <el-table-column prop="name" label="姓名"/>  
        <el-table-column prop="gender" label="性別"/>  
        <el-table-column prop="age" label="年齡"/>  
      </el-table>  
    </div>  
  </div>  
</template>

我這里設(shè)置了兩個類名 leftRowrightRow 來區(qū)分他是左側(cè)還是右側(cè)的行,Id-${row.id}作為唯一標識讓我們能獲取到某一行元素

// 設(shè)置可以連線的元素
function setContainer() {  
  const leftElList = document.querySelectorAll('.leftRow'); // 左側(cè)行元素集合
  const rightElList = document.querySelectorAll('.rightRow');  // 右側(cè)行元素集合
  // 將dom元素設(shè)置為連線的起點或者終點 設(shè)置了起點的元素才能開始連線 設(shè)置為終點的元素才能為連線終點  
  instance.batch(function () {  
    [leftElList, rightElList].forEach((trList, index) => {  
      trList.forEach((tr) => {  
        const id = interceptId(tr.classList[2]);  
        if (index === 0) {  
          const item = leftData.value.find(i => i.id == id);  
          // 判斷是否有子項,若沒有則設(shè)置為起點  
          !item?.hasChild && instance.makeSource(tr, {  
            allowLoopback: false,  
            anchor: ["Right"], // 設(shè)置端點位置  
            maxConnections: 1  
          });  
        } else {  
          const item = rightData.value.find(i => i.id == id);  
          // 判斷是否有子項,若沒有則設(shè)置為終點  
          !item?.hasChild && instance.makeTarget(tr, {  
            anchor: ["Left"],  
            maxConnections: 1  
          });  
        }  
      });  
    });  
  });  
}
// 截取元素類名中的id  
const interceptId = className => {  
  return className.slice(className.indexOf('-') + 1);  
}

然后我們在onMounted中調(diào)用這些方法就可以實現(xiàn)連線功能了

const initJsPlumb = () => {  
  jsPlumb.ready(function () {  
    // 初始化jsPlumb 創(chuàng)建jsPlumb實例  
    init();  
    // 設(shè)置可以為連線起點和連線終點的元素  
    setContainer();  
  });  
}
onMounted(() => {
  initJsPlumb();
})

連接.png

看!成功啦!

設(shè)置默認連線和刪除連線功能

const relationship = reactive([
  {sourceId: 4, targetId: 8}
])
// 設(shè)置默認連線  
function setConnect(relationship) {  
  setTimeout(() => {  
    relationship.forEach(function (data) {  
      // source是連線起點元素id target是連線終點元素id  
      instance.connect({  
        source: document.querySelector(`.Id-${data.sourceId}`),  
        target: document.querySelector(`.Id-${data.targetId}`)  
      });  
    });  
  })  
}  
//  綁定事件監(jiān)聽
function setEvent() {  
  // 連線事件  
  instance.bind("connection", function (connInfo, originalEvent) {  
    // connInfo是jsPlumb對象 可以打印出來康康有哪些東西  
    console.log(connInfo, originalEvent, 'connInfo')  
  });  
 // 點擊連接線刪除該條線  
 instance.bind('click', function (connection, originalEvent) {  
   instance.deleteConnection(connection);  
 })  
}
const initJsPlumb = () => {  
  jsPlumb.ready(function () {  
    // 初始化jsPlumb 創(chuàng)建jsPlumb實例  
    init();  
    // 設(shè)置可以為連線起點和連線終點的元素  
    setContainer();  
    // 設(shè)置默認連線  
    setConnect(relationship);  
    // 綁定事件監(jiān)聽  
    setEvent();  
  });  
}
onMounted(() => {
  initJsPlumb();
})

將上述代碼中的兩個函數(shù)一并放入到initJsPlumb函數(shù)中執(zhí)行即可

禁用el-table的expand功能

由于數(shù)據(jù)的結(jié)構(gòu)是樹結(jié)構(gòu)所以el-table在對含有子節(jié)點的行的最左側(cè)添加了展開收起功能的一個圖標按鈕,所以當(dāng)我們點擊它收縮后會改變原有的視圖結(jié)構(gòu),而jsplumb是用canvas繪制的線條,它的位置并不能實時更改,所以我的解決方案是利用el-tableexpand-change事件監(jiān)聽配合toggleRowExpansion方法實現(xiàn)不管用戶怎么操作都是展開的狀態(tài)。

連接01.png

<el-table  
  ref="leftTable"  
  :data="leftTreeData"  
  :row-class-name="({row}) => `leftRow Id-${row.id}`"  
  style="width: 40%; margin-bottom: 20px; display: inline-block;"  
  row-key="id"  
  border  
  default-expand-all  
  @expand-change="(row, expanded) => !expanded && leftTable?.toggleRowExpansion(row)"
>  
  <el-table-column prop="name" label="姓名"/>  
  <el-table-column prop="gender" label="性別"/>  
  <el-table-column prop="age" label="年齡"/>  
</el-table>  
<el-table  
  ref="rightTable"  
  :data="rightTreeData"  
  :row-class-name="({row}) => `rightRow Id-${row.id}`"  
  style="width: 40%; margin-bottom: 20px; display: inline-block;"  
  row-key="id"  
  border  
  default-expand-all  
  @expand-change="(row, expanded) => !expanded && rightTable?.toggleRowExpansion(row)"
>  
  <el-table-column prop="name" label="姓名"/>  
  <el-table-column prop="gender" label="性別"/>  
  <el-table-column prop="age" label="年齡"/>  
</el-table>

結(jié)言

到此這篇關(guān)于el-table和jsplumb實現(xiàn)連線功能的文章就介紹到這了,更多相關(guān)el-table jsplumb連線內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 詳解vue axios用post提交的數(shù)據(jù)格式

    詳解vue axios用post提交的數(shù)據(jù)格式

    這篇文章主要介紹了詳解vue axios用post提交的數(shù)據(jù)格式,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-08-08
  • 一篇文章帶你吃透Vuex3的狀態(tài)管理

    一篇文章帶你吃透Vuex3的狀態(tài)管理

    Vuex是一個專為Vue.js應(yīng)用程序開發(fā)的狀態(tài)管理模式,它采用集中式存儲管理應(yīng)用的所有組件的狀態(tài),并以相應(yīng)的規(guī)則保證狀態(tài)以一種可預(yù)測的方式發(fā)生變化,下面這篇文章主要給大家介紹了關(guān)于如何通過一篇文章帶你吃透Vuex3的狀態(tài)管理,需要的朋友可以參考下
    2022-07-07
  • Vue 頁面跳轉(zhuǎn)不用router-link的實現(xiàn)代碼

    Vue 頁面跳轉(zhuǎn)不用router-link的實現(xiàn)代碼

    這篇文章主要介紹了 Vue 頁面跳轉(zhuǎn)不用router-link的實現(xiàn)代碼,文中給大家介紹了vue router-link跳轉(zhuǎn)傳值示例,需要的朋友可以參考下
    2018-04-04
  • Vue3?Transition組件給頁面切換并加上動畫效果

    Vue3?Transition組件給頁面切換并加上動畫效果

    這篇文章主要給大家介紹了關(guān)于Vue3?Transition組件給頁面切換并加上動畫效果的相關(guān)資料,vue的過渡動畫主要是transition標簽的使用,配合css動畫實現(xiàn)的,需要的朋友可以參考下
    2023-06-06
  • element-ui中按需引入的實現(xiàn)

    element-ui中按需引入的實現(xiàn)

    這篇文章主要介紹了element-ui中按需引入的實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-12-12
  • Vue.js原理分析之observer模塊詳解

    Vue.js原理分析之observer模塊詳解

    這篇文章主要介紹了Vue.js中observer模塊的相關(guān)資料,文中通過原理分析介紹還是相對的詳細,相信對大家具有一定的參考價值,需要的朋友們下面來一起看看吧。
    2017-02-02
  • Vue的生命周期一起來看看

    Vue的生命周期一起來看看

    這篇文章主要為大家詳細介紹了Vue的生命周期,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助
    2022-02-02
  • vue+springboot實現(xiàn)圖形驗證碼Kaptcha的示例

    vue+springboot實現(xiàn)圖形驗證碼Kaptcha的示例

    圖形驗證碼是做網(wǎng)站常用的功能,本文主要介紹了vue+springboot實現(xiàn)圖形驗證碼Kaptcha的示例,具有一定的參考價值,感興趣的可以了解一下
    2023-11-11
  • Vue3 封裝 element-plus 圖標選擇器實現(xiàn)步驟

    Vue3 封裝 element-plus 圖標選擇器實現(xiàn)步驟

    這篇文章主要介紹了Vue3 封裝 element-plus 圖標選擇器,本文通過實例代碼給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2023-09-09
  • Vue實現(xiàn)用戶沒有登陸時,訪問后自動跳轉(zhuǎn)登錄頁面的實現(xiàn)思路

    Vue實現(xiàn)用戶沒有登陸時,訪問后自動跳轉(zhuǎn)登錄頁面的實現(xiàn)思路

    這篇文章主要介紹了Vue實現(xiàn)用戶沒有登陸時,訪問后自動跳轉(zhuǎn)登錄頁面,定義路由的時候配置屬性,這里使用needLogin標記訪問頁面是否需要登錄,本文通過實例代碼介紹的非常詳細,需要的朋友可以參考下
    2023-02-02

最新評論