感受此次去北京參加的前端星計劃,收穫很是的大,特別是月影大大講的js課程,讓我感受再次以前根本就沒有學到js的精髓,一直都是在爲了完成某個頁面而去寫這個頁面,根本沒有去考慮這個頁面接下來的維護,全部的變量所有都耦合在一塊兒,爲了改一個點,你須要該無數地方的代碼。而後在更多的時候都是在寫重複的代碼,根本沒有考慮到組件的複用的問題。而後對es6不少新的方法都沒有接觸過。總而言之,就是本身太菜了,還要加把勁的學習。css
在編寫一個組件的時候你先須要把組件的樣式給寫出來,好比說,咱們要作一個輪播的組件,而後就是幾張圖片疊加在一塊兒,須要哪張圖片就顯示哪張圖片,這個是基礎的樣式。html
輪播圖的切換動畫使用 css transition前端
在你想好要作組件以前,你須要對這個組件進行api的設置。建一個類,而後在類中寫各類須要的方法。
es6
在類之中的方法之間仍是會有必定的耦合,這樣的話能夠採用自定義事件的方法,只須要綁定事件就能夠web
控制結構小程序
<a class="slide-list__next"></a> <a class="slide-list__previous"></a> <div class="slide-list__control"> <span class="slide-list__control-buttons--selected"></span> <span class="slide-list__control-buttons"></span> <span class="slide-list__control-buttons"></span> <span class="slide-list__control-buttons"></span> </div>
自定義事件api
const detail = {index: idx} const event = new CustomEvent('slide', {bubbles:true, detail}) this.container.dispatchEvent(event)
在完成上面的後你還能夠進行各類優化,好比說,依賴注入,把每個小插件做爲一個依賴注入到組件中,須要這個依賴就注入一下就好,不須要就不要管他。代碼也不會報錯。而後你還能夠進行插件化和模版化把每一個依賴的小插件的html代碼寫在js中,只有使用了這個插件纔會渲染這段代碼。dom
大概寫出來是這個樣子,左邊是輸入框,經過輸入框輸入能夠改變右邊的進度,而後右邊是能夠拖動的拖動條,拖動後能夠改變左邊的輸入框的值。ide
這個組件大概包括如下的幾個接口函數
因爲須要數據雙向綁定,這裏使用的方法是,在你改變數據的時候不是直接改變數據,而是調用setData方法來改變數據,調用setData方法裏面會調用數據的渲染方法,就和小程序同樣,這樣改變數據纔會激活視圖的更新。
而後clickDot是實現點擊小圓點來拖動的效果。對小圓點設置一個mousedown事件,發生按下去的事件後對窗口設置一個mousemove事件隨時改變小圓點的位置,當鬆開的時候就清楚mousemove事件。
同時在小圓點動的時候激活一個自定義的移動事件,爲了響應的更改input中的數據。
改變進度和小圓點的位置的時候,所有依賴的是定義的數據,因此渲染界面只須要setData一下就能夠了。
而後對於輸入框,若是界面改變了,就會激活自定義事件,監聽一下,而後經過getPercentage來得到當前的數據。若是輸入框裏面的值變了,而後調用setData方法就行了。
這是第一次使用類的方式來寫組件,基本實現了數據的雙向綁定,而後在new的時候你能夠配置一些基本的參數,而後還學會了自定義事件,在此以前是經過回調函數來實現的。可是仍是有許多須要改進的地方,組件還能夠細分紅幾個小的插件,在新建的時候就能夠經過依賴注入的方式來注入想要的插件
<div id="control"> <div class="sensitivity" id="sensitivity"> <div class="line" id="line"> <div class="progress" id="progress"></div> </div> <div class="dot"></div> </div> </div>
*{ margin: 0; padding: 0; } .sensitivity { width: 100px; position: relative; } .line { width: 100%; height: 2px; background-color: #cccccc; border-radius: 1px; overflow: hidden; } .progress { height: 2px; width: 0; background-color: #57A3F3; -webkit-transition: all .2s; -moz-transition: all .2s; -ms-transition: all .2s; -o-transition: all .2s; transition: all .2s; } .dot { cursor: pointer; height: 6px; width: 6px; border: 2px solid #57A3F3; box-sizing: border-box; background-color: #ffffff; border-radius: 50%; position: absolute; top: -2px; left: -3px; -webkit-transition: all .2s; -moz-transition: all .2s; -ms-transition: all .2s; -o-transition: all .2s; transition: all .2s; } .dot:hover { cursor: pointer; border: 1px solid #57A3F3; }
class Slide { constructor(dot, progress, father) { this.data = 0; //判斷是否存在 this.dot = dot; this.progress = progress; //父組件 this.father = father; } //設置數據 setData(data) { this.data = data; this.setPercentage() } //渲染方法 render() { this.clickDot(); } //全部監聽事件來控制拖動條 clickDot() { let sensitivity = this.father.querySelector(".sensitivity"); let dot = this.father.querySelector(".sensitivity .dot"); //自定義事件,經過監聽事件來從新渲染dom const slideEvent = new CustomEvent("slide"); dot.addEventListener("mousedown", (e) => { document.onmousemove = (e) => { //設置data this.setData((e.clientX - sensitivity.offsetLeft) / sensitivity.offsetWidth * 100); document.dispatchEvent(slideEvent); }; document.onmouseup = () => { document.onmousemove = null; } }); } //設置百分數來改變進度 setPercentage() { if (this.data < 0) { this.data = 0; } if (this.data > 100) { this.data = 100; } let sensitivityWidth = this.father.querySelector(".sensitivity").offsetWidth; if (this.dot) { this.setDot(this.data * sensitivityWidth * 0.01 - 3 + 'px'); } if (this.progress) { this.setProgress(this.data * sensitivityWidth * 0.01 + "px"); } } //獲得當前的百分數 getPercentage() { return this.data; } //設置點的位置 setDot(position) { let dot = this.father.querySelector(".sensitivity .dot"); if (dot) { dot.style.left = position; } } //設置進度的位置 setProgress(position) { let progress = this.father.querySelector(".sensitivity .progress"); if (progress) { progress.style.width = position; } } }
let father = document.querySelector("#control"); let a = new Slide(true, true, father); a.render(); document.addEventListener("slide", (e) => { document.querySelector("#input").value = parseInt(a.getPercentage()); }); //監聽輸入框改變 document.querySelector("#input").onkeyup = () => { a.setData(document.querySelector("#input").value) }