您好,登錄后才能下訂單哦!
這篇“vue中如何實現(xiàn)一個換膚功能”文章的知識點大部分人都不太理解,所以小編給大家總結(jié)了以下內(nèi)容,內(nèi)容詳細(xì),步驟清晰,具有一定的借鑒價值,希望大家閱讀完這篇文章能有所收獲,下面我們一起來看看這篇“vue中如何實現(xiàn)一個換膚功能”文章吧。
1 色值的選取和原則
對于界面中的色彩元素,我們一般要保持視覺的連續(xù)性,即同一套色彩,盡量采取同一個色環(huán)上的色值
同一個圓環(huán)上的色值作為一套顏色會顯得更協(xié)調(diào)
所以這里采取ant design 的建議,取某一列色值作為我們的系列主題顏色(具體色值參照它的官網(wǎng)吧~)
而在某些特殊場合,需要表現(xiàn)出顏色的差異,如拋硬幣頁面的兩個顏色,
2 將格式色值轉(zhuǎn)換成十六進(jìn)制顏色值
這里我們通過設(shè)置主題顏色的透明度來實現(xiàn)區(qū)分不同顏色, 然后我們是通過存儲一個諸如 #123456 的16進(jìn)制顏色全局變量作為我們主題,這里就需要我們把這樣一個格式的色值轉(zhuǎn)化成 rgba 表示的顏色值啦,代碼如下,備用
hexToRgba (hex, opacity = 0.3) { let color = [] let rgb = [] hex = hex.replace(/#/, '') for (let i = 0; i < 3; i++) { color[i] = '0x' + hex.substr(i * 2, 2) rgb.push(parseInt(Number(color[i]))) } return `rgba(${rgb.join(',')},${opacity})` }
3 scss 的一些小眾用法
我們最終拿到這么一串我們想要的主題顏色
復(fù)制代碼 代碼如下:
$colors: #f04134, #00a854, #108ee9, #f5317f, #f56a00, #7265e6, #ffbf00, #00a2ae, #2e3238;
一個很直接的思路,我們需要在各個view頁面里面,去定義我們需要設(shè)置主題的元素的顏色,比如文字和icon的color, 以及頭部的background 等。 于是我們在app 里面定義一個color變量,派發(fā)到各個view組件里面去,通過這個全局的變量來控制所有路由頁面的顏色,以實現(xiàn)不同的主題效果。
派發(fā)的實現(xiàn)在下一個部分說,這里我們先來完成我們的第一步,我們可以容易提取出我們的需求:
4 設(shè)置并保存一個全局顏色
界面的小事:
我在首頁直接實現(xiàn)這個功能,項目中我引入了mint-ui 框架(餓了么團(tuán)隊的移動端框架,稍微遺憾使用感覺沒有element.ui 的舒服), 設(shè)置的交互就用彈層 mt-popup 的形式好了,然后直接點擊色塊便設(shè)置對應(yīng)顏色值
<!-- 設(shè)置顏色 --> <mt-popup v-model="changColor" position="bottom" class="color-panel"> <div class="color-items"> <span class="color-item" v-for="(item, $index) in colors" :key="$index" @click="chooseColor(item)"> <span class="color-cycle" :class="'bg-color' + ($index + 1)"></span> </span> </div> </mt-popup>
接著就是色塊div的呈現(xiàn),從上面代碼發(fā)現(xiàn),我會很容易出現(xiàn)類似這樣的css樣式表
.bg-color1 {background: #f04134} .bg-color2 {background: #f04134} .bg-color3 {background: #f04134} .bg-color4 {background: #f04134} ···
寫代碼時候如果我們一般發(fā)現(xiàn),一件類似的東西重復(fù)出現(xiàn)了,就總隱隱覺得可以開始表演了,然后可預(yù)見的是,這樣的情況意味著在項目增長后,還可能出現(xiàn)許多單一設(shè)置字體顏色或border顏色的樣式表,諸如color1, borderColor1···,這樣每種形式的表現(xiàn)我們都需要根據(jù)我們主題顏色的數(shù)組去逐條書寫,修改成本也會變高 。于是我的書寫風(fēng)格是這樣的,
// mixin.scss: $colors: #f04134, #00a854, #108ee9, #f5317f, #f56a00, #7265e6, #ffbf00, #00a2ae, #2e3238; // setColor.vue: @import '~@/assets/mixin.scss'; ··· @for $i from 1 to 10 { .bg-color#{$i} { background-color: nth($colors, $i) } }
scss 除了常用的類名嵌套書寫外,還有許多···低調(diào)奢華的語法, 對于這類需要重復(fù)書寫的樣式類型,我的約定是添加一個scss變量在mixin 文件中, 在需要書寫重復(fù)循環(huán)樣式時候作為變量引入,并在書寫樣式時候,利用sass的循環(huán),引用其中對應(yīng)的值,這樣無論設(shè)置顏色的樣式怎么拓展和變化,變成顏色背景邊框都好,我都只需要維護(hù)一份mixin的的文件里的色值就行了, 同樣的實踐也可以應(yīng)用于項目里面字體大小和間距值的統(tǒng)一之類,總之我們多嘗試體驗下吧
5 邏輯的小事
這個項目里面localstorage 基本被當(dāng)成數(shù)據(jù)庫使用了,所以點擊色塊設(shè)置主題時候,我們假裝發(fā)出請求,在localstorage存儲我們改變的顏色就好了( ./static/api.json 是一個返回helloword 的json, 為了寫實在這里這么用,$bus 事件巴士下面說, 作用就是設(shè)置全局的主題顏色變量,localStorage 模擬我們把設(shè)置存儲到后臺,每次重新打開頁面就去獲取這些設(shè)置值), 目前為止,我們的設(shè)置頁面就大致完成了
// 假裝調(diào)用接口設(shè)置顏色 chooseColor (color) { this.$axios.get('./static/api.json') .then((data) => { this.$bus.$emit('set-theme', color) this.changColor = false localStorage.setItem('themeColor', color) }) .catch((data) => { console.log(data) }) }
6 事件巴士的運(yùn)用
在上一步最后我們有個關(guān)鍵的東西沒完成, this.$bus.$emit('set-theme', color) ,將選取的顏色設(shè)置到全局,我的代碼結(jié)構(gòu)是這樣的
子組件
<setColor> 是 home 頁面 的一個子組件,而在一開始我們已經(jīng)說了,我們想在我們在app.vue (home.vue和其他view的父組件) 里面定義一個color變量,派發(fā)到各個view組件里面去。 于是這其實就是個,從 setColor 觸發(fā) app.vue 的設(shè)置顏色事件, 子組件向父組件通信的問題。
我們可以很直接地用綁定事件配合 emit() 的做法,在 app.vue 定義一個 setglobalColor 方法, 并綁定到router-view(包含了home.vue),接著在home組件繼續(xù)定義一個 setglobalColor 方法, 實現(xiàn)的功能就是 emit('setglobalColor') 去觸發(fā)app.vue的方法, 并把 home.vue 的這個 setglobalColor 繼續(xù)綁定到組件, 組件里面點選顏色時候,直接emit這個方法就行了。
為什么我想用事件巴士.vue 的事件巴士和 vuex, 在一些有追求的程序員手里總是小心翼翼的,我也一樣,因為作為涉及全局的東西,一般覺得能不用就不用,代碼能精簡就精簡,我們經(jīng)常用一個詞,不提倡。
可是有朝一日我經(jīng)常在想,代碼的可讀性可維護(hù)性,和性能以及“風(fēng)險”相對比,到底哪個更重要。對于事件巴士和vuex 這類全局性質(zhì)的方案的主要擔(dān)憂大部分在于, 他們是全局的,可能因為一個事件名變量名一致就造成沖突,在小型項目還會造成冗余和額外開銷。 但事實上,事件和變量的命名我們都可以通過約定去規(guī)范,而在表現(xiàn)上,使用了事件巴士和vuex的項目,在性能上和直接 props 傳遞數(shù)據(jù),emit 回調(diào)事件的項目相比,其實并沒有太大區(qū)別,反而是無止境的 props 和 emit ,給人一種麻煩難以維護(hù)的感覺。 像上述的 setglobalColor , 僅僅是跨越了兩層組件, 過程就顯得繁瑣了。所以我建議在出現(xiàn)兩級以上組件層次,數(shù)據(jù)流稍微多的項目中都可以這么去做,定義一個全局的事件巴士
export default (Vue) => { let eventHub = new Vue() Vue.prototype.$bus = { $on (...arg) { eventHub.$on(...arg) }, $off (...arg) { eventHub.$off(...arg) }, $emit (...arg) { eventHub.$emit(...arg) } } }
將事件巴士綁定到當(dāng)前vue對象,使用時候只需要:
this.$bus.$on('set-theme', (color) => {··· }) this.$bus.$emit('set-theme', '#000000')
在這個demo中,我在app.vue 綁定了
this.$bus.$on('set-theme', (color) => { this.loadingColor = color this.userinfo.color = color })
而在 setColor.vue 則在點擊顏色塊時候觸發(fā) this.$bus.$emit('set-theme', color), 則能實現(xiàn)我們設(shè)置全局顏色的效果。這樣的好處在于,對于跨了多個層次,或者兄弟組件的通信,我們不再需要太繁瑣的props,比如我在header.vue 也綁定了 this.$bus.$on('set-theme', (color) => { }) ,在 this.$bus.$emit 發(fā)生時候,header 的背景顏色就能直接改變,而不需要等待app.vue 將 全局的color值props傳遞到header.vue里面(僅做示例,這里 header.vue 只是 app.vue 的下一層級,通過props數(shù)據(jù)流會更清晰)
而對于其他路由頁面組件,和 app.vue 都是直接上下級關(guān)系,我們依然采用props保持一個清晰的數(shù)據(jù)流向下傳遞, demo 里我是將 color 存在userinfo(以后還有其他數(shù)據(jù)), userinfo傳到每個子路由, 最后,每個頁面在創(chuàng)建時候,通過拿到這個全局的顏色,再用dom去更改對應(yīng)的樣式就好啦,例如
mounted () { this.$nextTick(() => { // 綁定設(shè)置主題的事件,一旦觸發(fā)修改主題,則將當(dāng)前字體顏色改為對應(yīng)顏色 this.$el.querySelector('.myTitle').style.color = this.userinfo.color this.$el.querySelector('.weui-btn_primary').style.backgroundColor = this.userinfo.color this.$el.querySelector('.add_icon').style.color = this.userinfo.color }) }
以上就是關(guān)于“vue中如何實現(xiàn)一個換膚功能”這篇文章的內(nèi)容,相信大家都有了一定的了解,希望小編分享的內(nèi)容對大家有幫助,若想了解更多相關(guān)的知識內(nèi)容,請關(guān)注億速云行業(yè)資訊頻道。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。