最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Vue?UI框架的主題切換功能實現(xiàn)

 更新時間:2022年12月05日 08:52:56   作者:凍羊的小屋  
在如今,很多網(wǎng)頁已經(jīng)可以手動切換明亮模式和黑暗模式,網(wǎng)頁的主題切換已經(jīng)成為了一個常用的需求,因此,本文將從常見框架的處理方式總結(jié)一些相關(guān)的操作,對vue?ui框架主題切換功能感興趣的朋友跟隨小編一起看看吧

在如今,很多網(wǎng)頁已經(jīng)可以手動切換明亮模式和黑暗模式,網(wǎng)頁的主題切換已經(jīng)成為了一個常用的需求,因此,本文將從常見框架的處理方式總結(jié)一些相關(guān)的操作,并探究其本質(zhì)。

AntD 的方式

AntD 的 config-provider 似乎不能直接修改主題,目前網(wǎng)絡(luò)上的教程有兩類,一類是通過 less 的修改變量修改來完成,另一類是操作 DOM 改變對文件的引用,由于 ant-design-vue 已經(jīng)提供了黑暗主題,而且直接修改 less 文件的變量涉及到了太多變量,不太方便,因此參考了這篇文章vue3點擊出現(xiàn)彈窗后背景變暗且不可操作的實現(xiàn)代碼,使用動態(tài)添加 CSS 引用 DOM 的方式實現(xiàn)黑暗主題的切換,原理是添加一個 DOM,引用我們自定義的 CSS 樣式,后面的引用會覆蓋前面的引用,在切換到亮色主題時把這個 DOM 刪除。

1. 創(chuàng)建黑暗主題文件

在目錄下的適當位置創(chuàng)建一個黑暗主題的文件,后面要引用這個文件,這里直接把官方黑暗主題復制過來就可以了,它的位置在 node_modules\ant-design-vue\dist\antd.dark.min.css,假設(shè)我們把它復制到了 public/styles/dark.css 中。

2. 創(chuàng)建切換主題的函數(shù)

有了主題文件,我們就可以創(chuàng)建切換主題的函數(shù)了,在目錄中的合適位置創(chuàng)建一個 js 文件,例如 src/utils/theme.ts,其中的代碼為:

const darkThemeSwitch = () => {
    // id要與前面一致
    const theme_element = document.querySelector('#dark-theme-style');
    if (!theme_element) {
        const new_dark_Theme = document.createElement('link')
        new_dark_Theme.setAttribute('rel', 'stylesheet');
        //剛剛設(shè)置的css路徑
        new_dark_Theme.setAttribute('href', '/styles/dark.css');
        // id可以自由設(shè)置
        new_dark_Theme.setAttribute('id', 'dark-theme-style');
        const docHead = document.querySelector('head');
        docHead?.append(new_dark_Theme);
    } else {
        const parentNode = theme_element?.parentNode;
        parentNode?.removeChild(theme_element);
    }
}

export default darkThemeSwitch;

3. 切換主題

然后,我們在需要切換主題的地方使用這個方法就可以了:

<template>
    <a-button @click="toggleDark">切換主題</a-button>
</template>

<script setup lang="ts">
    import darkThemeSwitch from '../utils/theme';
    const toggleDark = () => {
        darkThemeSwitch();
    };
</script>

Quasar 的方式

quasar 的主題切換非常簡單,只要使用 quasar 官方提供的 dark 插件就可以了,使用方法如下:

import { useQuasar } from 'quasar'
const $q = useQuasar()

// get status
console.log($q.dark.isActive) // true, false

// get configured status
console.log($q.dark.mode) // "auto", true, false

// set status
$q.dark.set(true) // or false or "auto"

// toggle
$q.dark.toggle()

通過研究 Quasar 的源碼,可以發(fā)現(xiàn),Quasar 的黑暗有兩種設(shè)置方式,自動和手動,在自動模式下,插件通過監(jiān)聽 prefers-color-scheme: dark 的狀態(tài)來決定當前網(wǎng)頁的主題,通過這種方式,可以實現(xiàn)網(wǎng)頁跟隨系統(tǒng)主題自動變換淺色和深色模式,對應部分的代碼如下:

Plugin.mode = val
if (val === 'auto') {
  if (Plugin.__media === void 0) {
    Plugin.__media = window.matchMedia('(prefers-color-scheme: dark)')
    Plugin.__updateMedia = () => { Plugin.set('auto') }
    Plugin.__media.addListener(Plugin.__updateMedia)
  }

  val = Plugin.__media.matches
}

上面的代碼中,Plugin.mode 代表設(shè)置方式,Plugin.__media 的值默認就是 void 0,這里的判斷的作用是當?shù)谝淮螆?zhí)行時給相應的 Media 添加一個監(jiān)聽來獲得實時的變化。這里調(diào)用的 Plugin.set('auto') 就是手動設(shè)置的函數(shù),這個函數(shù)接受一個布爾值,然后根據(jù)布爾值的真假對主題進行設(shè)置,相應的實現(xiàn)如下:

document.body.classList.remove(`body--${ val === true ? 'light' : 'dark' }`)
document.body.classList.add(`body--${ val === true ? 'dark' : 'light' }`)

顯然,這里的實現(xiàn)方式也比較常規(guī),即在 body 標簽添加或刪除相應的樣式選擇器類名來實現(xiàn)主題的切換,quasar 值得我們學習的地方在于它把所有的功能集成到 useQuasar 中,用戶可以方便地使用各種插件,而不需要寫很多代碼。完整的代碼如下:

import defineReactivePlugin from '../utils/private/define-reactive-plugin.js'
import { isRuntimeSsrPreHydration } from './Platform.js'

const Plugin = defineReactivePlugin({
    // 插件的屬性
    isActive: false,
    mode: false
}, {
    __media: void 0,
    // 插件的核心方法
    set(val) {
        if (__QUASAR_SSR_SERVER__) { return }

        Plugin.mode = val
        // 自動主題切換
        if (val === 'auto') {
            if (Plugin.__media === void 0) {
                Plugin.__media = window.matchMedia('(prefers-color-scheme: dark)')
                Plugin.__updateMedia = () => { Plugin.set('auto') }
                Plugin.__media.addListener(Plugin.__updateMedia)
            }

            val = Plugin.__media.matches
        }
        else if (Plugin.__media !== void 0) {
            Plugin.__media.removeListener(Plugin.__updateMedia)
            Plugin.__media = void 0
        }

        Plugin.isActive = val === true
        // 手動指定主題
        document.body.classList.remove(`body--${val === true ? 'light' : 'dark'}`)
        document.body.classList.add(`body--${val === true ? 'dark' : 'light'}`)
    },
    // 主題的切換
    toggle() {
        if (__QUASAR_SSR_SERVER__ !== true) {
            Plugin.set(Plugin.isActive === false)
        }
    },

    install({ $q, onSSRHydrated, ssrContext }) {
        const { dark } = $q.config

        if (__QUASAR_SSR_SERVER__) {
            this.isActive = dark === true

            $q.dark = {
                isActive: false,
                mode: false,
                set: val => {
                    ssrContext._meta.bodyClasses = ssrContext._meta.bodyClasses
                        .replace(' body--light', '')
                        .replace(' body--dark', '') + ` body--${val === true ? 'dark' : 'light'}`

                    $q.dark.isActive = val === true
                    $q.dark.mode = val
                },
                toggle: () => {
                    $q.dark.set($q.dark.isActive === false)
                }
            }

            $q.dark.set(dark)
            return
        }

        $q.dark = this

        if (this.__installed === true && dark === void 0) {
            return
        }

        this.isActive = dark === true

        const initialVal = dark !== void 0 ? dark : false

        if (isRuntimeSsrPreHydration.value === true) {
            const ssrSet = val => {
                this.__fromSSR = val
            }

            const originalSet = this.set

            this.set = ssrSet
            ssrSet(initialVal)

            onSSRHydrated.push(() => {
                this.set = originalSet
                this.set(this.__fromSSR)
            })
        }
        else {
            this.set(initialVal)
        }
    }
})

export default Plugin

ElementUI 的方式

在 2.2.0 版本,Element UI 也可以進行黑暗模式切換了,操作如下:

  • 在 main.ts 引入官方的 CSS:import 'element-plus/theme-chalk/dark/css-vars.css'

更改 html 標簽的類,添加 dark 即為黑暗模式,去掉 dark 即為明亮模式,這一過程有很多實現(xiàn)方法,官方推薦使用 VueUse 這個函數(shù)庫中的 useDark 來實現(xiàn),這是一個非常強大的官方工具庫,里面提供了許多常用功能的實現(xiàn)以及一些小插件,非常值得學習,請參考VueUse的官方文檔:

<template>
    <el-button @click="toggleDark()">切換主題</el-button>
</template>

<script setup lang="ts">
    import { useDark, useToggle } from '@vueuse/core';

    const isDark = useDark();
    const toggleDark = useToggle(isDark);
</script>

NaiveUI 的方式

NaiveUI 的黑暗主題是通過其提供的 Config Provider 組件來實現(xiàn)的,通過設(shè)置其 theme 屬性為 null 或者 darkTheme(需要從 naive-ui 導入),可以更改其內(nèi)部組件的主題,配合 Global Style 組件,可以設(shè)置全局的主題:

<template>
  <n-config-provider :theme="theme">
    <n-card>
      <n-space>
        <n-button @click="theme = darkTheme">
          深色
        </n-button>
        <n-button @click="theme = null">
          淺色
        </n-button>
      </n-space>
    </n-card>
    <!-- 加上這個后可以切換全局主題 -->
    <n-global-style />
  </n-config-provider>
</template>

<script setup lang="ts">
import { ref } from 'vue'
import { darkTheme } from 'naive-ui'
import type { GlobalTheme } from 'naive-ui'

const theme = ref<GlobalTheme | null>(null)
</script>

還可以通過 useOsTheme 獲取系統(tǒng)的主題作為組件的主題:

<template>
  <n-config-provider :theme="theme">
    <n-card> 當前操作系統(tǒng)的主題是 {{ osTheme }}。 </n-card>
  </n-config-provider>
</template>

<script lang="ts">
import { defineComponent, computed } from 'vue'
import { useOsTheme, darkTheme } from 'naive-ui'

export default defineComponent({
  setup () {
    const osThemeRef = useOsTheme()
    return {
      theme: computed(() => (osThemeRef.value === 'dark' ? darkTheme : null)),
      osTheme: osThemeRef
    }
  }
})
</script>

讓我們來看一下它的實現(xiàn),好吧,我水平實在是有限,真的看不懂,但是看起來真的很厲害。

到此這篇關(guān)于Vue UI框架的主題切換功能實現(xiàn)的文章就介紹到這了,更多相關(guān)vue主題切換內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • vue props 單項數(shù)據(jù)流實例分享

    vue props 單項數(shù)據(jù)流實例分享

    在本篇文章里小編給大家分享的是一篇關(guān)于vue props 單項數(shù)據(jù)流實例分享內(nèi)容,需要的朋友們可以參考下。
    2020-02-02
  • vue單頁面應用打開新窗口顯示跳轉(zhuǎn)頁面的實例

    vue單頁面應用打開新窗口顯示跳轉(zhuǎn)頁面的實例

    今天小編就為大家分享一篇vue單頁面應用打開新窗口顯示跳轉(zhuǎn)頁面的實例,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2018-09-09
  • Vue2.0實現(xiàn)簡單分頁及跳轉(zhuǎn)效果

    Vue2.0實現(xiàn)簡單分頁及跳轉(zhuǎn)效果

    這篇文章主要為大家詳細介紹了Vue2.0實現(xiàn)簡單數(shù)據(jù)分頁,及頁數(shù)的跳轉(zhuǎn)效果,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2019-07-07
  • vue打印瀏覽器頁面功能的兩種實現(xiàn)方法

    vue打印瀏覽器頁面功能的兩種實現(xiàn)方法

    這篇文章主要給大家介紹了關(guān)于vue打印瀏覽器頁面功能的兩種實現(xiàn)方法,這個功能其實也是自己學習到的,做完也有一段時間了,一直想記錄總結(jié)一下,文中通過實例代碼介紹的非常詳細,需要的朋友可以參考下
    2023-04-04
  • Vue滑塊驗證碼組件anji-captcha的使用案例詳解

    Vue滑塊驗證碼組件anji-captcha的使用案例詳解

    滑塊驗證是一種常見的人機識別方法,這篇文章主要介紹了Vue滑塊驗證碼組件anji-captcha的使用,本文通過實例代碼圖文相結(jié)合給大家介紹的非常詳細,需要的朋友可以參考下
    2023-05-05
  • Vue中響應式系統(tǒng)實現(xiàn)原理圖文講解

    Vue中響應式系統(tǒng)實現(xiàn)原理圖文講解

    Vue的響應式實現(xiàn)是借助Object.defineProperty通過重寫getter和setter方法來進行的數(shù)據(jù)劫持,Vue3通過Proxy代理攔截對象中任意屬性的變化,通過Reflect反射對源對象的屬性進行操作,然后再在get里收集依賴在set里派發(fā)更新
    2023-03-03
  • antd vue表格可編輯單元格以及求和實現(xiàn)方式

    antd vue表格可編輯單元格以及求和實現(xiàn)方式

    這篇文章主要介紹了antd vue表格可編輯單元格以及求和實現(xiàn)方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-04-04
  • Vue-input框checkbox強制刷新問題

    Vue-input框checkbox強制刷新問題

    這篇文章主要介紹了Vue-input框checkbox強制刷新問題,非常不錯,具有一定的參考借鑒價值,需要的朋友可以參考下
    2019-04-04
  • Vue3.x+Element Plus仿制Acro Design簡潔模式實現(xiàn)分頁器組件

    Vue3.x+Element Plus仿制Acro Design簡潔模式實現(xiàn)分頁器組件

    開發(fā)中難免會遇到寬度很窄的列表需要使用分頁器的情況。本文將利用Vue3.x+Element Plus仿制Acro Design簡潔模式實現(xiàn)分頁器組件,感興趣的可以了解一下
    2023-02-02
  • 使用vue.js寫一個tab選項卡效果

    使用vue.js寫一個tab選項卡效果

    Vue 實現(xiàn) Tab切換實現(xiàn)的場景很多,比如,利用vue-router、利用第三方插件、利用組件等等.本文使用組件來實踐tab選項卡
    2017-03-03

最新評論

威信县| 仙游县| 子长县| 宁波市| 枣阳市| 盐山县| 兴化市| 松原市| 桦甸市| 阳泉市| 永和县| 辽宁省| 固原市| 大余县| 灯塔市| 渝中区| 泸州市| 靖宇县| 冕宁县| 汾阳市| 邵阳市| 昆山市| 澄城县| 汝城县| 台江县| 东乡族自治县| 滦南县| 赤水市| 仙桃市| 宣武区| 莒南县| 营山县| 永登县| 吉木萨尔县| 康保县| 阿巴嘎旗| 平昌县| 察雅县| 萝北县| 柘城县| 湖口县|