element ui+vue2.0實(shí)現(xiàn)換膚并且自身寫的顏色也可以

問題:本地環(huán)境換膚可以玫氢,但是打包后發(fā)現(xiàn)自己寫的主題色值#409eff阳掐,并沒有被替換成功紊婉,只有element ui自身的主題色替換了

主要代碼如下:

//watch監(jiān)聽主題色變化
theme: {
      async handler(val) {
        const oldVal = this.chalk ? this.theme : ORIGINAL_THEME
        if (typeof val !== 'string') return
        const themeCluster = this.getThemeCluster(val.replace('#', ''))
        const originalCluster = this.getThemeCluster(oldVal.replace('#', ''))
        const $message = this.$message({
          message: '主題色切換中...',
          customClass: 'theme-message',
          type: 'success',
          duration: 0,
          iconClass: 'el-icon-loading',
        })
        const getHandler = (variable, id) => {
          return () => {
            const originalCluster = this.getThemeCluster(
              ORIGINAL_THEME.replace('#', '')
            )
            const newStyle = this.updateStyle(
              this[variable],
              originalCluster,
              themeCluster
            )
            let styleTag = document.getElementById(id)
            if (!styleTag) {
              styleTag = document.createElement('style')
              styleTag.setAttribute('id', id)
              document.head.appendChild(styleTag)
            }
            styleTag.innerText = newStyle
          }
        }
        if (!this.chalk) {
          const url = `https://unpkg.com/element-ui@${version}/lib/theme-chalk/index.css`
          await this.getCSSString(url, 'chalk')
        }
        const chalkHandler = getHandler('chalk', 'chalk-style')
        chalkHandler()
        /**++++++++++++++++++++++++++++++++++++++++++++++++ */
        //為解決生產(chǎn)環(huán)境中切換主題色失敗
        if (!this.flag && process.env.NODE_ENV === 'production') {
          //判斷是否是第一次打開頁面
          this.flag = true
          ;[].slice
            .call(document.querySelectorAll('link')) //獲取所有的link鏈接
            .forEach(async (item) => {
              if (item.rel === 'stylesheet' || item.as === 'style') {
                //判斷是否是 css
                const { data } = await axios.get(item.href) // 重新獲取到 css 的內(nèi)容
                if (
                  new RegExp(oldVal, 'i').test(data) && // 判斷是否需要換膚
                  !/Chalk Variables/.test(data) // 判斷是否是 element-ui 的 css 前面已經(jīng)進(jìn)行處理了這里忽略
                ) {
                  item.remove() // 移出 link
                  const style = document.createElement('style') // 創(chuàng)建 style
                  style.innerText = data // 把 link 的內(nèi)容添加到 style 標(biāo)簽中
                  // 更新背景圖會(huì)導(dǎo)致路徑錯(cuò)誤会油,忽略更新烙无。
                  style.innerText = data.replace(
                    /url\(..\/..\/static/g,
                    'url(static'
                  )
                  style.isAdd = true // 為后面判斷是否是 link 生成的style录豺,方便標(biāo)識(shí)加入到頭部head中
                  styles.push(style)
                  this.stylesRender(styles, originalCluster, themeCluster) // 樣式渲染
                }
              }
            })
        }
        /**++++++++++++++++++++++++++++++++++++++++++++++++ */
        // 篩選需要修改的style
        const styles = [].slice
          .call(document.querySelectorAll('style'))
          .filter((style) => {
            const text = style.innerText
            return (
              new RegExp(oldVal, 'i').test(text) &&
              !/Chalk Variables/.test(text)
            )
          })
        this.styleRender(styles, originalCluster, themeCluster)
        this.$emit('change', val)

        $message.close()
      },
      immediate: true,
    },
     // 遍歷修改所有需修改的style
    styleRender(styles, originalCluster, themeCluster) {
      styles.forEach((style) => {
        const { innerText } = style
        if (typeof innerText !== 'string') return
        style.innerText = this.updateStyle(
          innerText,
          originalCluster,
          themeCluster
        )
        //打包后的link轉(zhuǎn)換的style
        if (style.isAdd) {
          // 如果是通過 link 創(chuàng)建的style 就添加到head中
          style.isAdd = false
          document.head.appendChild(style)
        }
      })
    },
    //更新 <style>
     updateStyle(style, oldCluster, newCluster) {
      let newStyle = style
      oldCluster.forEach((color, index) => {
        newStyle = newStyle.replace(new RegExp(color, 'ig'), newCluster[index])
      })
      return newStyle
    },
    //修改lin引入的css
    getCSSString(url, variable) {
      return new Promise((resolve) => {
        const xhr = new XMLHttpRequest()
        xhr.onreadystatechange = () => {
          if (xhr.readyState === 4 && xhr.status === 200) {
            this[variable] = xhr.responseText.replace(/@font-face{[^}]+}/, '')
            resolve()
          }
        }
        xhr.open('GET', url)
        xhr.send()
      })
    },
    //獲取顏色集
    getThemeCluster(theme) {
      const tintColor = (color, tint) => {
        let red = parseInt(color.slice(0, 2), 16)
        let green = parseInt(color.slice(2, 4), 16)
        let blue = parseInt(color.slice(4, 6), 16)

        if (tint === 0) {
          // when primary color is in its rgb space
          return [red, green, blue].join(',')
        } else {
          red += Math.round(tint * (255 - red))
          green += Math.round(tint * (255 - green))
          blue += Math.round(tint * (255 - blue))

          red = red.toString(16)
          green = green.toString(16)
          blue = blue.toString(16)

          return `#${red}${green}${blue}`
        }
      }

      const shadeColor = (color, shade) => {
        let red = parseInt(color.slice(0, 2), 16)
        let green = parseInt(color.slice(2, 4), 16)
        let blue = parseInt(color.slice(4, 6), 16)

        red = Math.round((1 - shade) * red)
        green = Math.round((1 - shade) * green)
        blue = Math.round((1 - shade) * blue)

        red = red.toString(16)
        green = green.toString(16)
        blue = blue.toString(16)

        return `#${red}${green}${blue}`
      }
      const clusters = [theme]
      for (let i = 0; i <= 9; i++) {
        clusters.push(tintColor(theme, Number((i / 10).toFixed(2))))
      }
      clusters.push(shadeColor(theme, 0.1))
      return clusters
    },

為了解決上面的問題:我主要加的代碼在加注釋那一塊跷车,上面的問題出現(xiàn)的原因在于链方,
1牵现、打包后的css為link形式铐懊,而我的換膚時(shí)主要篩選的是style樣式,然后進(jìn)行替換瞎疼。因此我判斷是否是生產(chǎn)環(huán)境并且是第一次進(jìn)來科乎,然后將link樣式轉(zhuǎn)為style,通過axios請(qǐng)求獲得link下的內(nèi)容,成功后移除了link贼急,創(chuàng)建style茅茂,并把獲得的內(nèi)容賦予給style

item.remove() // 移出 link
const style = document.createElement('style') // 創(chuàng)建 style
style.innerText = data // 把 link 的內(nèi)容添加到 style 標(biāo)簽中

2捏萍、然后我打了一個(gè)包,發(fā)現(xiàn)我的自己寫的顏色值#409eff都被換成我想要的主題色空闲,但是另一個(gè)問題來了令杈,我的背景圖片加載失敗了。我去f12看了下碴倾,我的圖片路徑變成了../../static逗噩。于是我只能在轉(zhuǎn)換style的時(shí)候手動(dòng)的改下路徑

// 更新背景圖會(huì)導(dǎo)致路徑錯(cuò)誤,忽略更新跌榔。
style.innerText = data.replace(/url\(..\/..\/static/g,'url(static')

3异雁、再次打了一個(gè)包,終于都可以正常顯示了僧须,真的是坎坷纲刀。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市担平,隨后出現(xiàn)的幾起案子示绊,更是在濱河造成了極大的恐慌,老刑警劉巖暂论,帶你破解...
    沈念sama閱讀 211,290評(píng)論 6 491
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件耻台,死亡現(xiàn)場離奇詭異,居然都是意外死亡空另,警方通過查閱死者的電腦和手機(jī)盆耽,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,107評(píng)論 2 385
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來扼菠,“玉大人摄杂,你說我怎么就攤上這事⊙埽” “怎么了析恢?”我有些...
    開封第一講書人閱讀 156,872評(píng)論 0 347
  • 文/不壞的土叔 我叫張陵,是天一觀的道長秧饮。 經(jīng)常有香客問我映挂,道長,這世上最難降的妖魔是什么盗尸? 我笑而不...
    開封第一講書人閱讀 56,415評(píng)論 1 283
  • 正文 為了忘掉前任柑船,我火速辦了婚禮,結(jié)果婚禮上泼各,老公的妹妹穿的比我還像新娘鞍时。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,453評(píng)論 6 385
  • 文/花漫 我一把揭開白布逆巍。 她就那樣靜靜地躺著及塘,像睡著了一般。 火紅的嫁衣襯著肌膚如雪锐极。 梳的紋絲不亂的頭發(fā)上笙僚,一...
    開封第一講書人閱讀 49,784評(píng)論 1 290
  • 那天,我揣著相機(jī)與錄音灵再,去河邊找鬼味咳。 笑死,一個(gè)胖子當(dāng)著我的面吹牛檬嘀,可吹牛的內(nèi)容都是我干的槽驶。 我是一名探鬼主播,決...
    沈念sama閱讀 38,927評(píng)論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼鸳兽,長吁一口氣:“原來是場噩夢啊……” “哼掂铐!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起揍异,我...
    開封第一講書人閱讀 37,691評(píng)論 0 266
  • 序言:老撾萬榮一對(duì)情侶失蹤全陨,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后衷掷,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體辱姨,經(jīng)...
    沈念sama閱讀 44,137評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,472評(píng)論 2 326
  • 正文 我和宋清朗相戀三年戚嗅,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了雨涛。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,622評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡懦胞,死狀恐怖替久,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情躏尉,我是刑警寧澤蚯根,帶...
    沈念sama閱讀 34,289評(píng)論 4 329
  • 正文 年R本政府宣布,位于F島的核電站胀糜,受9級(jí)特大地震影響颅拦,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜教藻,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,887評(píng)論 3 312
  • 文/蒙蒙 一距帅、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧怖竭,春花似錦锥债、人聲如沸陡蝇。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,741評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至广匙,卻和暖如春允趟,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背鸦致。 一陣腳步聲響...
    開封第一講書人閱讀 31,977評(píng)論 1 265
  • 我被黑心中介騙來泰國打工潮剪, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人分唾。 一個(gè)月前我還...
    沈念sama閱讀 46,316評(píng)論 2 360
  • 正文 我出身青樓抗碰,卻偏偏與公主長得像,于是被迫代替她去往敵國和親绽乔。 傳聞我的和親對(duì)象是個(gè)殘疾皇子弧蝇,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,490評(píng)論 2 348

推薦閱讀更多精彩內(nèi)容