前端为什么要使用组件化的思想,通过一个实例来分析
在平時項目中,為什么我們都會采用組件化的思想去編寫代碼?
其實的原因很簡單!!! 我們在寫代碼的時候,寫完以后發(fā)現(xiàn)這個代碼會出現(xiàn)在其他地方,想要復用,或者同事感興趣,想使用這個代碼。這個時候我們就需要通過組件化來實現(xiàn)代碼的復用了,否則工作量真的是…
接下來通過一個例子大概分析一下:
這個是一個點贊的功能~ 如果給我寫,那 簡單 啊
HTML
<body><div class='wrapper'><button class='like-btn'><span class='like-text'>點贊</span><span>(假裝有一張手的小圖標)</span></button></div></body>JavaScript
const button = document.querySelector('.like-btn')const buttonText = button.querySelector('.like-text')let isLiked = falsebutton.addEventListener('click', () => {isLiked = !isLikedif (isLiked) {buttonText.innerHTML = '取消'} else {buttonText.innerHTML = '點贊'}}, false)代碼寫完以后,這時候你的同事跑過來了,說他很喜歡你的按鈕,他也想用你寫的這個點贊功能。這時候問題就來了,你就會發(fā)現(xiàn)這種實現(xiàn)方式很致命:你的同事要把整個 button 和里面的結構復制過去,還有整段 JavaScript 代碼也要復制過去。這樣的實現(xiàn)方式?jīng)]有任何可復用性。
實現(xiàn)簡單的組件化
這里有一個將字符串,變成DOM的函數(shù)
// ::String => ::Document const createDOMFromString = (domString) => {const div = document.createElement('div')div.innerHTML = domStringreturn div }按組件處理以后
class LikeButton {constructor () {this.state = { isLiked: false }}changeLikeText () {const likeText = this.el.querySelector('.like-text')this.state.isLiked = !this.state.isLikedlikeText.innerHTML = this.state.isLiked ? '取消' : '點贊'}render () {this.el = createDOMFromString(`<button class='like-button'><span class='like-text'>點贊</span><span>(假裝有一張手的小圖標)</span></button>`)this.el.addEventListener('click', this.changeLikeText.bind(this), false)return this.el}}
在別的地方使用組件
現(xiàn)在這個組件的可復用性已經(jīng)很不錯了,你的同事們只要實例化一下然后插入到 DOM 里面去就好了。
const wrapper = document.querySelector('.wrapper')const likeButton1 = new LikeButton()wrapper.appendChild(likeButton1.render())const likeButton2 = new LikeButton()wrapper.appendChild(likeButton2.render())一個組件的顯示多個狀態(tài)
一個組件的顯示形態(tài)由多個狀態(tài)決定的情況非常常見。代碼中混雜著對 DOM 的操作其實是一種不好的實踐,手動管理數(shù)據(jù)和 DOM 之間的關系會導致代碼可維護性變差、容易出錯。
這里要提出的一種解決方案:
一旦狀態(tài)發(fā)生改變,就重新調(diào)用 render 方法,構建一個新的 DOM 元素。 這樣做的好處是什么呢?好處就是你可以在 render 方法里面使用最新的 this.state 來構造不同 HTML 結構的字符串,并且通過這個字符串構造不同的 DOM 元素。頁面就更新了!聽起來有點繞,看看代碼怎么寫,修改原來的代碼為:
class LikeButton {constructor () {this.state = { isLiked: false }}setState (state) {const oldEl = this.elthis.state = statethis.el = this.render()if (this.onStateChange) this.onStateChange(oldEl, this.el)}changeLikeText () {this.setState({isLiked: !this.state.isLiked})}render () {this.el = createDOMFromString(`<button class='like-btn'><span class='like-text'>${this.state.isLiked ? '取消' : '點贊'}</span><span>(假裝有一張手的小圖標)</span></button>`)this.el.addEventListener('click', this.changeLikeText.bind(this), false)return this.el}}其實只是改了幾個小地方:
render 函數(shù)里面的 HTML 字符串會根據(jù) this.state 不同而不同(這里是用了 ES6
的模版字符串,做這種事情很方便)。
新增一個 setState 函數(shù),這個函數(shù)接受一個對象作為參數(shù);它會設置實例的
當用戶點擊按鈕的時候, changeLikeText 會構建新的 state
對象,這個新的 state ,傳入 setState 函數(shù)當中。
這樣的結果就是,用戶每次點擊,changeLikeText 都會調(diào)用改變組件狀態(tài)然后調(diào)用 setState ;setState 會調(diào)用 render ,render 方法會根據(jù) state 的不同重新構建不同的 DOM 元素。
也就是說,你只要調(diào)用 setState,組件就會重新渲染。我們順利地消除了手動的 DOM 操作。
在別的地方使用組件
const likeButton = new LikeButton() wrapper.appendChild(likeButton.render()) // 第一次插入 DOM 元素 likeButton.onStateChange = (oldEl, newEl) => {wrapper.insertBefore(newEl, oldEl) // 插入新的元素wrapper.removeChild(oldEl) // 刪除舊的元素 } 創(chuàng)作挑戰(zhàn)賽新人創(chuàng)作獎勵來咯,堅持創(chuàng)作打卡瓜分現(xiàn)金大獎總結
以上是生活随笔為你收集整理的前端为什么要使用组件化的思想,通过一个实例来分析的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 最强蜗牛怎么打败机器人 汉典最字的基本解
- 下一篇: 库乐队如何导出乐曲(10如何创建库)