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

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

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

前言

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

準(zhǔn)備工作

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

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

新建一個(gè)line.vue文件,定義一個(gè)id為container的div標(biāo)簽,在這個(gè)標(biāo)簽內(nèi)放入兩個(gè)el-table,并根據(jù)定義的靜態(tài)數(shù)據(jù)進(jìn)行基礎(chǔ)的配置。需要注意的是el-table當(dāng) row 中包含 children 字段時(shí),被視為樹形數(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í)例,實(shí)例中大部分的配置主要是對(duì)箭頭的樣式配置,具體參數(shù)信息可以查看官網(wǎng)。

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

由于業(yè)務(wù)的需求是只能從左側(cè)的數(shù)據(jù)連接到右側(cè)的數(shù)據(jù),并且有子項(xiàng)的那一行不能進(jìn)行連接操作,所以我這邊要將左側(cè)的每行數(shù)據(jù)設(shè)置為起點(diǎn)右側(cè)為終點(diǎn)并過濾那些有子項(xiàng)的行,而設(shè)置起點(diǎn)和終點(diǎn)需要拿到對(duì)應(yīng)的元素或者標(biāo)識(shí),這時(shí)我們就需要給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è)置了兩個(gè)類名 leftRowrightRow 來(lái)區(qū)分他是左側(cè)還是右側(cè)的行,Id-${row.id}作為唯一標(biāo)識(shí)讓我們能獲取到某一行元素

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

然后我們?cè)?code>onMounted中調(diào)用這些方法就可以實(shí)現(xiàn)連線功能了

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

連接.png

看!成功啦!

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

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

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

禁用el-table的expand功能

由于數(shù)據(jù)的結(jié)構(gòu)是樹結(jié)構(gòu)所以el-table在對(duì)含有子節(jié)點(diǎn)的行的最左側(cè)添加了展開收起功能的一個(gè)圖標(biāo)按鈕,所以當(dāng)我們點(diǎn)擊它收縮后會(huì)改變?cè)械囊晥D結(jié)構(gòu),而jsplumb是用canvas繪制的線條,它的位置并不能實(shí)時(shí)更改,所以我的解決方案是利用el-tableexpand-change事件監(jiān)聽配合toggleRowExpansion方法實(shí)現(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實(shí)現(xiàn)連線功能的文章就介紹到這了,更多相關(guān)el-table jsplumb連線內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

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

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

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

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

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

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

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

    Vue3?Transition組件給頁(yè)面切換并加上動(dòng)畫效果

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

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

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

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

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

    Vue的生命周期一起來(lái)看看

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

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

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

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

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

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

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

最新評(píng)論