vue中使用Element主題自定義膚色

来源:https://www.cnblogs.com/dengqichang/archive/2019/02/12/10364455.html
-Advertisement-
Play Games

一、搭建好項目的環境。 二、根據ElementUI官網的自定義主題(http://element.eleme.io/#/zh-CN/component/custom-theme)來安裝【主題生成工具】。 三、在 element-variables.scss 文件里修改 $–color-primary ...


一、搭建好項目的環境。

二、根據ElementUI官網的自定義主題(http://element.eleme.io/#/zh-CN/component/custom-theme)來安裝【主題生成工具】。

三、在 element-variables.scss 文件里修改 $–color-primary:#409EFF,即你想要的主題顏色。然後,執行主題編譯命令生成主題(et),根目錄會生成一個theme文件夾。

 

 四、封裝動態換膚色ThemePicker.vue組件。

 

<template>
  <el-color-picker
    class="theme-picker"
    popper-class="theme-picker-dropdown"
    v-model="theme"
    :size="size">
  </el-color-picker>
</template>

<script>

const version = require('element-ui/package.json').version // element-ui version from node_modules
const ORIGINAL_THEME = '#409EFF' // default color
export default {
  name: 'ThemePicker',
  props: {
    default: { // 初始化主題,可由外部傳入
      type: String,
      //default: '#EB815B'
      default: ""+localStorage.getItem("tremePackers")+""
    },
    size: { // 初始化主題,可由外部傳入
      type: String,
      default: 'small'
    }
  },
  data() {
    return {
      chalk: '', // content of theme-chalk css
      theme: ORIGINAL_THEME,
      showSuccess: true, // 是否彈出換膚成功消息
    }
  },
  mounted() {
    if(this.default != null) {
      this.theme = this.default
      this.$emit('onThemeChange', this.theme)
      this.showSuccess = false
    }
  },
  watch: {
    theme(val, oldVal) {
      if (typeof val !== 'string') return
      const themeCluster = this.getThemeCluster(val.replace('#', ''))
      const originalCluster = this.getThemeCluster(oldVal.replace('#', ''))
      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
        }
      }

      const chalkHandler = getHandler('chalk', 'chalk-style')

      if (!this.chalk) {
        const url = `https://unpkg.com/element-ui@${version}/lib/theme-chalk/index.css`
        this.getCSSString(url, chalkHandler, 'chalk')
      } else {
        chalkHandler()
      }

      const styles = [].slice.call(document.querySelectorAll('style'))
        .filter(style => {
          const text = style.innerText
          return new RegExp(oldVal, 'i').test(text) && !/Chalk Variables/.test(text)
        })
      styles.forEach(style => {
        const { innerText } = style
        if (typeof innerText !== 'string') return
        style.innerText = this.updateStyle(innerText, originalCluster, themeCluster)
      })

      // 響應外部操作
      this.$emit('onThemeChange', val)
      //存入localStorage
      localStorage.setItem('tremePackers',val);
      if(this.showSuccess) {
        this.$message({
          message: '換膚成功',
          type: 'success'
        })
      } else {
        this.showSuccess = true
      }
    }
  },
  methods: {
    updateStyle(style, oldCluster, newCluster) {
      let newStyle = style
      oldCluster.forEach((color, index) => {
        newStyle = newStyle.replace(new RegExp(color, 'ig'), newCluster[index])
      })
      return newStyle
    },

    getCSSString(url, callback, variable) {
      const xhr = new XMLHttpRequest()
      xhr.onreadystatechange = () => {
        if (xhr.readyState === 4 && xhr.status === 200) {
          this[variable] = xhr.responseText.replace(/@font-face{[^}]+}/, '')
          callback()
        }
      }
      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
    }
  }
}
</script>

<style>
.theme-picker .el-color-picker__trigger {
  vertical-align: middle;
}

.theme-picker-dropdown .el-color-dropdown__link-btn {
  display: none;
}
</style>

五、直接在組件中引用

 

 六、換膚效果測試。(關閉瀏覽器再次打開依舊是你所選中的主題膚色)

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 本文由雲+社區發表 作者:嘿嘿嘿 可能大家都知道,js執行會阻塞DOM樹的解析和渲染,那麼css載入會阻塞DOM樹的解析和渲染嗎?接下來,我就來對css載入對DOM樹的解析和渲染的影響做一個測試。 為了完成本次測試,先來科普一下,如何利用chrome來設置下載速度 \1. 打開chrome控制台(按 ...
  • 棧(stack) 、堆(heap)、 隊列(queue)是js的三種數據結構。 棧(stack) 棧的特點是"LIFO,即後進先出(Last in, first out)"。數據存儲時只能從頂部逐個存入,取出時也需從頂部逐個取出。《前端進擊的巨人(一):執行上下文與執行棧,變數對象》中解釋執行棧時, ...
  • new 操作符 做了什麼 new 運算符創建一個用戶定義的對象類型的實例或具有構造函數的內置對象的實例。 假設 是一個構造函數,通常在創建對象的實例時,要使用 ,eg: , 那麼在調用 的時候,發生了什麼呢? 步驟如下: 1.一個繼承自 Test.prototype 的新對象被創建。可以理解為: 2 ...
  • 一、用jquery動態綁定點擊事件的寫法 部分代碼: ...
  • 在此之前的項目開發中,發現利用正則方法能夠提高開發效率,所以看著教程和博客,自己重新學習了一遍正則,並記錄下來。 正則聲明 構造函數聲明方式 字面量聲明方式 tip:參數解釋: pattern:模式,要匹配的內容。 modifiers:修飾符 i:ignore。不區分大小寫的匹配 g:global。 ...
  • 主要是用於獲取焦點,自動把游標放到此組件上面,無須用戶再次操作。 示例: 輸入超過50字元長度的內容,會彈出一個提示對話框。當你點擊確定之後,游標會自動回到輸入框位置。這就是focus()的作用。 ...
  • 在開發微信小程式時,有一個消息推送,它的解釋是這樣的。 消息推送具體的內容是下麵的這個網址 https://developers.weixin.qq.com/miniprogram/dev/framework/server-ability/message-push.html,他介紹的也還可以,就是我 ...
  • try 語句測試代碼塊的錯誤。 catch 語句處理錯誤。 throw 語句創建自定義錯誤。 1. try/catch語句 catch語句用來捕獲try代碼塊中的錯誤,並執行自定義的語句來處理它。 語法: 2. throw語句 throw語句允許我們創建自定義錯誤 示例: ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...