整合營銷服務(wù)商

          電腦端+手機(jī)端+微信端=數(shù)據(jù)同步管理

          免費(fèi)咨詢熱線:

          2021系列-學(xué)好前端?請弄清CSS的這15件事(入

          2021系列-學(xué)好前端?請弄清CSS的這15件事(入門)

          前端開發(fā)社區(qū)中,被抱怨最多的恐怕就是CSS,因為它真心不容易學(xué)。但它功能強(qiáng)大,越深入挖掘CSS的潛能,你就越有機(jī)會像魔法師一樣釋放各種神奇魔力。

          無疑,學(xué)習(xí)CSS相關(guān)的基礎(chǔ)知識只是一方面,你還需要去學(xué)習(xí)CSS所具有創(chuàng)造力和可視化事物的能力,這就是本期我們規(guī)劃了推薦CSS這15個功能的原因。


          1 . HTML

          跑題了?開篇先說HTML而非CSS?注意!行內(nèi)人常說,HTML就像 一個人的骨骼與器官,而CSS就是皮膚,有了這兩樣再去注入靈魂(JS),所以,我想先強(qiáng)調(diào)下骨骼和器官的重要性。

          如果你先入手了HTML的所有基礎(chǔ)知識,自然CSS會變得更加容易。另外,通常我們要完成所需的樣式,就需要在方式上有選擇性的去構(gòu)造HTML;誠然,犧牲樣式的結(jié)構(gòu)和語義是走不通的,越好的CSS,理論上你的HTML結(jié)構(gòu)也應(yīng)是越好的,由此一個出色的Web開發(fā)人員應(yīng)該明白如何寫好UI,同時不會引入過多不必要的HTML,損害可訪問性或者讓內(nèi)容難以管理。


          2 . 盒模型

          記得之前Flutter有個說法叫“萬物皆Widget”,翻譯得不錯!對于 CSS,

          相關(guān)鏈接:https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Box_Model/Introduction_to_the_CSS_box_model

          盒子模型幾乎是學(xué)好CSS的一個"公開的秘密"——margin是你將box分開的距離(邊距),

          相關(guān)鏈接:https://developer.mozilla.org/en-US/docs/Web/CSS/margin

          border是邊框,

          相關(guān)鏈接:https://developer.mozilla.org/en-US/docs/Web/CSS/border

          padding是框內(nèi)內(nèi)容和邊框之間的間隔,這樣你的內(nèi)容可以是其他框或者文本。

          相關(guān)鏈接:https://developer.mozilla.org/en-US/docs/Web/CSS/padding

          談?wù)摵心P徒?jīng)常遺漏的一件事是輪廓(outline),它是位于邊框和邊距之間的線條,也是可以樣式化的。

          相關(guān)鏈接:https://developer.mozilla.org/en-US/docs/Web/CSS/outline

          3 . 特異性和級聯(lián)流程

          這個副標(biāo)題差不多就定義了CSS,CSS又叫級聯(lián)樣式表。

          編寫CSS時的頭號難題是某樣式被替換為第三方樣式或你自己的樣式。雖然現(xiàn)今已經(jīng)涌現(xiàn)出許多通過隔離樣式塊來解決類似問題的工具,但是最佳方法是理解和吃透問題本身,包括:瀏覽器以何種順序應(yīng)用樣式、如何去覆蓋第三方樣式、!important標(biāo)志相關(guān)問題等等。

          努力遵循CSS流程以及它的工作方式,且你還需要找到一個適合CSS結(jié)構(gòu),努力堅持使用。


          4 . 屬性選擇器、組合器、偽類以及偽元素

          選擇器可幫助你定位HTML;組合器可幫助你組合和定位模式;

          相關(guān)鏈接:https://developer.mozilla.org/en-US/docs/Learn/CSS/Building_blocks/Selectors/Combinators

          偽類可幫助你確定狀態(tài);

          相關(guān)鏈接:https://developer.mozilla.org/en-US/docs/Web/CSS/Pseudo-classes

          偽元素可幫助你確定或創(chuàng)建HTML的特定部分。

          相關(guān)鏈接:https://developer.mozilla.org/en-US/docs/Web/CSS/Pseudo-elements

          掌握這些對于成為CSS魔法師來說,至關(guān)重要。


          5 . 變量

          變量絕對將CSS帶入一個新的高度。雖然CSS具備一些有用的函數(shù),

          相關(guān)鏈接:https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Functions

          但離不開變量,因為變量使CSS更加強(qiáng)大......

          相關(guān)鏈接:https://developer.mozilla.org/en-US/docs/Web/CSS/Using_CSS_custom_properties

          譬如,變量引入了共享和作用域值的思想。了解如何使用變量的方法能夠讓你的CSS風(fēng)格更上一層樓。

          我在SCSS上使用變量,但是SCSS是預(yù)處理器,意味著一旦CSS到達(dá)瀏覽器,它便不復(fù)存在;而使用CSS變量,你可以利用JS對其進(jìn)行操作,例如在網(wǎng)站上切換暗黑和正常模式。


          6 . 顯示和定位

          CSS'顯示和位置‘屬性可以幫助我們控制元素在內(nèi)容流內(nèi)部和外部的放置方式。任何CSS開發(fā)人員都應(yīng)該掌握這兩個屬性以及由它們派生出來的一些知識點(diǎn)。在CSS中,定位事物仍然是最大的挑戰(zhàn)之一,因此,你必須著重進(jìn)行學(xué)習(xí)。


          7 . 響應(yīng)式設(shè)計與布局

          響應(yīng)式設(shè)計不但能支持網(wǎng)頁適配于任何尺寸的屏幕,而且還能調(diào)整布局以適應(yīng)可用空間。

          過往,通常我會建議身邊的人持續(xù)關(guān)注CSS媒體查詢,

          相關(guān)鏈接:https://developer.mozilla.org/en-US/docs/Web/CSS/Media_Queries/Using_media_queries

          但是,想一想,CSS的發(fā)展演進(jìn)很有些年頭了,意味著你如果想要打造響應(yīng)式的網(wǎng)頁,可完全擱置使用媒體查詢,改用網(wǎng)格布局(或flexbox)外加CSS clamp函數(shù)去控制字體。

          相關(guān)鏈接:https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Functions

          響應(yīng)式與流暢設(shè)計完美匹配超越了你對display:flex和網(wǎng)格布局的了解,

          相關(guān)鏈接:https://developer.mozilla.org/en-US/docs/Learn/CSS/CSS_layout/Responsive_Design

          沒有付出怎有收獲?利用響應(yīng)式設(shè)計的前提是,開發(fā)者需要了解諸如:設(shè)備和視口比例等問題、不同tags在可用空間限制下的表現(xiàn)、HTML的meta tags、既定視口的元素之間的合理距離、不同的設(shè)備尺寸等。所有這些都需要不斷地去學(xué)習(xí)和積累經(jīng)驗,大魔法師千萬不能小覷他們喲~


          8 . 圖片和背景

          <img />標(biāo)簽和CSS背景兩者是并存的,你必須了解何時使用image標(biāo)簽和CSS背景。尤其是CSS背景功能強(qiáng)大,我們甚至可以使用它來創(chuàng)建文本下劃線和一些其他出色的背景效果。對我個人來說,它們是CSS中最有趣的部分之一,選入此15件事中,就是提醒你不要忽略它。


          9 . 字體

          關(guān)于字體,開發(fā)者往往忽略了一些細(xì)節(jié),我感覺它們非常重要——你需要清楚如何為網(wǎng)站優(yōu)化字體,包括諸如:如何加載它們、有哪些選項、如何控制它們;實際上,很難找到完美的字體,但好的前端必須知道如何就地取材將它們提升到一個新的水平,從細(xì)節(jié)做起,以幫助到提升頁面的整體效果。


          10 . 色彩

          顏色無處不在。 你可以將其用在邊框、背景、輪廓等等。大多數(shù)開發(fā)者使用純hex顏色色值或顏色名稱,當(dāng)然也可以通過使用RGBA控制顏色的alpha透明度;基于alpha值,利用HSLA控制hue-rotate、飽和度和亮度,以便進(jìn)一步提升頁面色彩展示效果。

          駕馭頁面色彩不僅僅是色值的事,CSS currentColor屬性也需要納入管理范疇——

          相關(guān)鏈接:https://www.w3schools.com/colors/colors_currentcolor.asp

          我們可以在hex顏色值中再添加2個其它值,以控制RGBA顏色的alpha值, 例如:#29910d82是個不透明的綠色,這其中的‘82’控制的是alpha值,類似使用RGBA時的最后一個值。


          11. 過渡與動畫效果

          過渡效果簡單說就是一種控制CSS值從狀態(tài)A變?yōu)闋顟B(tài)B的方式,

          相關(guān)鏈接:https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Transitions/Using_CSS_transitions

          而動畫效果是一種使眾多的關(guān)鍵幀實現(xiàn)動態(tài)畫面的方式。

          相關(guān)鏈接:https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Animations/Using_CSS_animations

          動畫一旦使用得當(dāng),任何網(wǎng)頁都會美不勝收,而動畫和過渡效果相結(jié)合有利于增強(qiáng)用戶體驗,從而增強(qiáng)用戶與網(wǎng)頁之間的互動性。


          12. Transform屬性

          另一種被廣泛用來增強(qiáng)網(wǎng)頁使用體驗的方式就是引入3D效果。

          相關(guān)鏈接:https://developer.mozilla.org/en-US/docs/Web/CSS/transform

          Transform是那些你日常需要進(jìn)行動畫處理和過渡的內(nèi)容,自不言說,transform屬性與CSS動畫+過渡是緊密相關(guān)的,這是我推薦它的原因之一;而另一個原因是,近些年,海內(nèi)外運(yùn)用Transform屬性的網(wǎng)站越來越多,大概率你在未來工作中會用到,值得學(xué)習(xí)和關(guān)注。


          13 . 預(yù)處理器

          CSS的預(yù)處理器功能強(qiáng)大,可令我們更得心應(yīng)手地利用上希望在CSS中注入的東西。它使我們能夠橋接上諸如mixins、函數(shù)和模塊化等概念,此外它還有助于導(dǎo)入和撰寫樣式。

          相關(guān)鏈接:https://sass-lang.com/documentation/syntax

          上面給你推薦的是SASS,除了SASS,還有其他預(yù)處理器,譬如LESS和Stylus,相對來說,它們僅基于一些語法上的更改,但都殊路同歸。

          無論你會選擇哪種方法,在網(wǎng)頁樣式例程中引入預(yù)處理器都是讓你收獲頗豐,至少可以幫助你以更少的CSS來創(chuàng)建復(fù)雜的樣式。


          14 . CSS Houdini

          CSS Houdini是一個低級的API,通過幫助我們訪問到CSS引擎,從而為你提供了一些所需功能去擴(kuò)展CSS。

          相關(guān)鏈接:https://developer.mozilla.org/en-US/docs/Web/Houdini

          CSS Houdini不存在等待瀏覽器的渲染周期的問題,因而解析起來要快得多。再有,它公開了一些被用來對CSS進(jìn)行模塊化的東西,這些稱之為worklets,worklets不需要模塊化CSS代碼的預(yù)處理器。 在這樣一個簡單的API中,應(yīng)該算是個非常高級的概念了,它讓離成為一個魔法師又邁出了一步。


          15 . CSS架構(gòu)

          隨著你構(gòu)建的應(yīng)用體量越來越大,編寫CSS時很容易出現(xiàn)沖突,這也是我為什么把CSS架構(gòu)放到最后單獨(dú)觸及的原因。

          在你和你的團(tuán)隊達(dá)成意見一致的情況下,采用何種技術(shù)方法來幫助你們是當(dāng)務(wù)之急,下面是一些示例:

          BEM :是由Yandex團(tuán)隊提出的一種CSS Class 命名方法

          相關(guān)鏈接:http://getbem.com/introduction/

          OOCSS:面向?qū)ο蟮腃SS指南

          相關(guān)鏈接:http://oocss.org/

          SMACSS :CSS的可擴(kuò)展模塊化體系結(jié)構(gòu)

          相關(guān)鏈接:http://smacss.com/

          上面這三個都是CSS結(jié)構(gòu)樣式指南,你可以按照指南更合理地去構(gòu)造選擇器和樣式,甚至還可以根據(jù)喜好提出自己的建議。


          結(jié)論:

          晉級CSS是一個連貫性的學(xué)習(xí)過程,需要大量的實踐。如果你無法做到堅持嘗試上述這15個方法/概念,同時上手各種項目去進(jìn)行實踐,那么你永遠(yuǎn)成為不了一位魔法師。

          我建議你找些小型CSS項目練練手,我近期也會為你找些github上開源的項目練手,敬請期待。


          前在相關(guān)的元旦活動中,就已透露后面還有更好的活動及獎勵,今天,終于是揭曉了,在元旦過后,拳頭及英雄聯(lián)盟,也是準(zhǔn)備迎接新的一年,以及鼓勵大家迎接新的一個賽季,即S12。

          我想一些召喚師也察覺到,新的一年正式開始,新英雄的預(yù)告、新年皮膚、新賽季、新活動等各色內(nèi)容接踵而至,灰呆都覺得最近新聞太多不知道先寫哪個了,咱這就來看看這次的活動。

          活動內(nèi)容

          活動時間

          任務(wù)統(tǒng)計時間為:2022年1月7日0點(diǎn)—2022年2月7日23:59。

          獎勵領(lǐng)取截止時間:2022年2月13日23:59。

          獎勵及任務(wù)

          目標(biāo)一:進(jìn)行1場峽谷排位賽

          可獲得:3勝雙倍經(jīng)驗卡×1

          ?目標(biāo)二:贏得5場峽谷對局(匹配+排位)

          可獲得:杰作寶箱+鑰匙

          ?目標(biāo)三:組隊完成1場游戲?qū)?/p>

          可獲得:隨機(jī)1個表情

          ?目標(biāo)四:組隊完成3場游戲?qū)?/p>

          可獲得:藍(lán)色精萃×500+橙色精萃×500

          ?目標(biāo)五:

          1.累計12天,當(dāng)天有完成1場游戲?qū)?/p>

          2.累計5天,當(dāng)天有登錄掌上英雄聯(lián)盟

          可獲得:隨機(jī)1個皮膚

          ?

          活動鏈接:https://lol.qq.com/act/a20220107season/index.html?_code=507041

          同樣的如果鏈接掛了的話就去掌盟看看吧~

          活動會優(yōu)先從對應(yīng)獎池內(nèi)產(chǎn)出未擁有道具,大家倒是不用擔(dān)心會抽出重復(fù)皮膚,如果是獎池內(nèi)容已經(jīng)全收集就會將此皮膚轉(zhuǎn)到其他區(qū)的號里,如果真的全收集那也太富了,哈哈哈。

          在的app和pc網(wǎng)站做的越來越花哨,但是有時候用戶并不喜歡你給他挑選好的主題顏色,這個時候就需要一個換皮膚的功能了。

          那么我們怎么在vue中實現(xiàn)這個換皮膚的功能呢?



          項目結(jié)構(gòu)

          1. 實現(xiàn)思路
          • 我們用vue一般都是寫單頁面程序,因此在實際發(fā)布的時候只有一個html以及一堆靜態(tài)文件(js、css、img之類)。而在html中引用了這些js和css。我們要換皮膚的話其實就是動態(tài)的去切換css,所以在這里實現(xiàn)換皮膚其實也就是動態(tài)的更改html中引用css的路徑,使得當(dāng)用戶選擇了不同的皮膚,頁面引用的css不同從而呈現(xiàn)的樣式也不一樣。
          1. 優(yōu)化策略
          • 其實在實際場景中,需要通過切換皮膚來改變css的元素占所有css的比重并不會很多,因此我們需要把需要通過切換改變的css單獨(dú)提取出來,在動態(tài)改變css路徑時只需要去改變這個控制皮膚的css就可以了。
          • 把皮膚相關(guān)的css壓縮。
          1. 實現(xiàn)代碼分析
          2. 如下是我們的html代碼,注意其中的<link rel="stylesheet" name="theme" href="">,其他的都是正常引用。
          <!DOCTYPE html>
          <html lang="zh-CN">
          <head>
           <title>iView admin</title>
           <meta charset="UTF-8">
           <!-- -->
           <meta name="viewport" content="width=device-width,initial-scale=1.0,maximum-scale=1.0,user-scalable=0">
           <!-- 引入的css -->
           <link rel="stylesheet" href="/dist/main.css">
           <!-- 注意這是我們換皮膚需要的css -->
           <link rel="stylesheet" name="theme" href="">
           <!-- 圖標(biāo) -->
           <link rel="icon" href="./td_icon.ico" type="image/x-icon"/>
          </head>
          <body>
          <div id="app"></div>
          <!-- 用到的js -->
          <script type="text/javascript" src="/dist/vender-base.js"></script>
          <script type="text/javascript" src="/dist/vender-exten.js"></script>
          <script type="text/javascript" src="/dist/main.js"></script>
          </body>
          </html>
          

          接下來就是具體實現(xiàn)換皮膚功能了,換皮膚一般都是點(diǎn)擊一個按鈕彈出一些皮膚的選項,選中選項后皮膚生效。

          我們將換皮膚功能抽成一個組件theme-switch。pc端使用iview,手機(jī)端使用了vant。一共有3套皮膚用于切換。



          目錄結(jié)構(gòu)

          • pc端
          <template>
           <div style="display:inline-block;padding:0 6px;">
           <Dropdown trigger="click" @on-click="setTheme">
           <a href="javascript:void(0)">
           <Icon :style="{marginTop: '-2px', verticalAlign: 'middle'}" color="#495060" :size="18" type="paintbucket"></Icon>
           <Icon type="arrow-down-b"></Icon>
           </a>
           <DropdownMenu slot="list">
           <DropdownItem v-for="(item, index) in themeList" :key="index" :name="item.name">
           <Row type="flex" justify="center" align="middle">
           <span style="margin-right:10px;"><Icon :size="20" :type="item.name.substr(0, 1) !=='b' ? 'happy-outline' : 'happy'" :color="item.menu"/></span>
           <span><Icon :size="22" type="record" :color="item.element"/></span>
           </Row>
           </DropdownItem>
           </DropdownMenu>
           </Dropdown>
           </div>
          </template>
          <script>
          import Cookies from 'js-cookie';
          import config from '../../../../build/config.js';
          export default {
           name: 'themeSwitch',
           data () {
           return {
           themeList: [
           {
           name: 'black_b',
           menu: '#495060',
           element: '#2d8cf0'
           },
           {
           name: 'black_g',
           menu: '#495060',
           element: '#00a854'
           },
           {
           name: 'black_y',
           menu: '#495060',
           element: '#e96500'
           }
           ]
           };
           },
           methods: {
           // 點(diǎn)擊切換事件
           setTheme (themeFile) {
           let menuTheme=themeFile.substr(0, 1);
           let mainTheme=themeFile.substr(-1, 1);
           if (menuTheme==='b') {
           // 黑色菜單
           this.$store.commit('changeMenuTheme', 'dark');
           menuTheme='dark';
           } else {
           this.$store.commit('changeMenuTheme', 'light');
           menuTheme='light';
           }
           let path='';
           // 取到我們在html上給皮膚的css留的坑并且設(shè)置路徑
           let themeLink=document.querySelector('link[name="theme"]');
           let userName=Cookies.get('user');
           if (localStorage.theme) {
           let themeList=JSON.parse(localStorage.theme);
           let index=0;
           let hasThisUser=themeList.some((item, i)=> {
           if (item.userName===userName) {
           index=i;
           return true;
           } else {
           return false;
           }
           });
           if (hasThisUser) {
           themeList[index].mainTheme=mainTheme;
           themeList[index].menuTheme=menuTheme;
           } else {
           themeList.push({
           userName: userName,
           mainTheme: mainTheme,
           menuTheme: menuTheme
           });
           }
           localStorage.theme=JSON.stringify(themeList);
           } else {
           localStorage.theme=JSON.stringify([{
           userName: userName,
           mainTheme: mainTheme,
           menuTheme: menuTheme
           }]);
           }
           let stylePath='';
           if (config.env.indexOf('dev') > -1) {
           stylePath='./src/views/main-components/theme-switch/theme/';
           } else {
           stylePath='dist/';
           }
           if (mainTheme !=='b') {
           path=stylePath + mainTheme + '.css';
           } else {
           path='';
           }
           themeLink.setAttribute('href', path);
           }
           },
           created () {
           let path='';
           // 判斷運(yùn)行環(huán)境用于切換地址
           if (config.env.indexOf('dev') > -1) {
           path='./src/views/main-components/theme-switch/theme/';
           } else {
           path='dist/';
           }
           let name=Cookies.get('user');
           // 如果用戶之前選擇過皮膚則直接使用之前選擇的,否則使用默認(rèn)皮膚
           if (localStorage.theme) {
           let hasThisUser=JSON.parse(localStorage.theme).some(item=> {
           if (item.userName===name) {
           this.$store.commit('changeMenuTheme', item.menuTheme);
           this.$store.commit('changeMainTheme', item.mainTheme);
           return true;
           } else {
           return false;
           }
           });
           if (!hasThisUser) {
           this.$store.commit('changeMenuTheme', 'dark');
           this.$store.commit('changeMainTheme', 'b');
           }
           } else {
           this.$store.commit('changeMenuTheme', 'dark');
           this.$store.commit('changeMainTheme', 'b');
           }
           // 根據(jù)用戶設(shè)置主題
           if (this.$store.state.app.themeColor !=='b') {
           let stylesheetPath=path + this.$store.state.app.themeColor + '.css';
           // 取到我們在html上給皮膚的css留的坑并且設(shè)置路徑
           let themeLink=document.querySelector('link[name="theme"]');
           themeLink.setAttribute('href', stylesheetPath);
           }
           }
          };
          </script>
          
          • 手機(jī)端
          <template>
           <div style="display:inline-block;padding:0 6px;">
           <div @click="showBtn">換皮膚</div>
           <van-actionsheet v-model="show" :actions="themeList" @select="setTheme"/>
           </div>
          </template>
          <script>
          import Cookies from "js-cookie";
          import { Actionsheet } from "vant";
          // import config from "../../../../build/config.js";
          export default {
           name: "themeSwitch",
           components: {
           [Actionsheet.name]: Actionsheet
           },
           data() {
           return {
           show: false,
           themeList: [
           {
           name: "黑色",
           data: "black_b"
           },
           {
           name: "綠色",
           data: "black_g"
           },
           {
           name: "黃色",
           data: "black_y"
           }
           ]
           };
           },
           methods: {
           showBtn() {
           this.show=true;
           },
           setTheme(themeFile) {
           themeFile=themeFile.data;
           let menuTheme=themeFile.substr(0, 1);
           let mainTheme=themeFile.substr(-1, 1);
           if (menuTheme==="b") {
           // 黑色菜單
           this.$store.commit("changeMenuTheme", "dark");
           menuTheme="dark";
           } else {
           this.$store.commit("changeMenuTheme", "light");
           menuTheme="light";
           }
           let path="";
           let themeLink=document.querySelector('link[name="theme"]');
           let userName=Cookies.get("user");
           if (localStorage.theme) {
           let themeList=JSON.parse(localStorage.theme);
           let index=0;
           let hasThisUser=themeList.some((item, i)=> {
           if (item.userName===userName) {
           index=i;
           return true;
           } else {
           return false;
           }
           });
           if (hasThisUser) {
           themeList[index].mainTheme=mainTheme;
           themeList[index].menuTheme=menuTheme;
           } else {
           themeList.push({
           userName: userName,
           mainTheme: mainTheme,
           menuTheme: menuTheme
           });
           }
           localStorage.theme=JSON.stringify(themeList);
           } else {
           localStorage.theme=JSON.stringify([
           {
           userName: userName,
           mainTheme: mainTheme,
           menuTheme: menuTheme
           }
           ]);
           }
           let stylePath='css/';
           // stylePath="./src/view/component/theme-switch/theme/";
           // if (config.env.indexOf('dev') > -1) {
           // stylePath='src/view/component/theme-switch/theme';
           // } else {
           // stylePath='dist/';
           // }
           if (mainTheme !=="b") {
           path=stylePath + mainTheme + ".css";
           } else {
           path="";
           }
           themeLink.setAttribute("href", path);
           this.show=false;
           }
           },
           created() {
           let path="";
           path="css/";
           // if (config.env.indexOf("dev") > -1) {
           // path="src/view/component/theme-switch/theme";
           // } else {
           // path="dist/";
           // }
           let name=Cookies.get("user");
           if (localStorage.theme) {
           let hasThisUser=JSON.parse(localStorage.theme).some(item=> {
           if (item.userName===name) {
           this.$store.commit("changeMenuTheme", item.menuTheme);
           this.$store.commit("changeMainTheme", item.mainTheme);
           return true;
           } else {
           return false;
           }
           });
           if (!hasThisUser) {
           this.$store.commit("changeMenuTheme", "dark");
           this.$store.commit("changeMainTheme", "b");
           }
           } else {
           this.$store.commit("changeMenuTheme", "dark");
           this.$store.commit("changeMainTheme", "b");
           }
           console.log(path);
           // 根據(jù)用戶設(shè)置主題
           if (this.$store.state.app.themeColor !=="b") {
           let stylesheetPath=path + this.$store.state.app.themeColor + ".css";
           let themeLink=document.querySelector('link[name="theme"]');
           themeLink.setAttribute("href", stylesheetPath);
           }
           }
          };
          </script>
          

          在首頁引用該組件,初次渲染時進(jìn)入該組件的creat方法,如果用戶之前選擇過皮膚則直接使用之前選擇的,否則使用默認(rèn)皮膚。在store中加入相應(yīng)方法。

          changeMenuTheme (state, theme) {
           state.menuTheme=theme;
          },
          changeMainTheme (state, mainTheme) {
           state.themeColor=mainTheme;
           }
          

          動態(tài)切換最關(guān)鍵的是這兩行代碼,其他的都是將皮膚狀態(tài)存起來方便下次使用:

          let themeLink=document.querySelector('link[name="theme"]')

          themeLink.setAttribute('href', stylesheetPath)

          但是這個時候我們皮膚相關(guān)的css并沒有打到代碼中,需要我們額外進(jìn)行配置。

          在webpack的配置文件中找到plugins,加入以下插件:

          • pc端
           new CopyWebpackPlugin([
           {
           from: 'td_icon.ico'
           },
           {
           from: 'src/styles/fonts',
           to: 'fonts'
           },
           {
           from: 'src/views/main-components/theme-switch/theme'
           }
           ],
          
          • 手機(jī)端
           new CopyWebpackPlugin([
           {
           from: 'static',
           to: 'static'
           },
           {
           from: 'src/view/component/theme-switch/theme',
           to: './css'
           }
           ])
          

          之前我們可能已經(jīng)有了這個插件了,現(xiàn)在只是需要把皮膚相關(guān)的css額外配置一下。以上工作完成之后已經(jīng)可以動態(tài)的切換html中皮膚相關(guān)的css路徑了。接下來就需要我們在需要切換css的地方引用具體的class并且寫三套樣式分別放在theme中的css文件里。

          注意在具體的vue文件中不需要引用theme中的css,因為html中已經(jīng)幫我們引用了

          如果報各種與路徑有關(guān)的錯誤那就是你的路徑真的寫錯啦。好好對比一下組件中引用的路徑,webpack中配置的路徑和你的項目路徑吧~

          當(dāng)然這只是換皮膚的一種實現(xiàn)思路,也就是動態(tài)切換html中的引用路徑。也希望大家集思廣益提供更多的解決思路~


          主站蜘蛛池模板: 亚洲视频一区二区在线观看| 一区二区三区四区在线观看视频| 日韩精品一区二区三区不卡 | 欧美成人aaa片一区国产精品| 一区二区三区在线免费观看视频| av无码免费一区二区三区| 久久久精品日本一区二区三区| 精品人妻无码一区二区三区蜜桃一| 国产一区二区四区在线观看| 日韩免费视频一区| 国产精品一区视频| 亚洲午夜一区二区电影院| 一区二区三区无码视频免费福利| 国产精品免费综合一区视频| 日韩免费一区二区三区在线| 久久久久久人妻一区精品| 中文字幕在线无码一区| 一区二区精品视频| 日本免费精品一区二区三区| 免费精品一区二区三区在线观看 | 国产精品一区二区久久乐下载| 色妞色视频一区二区三区四区 | 亚洲日韩一区二区三区| 亚洲av不卡一区二区三区| 波多野结衣AV无码久久一区| 国产精品亚洲不卡一区二区三区 | 国产观看精品一区二区三区 | 国产丝袜无码一区二区三区视频| 国产精品第一区揄拍无码| 国产SUV精品一区二区四| 伊人久久精品无码麻豆一区| 亚洲av无码片区一区二区三区| 亚洲国产精品乱码一区二区| 日本一区二区三区在线观看 | 亚洲国产成人久久综合一区77| 国产一区二区三区手机在线观看 | 国产一区二区精品在线观看| 国产亚洲综合精品一区二区三区| 在线不卡一区二区三区日韩| 国产成人综合亚洲一区| 精品一区二区高清在线观看|