成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

基于vue的簡(jiǎn)單流程圖開發(fā)

willin / 2934人閱讀

摘要:拖了這么久,現(xiàn)在終于要開始硬著頭皮寫一篇基于的流程圖偽教程文章了。本教程主要講述一個(gè)基于如何實(shí)現(xiàn)一個(gè)簡(jiǎn)單的流程圖,更多引發(fā)的思考是,什么項(xiàng)目更適合使用這種模式的框架,以及如何發(fā)揮的價(jià)值。

嚴(yán)重拖延癥,一方面這項(xiàng)目模塊純屬個(gè)人娛樂(lè)。另一方面,流程圖這塊涉及的東西還是蠻多的,這次也只是介紹一些簡(jiǎn)單的部分。拖了這么久,現(xiàn)在終于要開始硬著頭皮寫一篇基于vue+svg的流程圖"偽教程"文章了。初次獻(xiàn)丑,還請(qǐng)輕噴。

模塊簡(jiǎn)介

項(xiàng)目地址

出于學(xué)習(xí)vue而非兼容的目的,本項(xiàng)目?jī)H考慮現(xiàn)代瀏覽器( 谷歌 ),部分兼容問(wèn)題還請(qǐng)見(jiàn)諒。

本模塊的開發(fā)源于對(duì)流程圖的簡(jiǎn)單需求( 純UI實(shí)現(xiàn),暫不存在業(yè)務(wù)邏輯 ),這里不贅訴vue-cli生成的目錄結(jié)構(gòu)(可以參考這篇或自行谷歌)。

項(xiàng)目實(shí)際用到的技術(shù)棧:SVG + vue + vuex

功能介紹:

畫布縮放

節(jié)點(diǎn)( 開始,基礎(chǔ),判斷等 )添加,刪除

節(jié)點(diǎn)間連線( 直線/折線 )

文本添加

外部導(dǎo)入SVG圖形

撤銷與重做

畫布縮放

考慮到畫布縮放后布局需保持一致,這里通過(guò)修改transform: scale(); transform-origin: ; 來(lái)實(shí)現(xiàn),節(jié)點(diǎn)則相對(duì)父層定位。

TODO: SVG最優(yōu)縮放解決方案?

節(jié)點(diǎn)相關(guān)

下面我簡(jiǎn)單說(shuō)一下思路:

由于不存在業(yè)務(wù)邏輯,我把流程圖簡(jiǎn)化為 開始 基礎(chǔ) 判斷 3個(gè)基礎(chǔ)組件( 基于SVG )。

如:

這里說(shuō)一下判斷這個(gè)組件( 后期可能出現(xiàn)復(fù)雜形狀均以path實(shí)現(xiàn) ),一般由AI軟件直接導(dǎo)出相關(guān)形狀。

左邊工具欄跟畫布中的相同圖形源于同個(gè)組件,故設(shè)有兩個(gè)樣式,即 defaultStyledrawStyle。之前有考慮過(guò),如果流程圖的圖形復(fù)雜多變的話,那這種模式豈不是每一個(gè)組件都得人為定義。同樣,采用導(dǎo)入SVG也有類似問(wèn)題。因?yàn)槿绻麍D形大小都不確定的話,除了支持圖形修改大小,否者將導(dǎo)致畫布出現(xiàn)大小不一的圖形。( 非常遺憾這方面沒(méi)有做出突破,不過(guò)這將成為未來(lái)改進(jìn)的方向。)

最開始采用的解決方案是以scale的方式,也就是統(tǒng)一讓工具欄中的圖形跟拖入畫布中的圖形成等比縮放關(guān)系。不過(guò)該方式會(huì)造成stroke也同比縮放,并非我們想要的。

所以目前暫時(shí)采用寫死的方式。

注意: 在svg中 ellipse 定位相對(duì)于中心點(diǎn),而rect定位是相對(duì)于左上角。

TODO是否有辦法將各組件定位源點(diǎn)設(shè)置為組件中心點(diǎn)。

節(jié)點(diǎn)渲染

節(jié)點(diǎn)渲染方面,由于之前是將圖形作為組件,于是采用 component + is 的方式來(lái)渲染圖形。同時(shí)也是以數(shù)據(jù)驅(qū)動(dòng)的方式來(lái)渲染,即數(shù)據(jù)決定視圖。

 

拖動(dòng)節(jié)點(diǎn)涉及鏡像節(jié)點(diǎn)時(shí):

代碼直通車

新增節(jié)點(diǎn)

drag drop 的形式。采用該方式的好處是不需要模擬拖拽事件。也就是鏡像什么的不需要自己做。( 畫布內(nèi)節(jié)點(diǎn)拖拽則使用原生模擬 )

代碼直通車

對(duì)節(jié)點(diǎn)的操作均以指令( directives )的形式( 直接操作DOM )。這引發(fā)了我對(duì)該類項(xiàng)目是否適合用vue類框架來(lái)做的疑問(wèn),從開發(fā)效率方面,還是首選vue,但是從性能方面,由于沒(méi)有深入研究,并沒(méi)有發(fā)言權(quán)。

TODO 場(chǎng)景模擬,假設(shè)我們需要移動(dòng)畫布內(nèi)節(jié)點(diǎn),通過(guò)directives的el來(lái)獲取節(jié)點(diǎn),然后通過(guò)el.onmousemove來(lái)修改data中對(duì)應(yīng)的translate來(lái)實(shí)現(xiàn)位置的更改。這里修改data來(lái)驅(qū)動(dòng)視圖是我們常用的方式,但是我想不通的就是el.onmousemove來(lái)修改data實(shí)現(xiàn)的雙向數(shù)據(jù)綁定所帶來(lái)的性能在這里是否有體現(xiàn)。

我所設(shè)想的是,是否涉及多依賴的時(shí)候,diff帶來(lái)的性能提升才有價(jià)值。舉個(gè)例子,我有一個(gè)列表,存在于data中的listData,然后在view中有多處關(guān)聯(lián)listData。那此時(shí)操作listData比直接操作DOM來(lái)得更好些。

看過(guò)相關(guān)vitrualDOM的介紹,通過(guò)diff可以只操作變化的DOM。

獲取SVG大小

獲取節(jié)點(diǎn)大小使用 getBoundingClientRect ,同時(shí)由于前面做了縮放功能,這里獲取節(jié)點(diǎn)大小時(shí)需要除以縮放比例來(lái)獲取正確值。

let obj = el.getElementsByTagName("g")[0]
let w = obj.getBoundingClientRect().width / _this.drawStyle.zoomRate
let h = obj.getBoundingClientRect().height / _this.drawStyle.zoomRate
let wh = {
    width: w,
    height: h
}

代碼直通車

節(jié)點(diǎn)操作總結(jié)

由于節(jié)點(diǎn)的顯示是基于NodeData,所以增刪其實(shí)就是對(duì)NodeData的增刪。

主要代碼

連線相關(guān)

連線其實(shí)也只是用到了svg的linepolyline,這里跟節(jié)點(diǎn)類似,均以組件的形式存在,并以lineData驅(qū)動(dòng)連線視圖。所以最終連線的增刪也是對(duì)數(shù)據(jù)的操作。

連接點(diǎn)的顯示

首先是鏈接點(diǎn)的位置( 綠色遠(yuǎn)點(diǎn)位置 ),之前基于jquery做的流程圖是用div布局,現(xiàn)在用svg增加了難度,由于svg不能使用position,所以無(wú)法基于當(dāng)前元素定位。采用的是土辦法,即用圖形大小+padding動(dòng)態(tài)獲取4個(gè)點(diǎn)的位置。期間,由于4個(gè)連線節(jié)點(diǎn)與圖形節(jié)點(diǎn)有空隙,當(dāng)mouseover不處于圖形或節(jié)點(diǎn)時(shí),事件無(wú)法觸發(fā)。在此是模擬一個(gè)區(qū)域來(lái)解決的。由于個(gè)人經(jīng)驗(yàn)問(wèn)題,這部分代碼完全就是命令式的風(fēng)格。勿噴

代碼直通車
代碼直通車2

連接處理

節(jié)點(diǎn)間連線做了兩種情況:(這里不講訴從mousedown至mouseup具體細(xì)節(jié),可以看這里)

其實(shí)很多人說(shuō),算法可以解決很多垃圾代碼??上疫€沒(méi)掌握它的真諦,比如之前的圖形組件,以及接下來(lái)的不同線條。其實(shí)都可以通過(guò)一定的算法得出來(lái)。我這里只講講最笨的方法,待我成長(zhǎng)到能用算法來(lái)說(shuō)話的時(shí)候,在回來(lái)好好理下這篇文章。

line直線

直線無(wú)外乎就是兩個(gè)點(diǎn)坐標(biāo),通過(guò)svg中的line來(lái)顯示。這時(shí)候就得看項(xiàng)目的需求,我們假設(shè)最簡(jiǎn)單的情況,就是上面講到過(guò)的4個(gè)連接點(diǎn)最為連線的起始或結(jié)束點(diǎn)。
下面是計(jì)算圖形中4個(gè)點(diǎn)的坐標(biāo)位置

computeLine(direction, obj) { // low不止一點(diǎn)點(diǎn)
    let { top, left, width, height } = obj
    let w = width / 2
    let h = height / 2
    switch (direction) {
    case "t":
        top = top - h
        break
    case "b":
        top = top + h
        break
    case "l":
        left = left - w
        break
    case "r":
        left = left + w
        break
    default:
        break
    }
    return { top, left }
}

polyline折線

折線考慮的情況相對(duì)比較多一點(diǎn),這邊由于使用的是polyline,它的點(diǎn)位設(shè)置長(zhǎng)這樣子points="125,96 183.5,96 183.5,399 242,399"

這個(gè)時(shí)候一般會(huì)把字符轉(zhuǎn)化為較為好操作的數(shù)組或?qū)ο?。折線涉及的開始點(diǎn)跟結(jié)束點(diǎn)跟上面介紹直線的點(diǎn)位一樣,不同的是中間線的位置,如果不考慮復(fù)雜的情況,

一般可以分為兩種,上下,左右。通過(guò)獲取開始與結(jié)束點(diǎn)的中點(diǎn)位置來(lái)確定中線即可以得到想要的折線。代碼如下:(都是用簡(jiǎn)單粗暴的方式。)

computePolyLine(start, end, direction) {
    let startPoint = {
    x: +(start.split(",")[0]),
    y: +(start.split(",")[1])
    }
    let endPoint = {
    x: +(end.split(",")[0]),
    y: +(end.split(",")[1])
    }
    let m1, m2
    switch (direction) {
    case "t":
    case "b":
        let mY = startPoint.y + (endPoint.y - startPoint.y) / 2
        m1 = {
        x: startPoint.x,
        y: mY
        }
        m2 = {
        x: endPoint.x,
        y: mY
        }
        break
    case "l":
    case "r":
        let mX = startPoint.x + (endPoint.x - startPoint.x) / 2
        m1 = {
        x: mX,
        y: startPoint.y
        }
        m2 = {
        x: mX,
        y: endPoint.y
        }
        break
    default:
        break
    }
    return `${startPoint.x},${startPoint.y} ${m1.x},${m1.y} ${m2.x},${m2.y} ${endPoint.x},${endPoint.y}`
}
連線總結(jié)

節(jié)點(diǎn)跟連線在渲染以及操作的處理上大同小異,這里不確定是否為最佳實(shí)踐的有兩個(gè)地方,一是采用component+is的形式來(lái)渲染組件,二是采用 diretives的方式來(lái)操作DOM。連線的計(jì)算形式也略顯簡(jiǎn)單,這確實(shí)是需要一定時(shí)間來(lái)成長(zhǎng)的。扯偏了,在這簡(jiǎn)單總結(jié)一下,無(wú)論是哪種連線方式,我們需要做的就是正確獲取對(duì)應(yīng)點(diǎn)的位置,然后修改數(shù)據(jù)來(lái)驅(qū)動(dòng)視圖。不過(guò)能在各種復(fù)雜的情況下總結(jié)出算法,也是一種跨越,加油吧。

節(jié)點(diǎn)及連線的文本添加

節(jié)點(diǎn)及連線的文本添加原理都一樣,這里采用的是設(shè)置 contenteditable 當(dāng)contenteditable為true時(shí),html結(jié)構(gòu)自動(dòng)添加文本節(jié)點(diǎn)并且可編輯。更多細(xì)節(jié)可以參考張?chǎng)涡竦倪@篇

順道講一下pointer-events本模塊有兩個(gè)地方用到該css屬性。一個(gè)是文本添加這塊,以及頭部工具欄部分。

CSS屬性pointer-events允許作者控制特定的圖形元素在何時(shí)成為鼠標(biāo)事件的target。當(dāng)未指定該屬性時(shí),SVG內(nèi)容表現(xiàn)如同visiblePainted。

除了指定元素不成為鼠標(biāo)事件的目標(biāo),none值還指示鼠標(biāo)事件穿過(guò)該元素,并指向位于元素下面的元素。

更多細(xì)節(jié)關(guān)于pointer-events

張?chǎng)涡?br>MDN

TODO 文本編輯雖已實(shí)現(xiàn)功能,但這塊BUG較多,還未完善。

外部導(dǎo)入SVG

這邊也是用到了HTML5的Drop功能,顯示則是用到了svg的images。拖拽實(shí)現(xiàn)比較簡(jiǎn)單:

dropHandle (e) {
    let reader = new FileReader()
    let file = e.dataTransfer.files[0]
    reader.onload = (e) => {
        this.userImages.push(e.target.result)
    }
    reader.readAsDataURL(file)
},
dragoverHandle () {
},
dragstart (imgSrc) {
    event.dataTransfer.setData("URL", imgSrc)
}

這邊需要注意的是@drop.stop.prevent="dropHandle" @dragover.stop.prevent="dragoverHandle"要阻止冒泡以及阻止瀏覽器默認(rèn)行為。

還有一個(gè)要注意的是dataTransfer.getData()在dragover,dragenter,dragleave中無(wú)法獲取數(shù)據(jù)的問(wèn)題

根據(jù)W3C標(biāo)準(zhǔn),drag data store有三種模式,Read/write mode, Read-only mode跟Protected mode。細(xì)節(jié)

Read/write mode
讀/寫模式,在dragstart事件中使用,可以添加新數(shù)據(jù)到drag data store中。

Read-only mode
只讀模式,在drop事件中使用,可以讀取被拖拽數(shù)據(jù),不可添加新數(shù)據(jù)。

Protected mode
保護(hù)模式,在所有其他的事件中使用,數(shù)據(jù)的列表可以被枚舉,但是數(shù)據(jù)本身不可用且不能添加新數(shù)據(jù)。

深入

撤銷與重做

這一功能本質(zhì)上是沒(méi)有完成的,因?yàn)椴捎昧艘环N偷懶的方式,vuex 生成 State 快照,生產(chǎn)環(huán)境不建議使用。

基本原理就是通過(guò)vuex提交更高(mutation)來(lái)觸發(fā)回調(diào)。以此來(lái)記錄state 快照

代碼直通車

總結(jié)

本項(xiàng)目屬于入門級(jí)的vue+vuex,但是并沒(méi)有講如何使用vue或者vuex,因?yàn)檫@些在官方文檔其實(shí)都已經(jīng)講的非常清楚了。該項(xiàng)目也只是簡(jiǎn)單使用了如vue的自定義指令,MiXin等常用方法。諸如vue Render函數(shù)組件,不在本文談?wù)摲秶?,這里簡(jiǎn)單講下使用體驗(yàn),render組件比較適合高自定義的組件(變化邏輯比較復(fù)雜)。因?yàn)橐恍┖?jiǎn)單組件其實(shí)更適合用tempalte的形式,雖然使用Render可以提高一定的性能( 減少了從tempalte到render這一步 ),但是很多現(xiàn)有的如sync,是render組件所不具備的( 需自己實(shí)現(xiàn) )。vuex的使用,則需要注意的是object引用地址的問(wèn)題。也就是說(shuō),要避免數(shù)據(jù)間的潛在影響。(雖然vuex自身也有規(guī)避這個(gè)問(wèn)題)可以了解一下immutable 。

本教程主要講述一個(gè)基于vue如何實(shí)現(xiàn)一個(gè)簡(jiǎn)單的流程圖,更多引發(fā)的思考是,什么項(xiàng)目更適合使用這種MVVM模式的框架,以及如何發(fā)揮VitrualDOM的價(jià)值。其實(shí)上面幾個(gè)章節(jié)的點(diǎn)隨便拿個(gè)出來(lái)都可以深入探討出很多技術(shù)問(wèn)題,以后有機(jī)會(huì)再陸續(xù)深入。

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/51383.html

相關(guān)文章

  • 基于vue簡(jiǎn)單程圖開發(fā)

    摘要:拖了這么久,現(xiàn)在終于要開始硬著頭皮寫一篇基于的流程圖偽教程文章了。本教程主要講述一個(gè)基于如何實(shí)現(xiàn)一個(gè)簡(jiǎn)單的流程圖,更多引發(fā)的思考是,什么項(xiàng)目更適合使用這種模式的框架,以及如何發(fā)揮的價(jià)值。 嚴(yán)重拖延癥,一方面這項(xiàng)目模塊純屬個(gè)人娛樂(lè)。另一方面,流程圖這塊涉及的東西還是蠻多的,這次也只是介紹一些簡(jiǎn)單的部分。拖了這么久,現(xiàn)在終于要開始硬著頭皮寫一篇基于vue+svg的流程圖偽教程文章了。初次獻(xiàn)...

    hover_lew 評(píng)論0 收藏0
  • 大前端 - 收藏集 - 掘金

    摘要:是目前唯一一個(gè)支持同步調(diào)用的跨平臺(tái)年度上最多的個(gè)項(xiàng)目前端掘金年接近尾聲,在最近的幾篇文章中,會(huì)整理總結(jié)一些年度開源項(xiàng)目。 JS 全棧教程 - 前端 - 掘金本課程是基于阮一峰的 js 全棧教程的視頻版本,免費(fèi)供大家觀看... 2016 年 10 個(gè)最佳的 CodePen 作品 - 前端 - 掘金說(shuō)到 CodePen,前端開發(fā)者們肯定不會(huì)陌生。如果說(shuō) Dribbble 是設(shè)計(jì)師們聚集的圣...

    honhon 評(píng)論0 收藏0
  • Vue-book 2.0 一個(gè)移動(dòng)端簡(jiǎn)單全棧 web APP

    摘要:本項(xiàng)目是一個(gè)簡(jiǎn)單的全棧項(xiàng)目,前端新手可以拿來(lái)練練手。項(xiàng)目實(shí)現(xiàn)了一些簡(jiǎn)單的功能,后臺(tái)可以對(duì)圖書進(jìn)行錄入錄出掃碼或手動(dòng),前臺(tái)顯示錄入的圖書,并且前臺(tái)注冊(cè)登錄后可以將書的訂單發(fā)給服務(wù)器,并存到服務(wù)器。 Vue-book 2.0 Github 地址:https://github.com/percy507/v... 【覺(jué)得不錯(cuò)就來(lái)個(gè) star 吧 ^_^】 說(shuō)明(菜鳥請(qǐng)進(jìn),大神繞道 ~) 前端...

    wh469012917 評(píng)論0 收藏0
  • Vue-book 2.0 一個(gè)移動(dòng)端簡(jiǎn)單全棧 web APP

    摘要:本項(xiàng)目是一個(gè)簡(jiǎn)單的全棧項(xiàng)目,前端新手可以拿來(lái)練練手。項(xiàng)目實(shí)現(xiàn)了一些簡(jiǎn)單的功能,后臺(tái)可以對(duì)圖書進(jìn)行錄入錄出掃碼或手動(dòng),前臺(tái)顯示錄入的圖書,并且前臺(tái)注冊(cè)登錄后可以將書的訂單發(fā)給服務(wù)器,并存到服務(wù)器。 Vue-book 2.0 Github 地址:https://github.com/percy507/v... 【覺(jué)得不錯(cuò)就來(lái)個(gè) star 吧 ^_^】 說(shuō)明(菜鳥請(qǐng)進(jìn),大神繞道 ~) 前端...

    NotFound 評(píng)論0 收藏0
  • 前端每周清單:Node.js 微服務(wù)實(shí)踐,Vue.js 與 GraphQL,Angular 組件技巧

    摘要:前端每周清單第期微服務(wù)實(shí)踐,與,組件技巧,攻防作者王下邀月熊編輯徐川前端每周清單專注前端領(lǐng)域內(nèi)容,以對(duì)外文資料的搜集為主,幫助開發(fā)者了解一周前端熱點(diǎn)分為新聞熱點(diǎn)開發(fā)教程工程實(shí)踐深度閱讀開源項(xiàng)目巔峰人生等欄目。 前端每周清單第 26 期:Node.js 微服務(wù)實(shí)踐,Vue.js 與 GraphQL,Angular 組件技巧,HeadlessChrome 攻防 作者:王下邀月熊 編輯:徐川...

    wall2flower 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

閱讀需要支付1元查看
<