You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何在Vuetify项目中动态全局修改字体样式/字重等非颜色属性?

如何在Vuetify中动态切换全局字体(无需逐个加类)

这个问题我之前踩过坑——直接修改variables.scss里的SCSS变量根本行不通,因为SCSS是预编译阶段就把变量替换成固定值了,运行时没法动态更新。不过我们可以用CSS自定义属性(也就是CSS变量)来绕开这个限制,配合Vuetify的主题配置,实现全局字体的实时切换,完全不用在组件里到处加类,维护性拉满!

核心思路

把Vuetify依赖的字体相关属性(比如font-family、字重)替换成运行时可修改的CSS变量,然后通过JavaScript动态修改这些变量的值,就能让整个应用的字体自动更新。

具体步骤

1. 配置Vuetify使用CSS变量

在你的Vuetify初始化文件(一般是src/plugins/vuetify.js)里,把主题的字体相关变量改成引用CSS变量:

import { createVuetify } from 'vuetify'

export default createVuetify({
  theme: {
    defaultTheme: 'light',
    themes: {
      light: {
        variables: {
          // 用CSS变量替代SCSS变量
          fontFamily: 'var(--v-font-family)',
          fontWeightRegular: 'var(--v-font-weight-regular)',
          fontWeightMedium: 'var(--v-font-weight-medium)',
          fontWeightBold: 'var(--v-font-weight-bold)',
        },
        // 你的颜色主题配置...
      },
    },
  },
})

2. 定义全局CSS变量并加载字体

在全局样式文件(比如src/styles/main.scss或者App.vue<style>标签里),定义默认的CSS变量,同时确保你要切换的字体已经加载(比如用Google Fonts或者本地字体):

/* 根元素定义默认CSS变量 */
:root {
  --v-font-family: 'Roboto', sans-serif;
  --v-font-weight-regular: 400;
  --v-font-weight-medium: 500;
  --v-font-weight-bold: 700;
}

/* 加载可选字体(这里以Google Fonts为例) */
@import url('https://fonts.googleapis.com/css2?family=Roboto:wght@400;500;700&family=Raleway:wght@300;400;600&display=swap');

3. 实现动态切换逻辑

在你的设置组件(比如一个字体选择器页面)里,用v-select提供可选字体,然后通过JavaScript修改根元素的CSS变量:

<template>
  <v-container>
    <v-select
      v-model="selectedFont"
      :items="availableFonts"
      label="选择全局字体"
      variant="outlined"
      class="mb-4"
    />
    <!-- 可以再加一个字重选择器,逻辑类似 -->
    <v-select
      v-model="selectedWeight"
      :items="availableWeights"
      label="选择全局常规字重"
      variant="outlined"
    />
  </v-container>
</template>

<script setup>
import { ref, watch } from 'vue'

// 可选字体列表
const availableFonts = [
  { text: 'Roboto', value: "'Roboto', sans-serif" },
  { text: 'Raleway', value: "'Raleway', sans-serif" },
  // 可以添加更多字体
]

// 可选字重列表
const availableWeights = [
  { text: '常规(400)', value: '400' },
  { text: '轻量(300)', value: '300' },
  { text: '中等(500)', value: '500' },
]

// 初始化选中值,优先从localStorage读取(可选,实现刷新保留设置)
const selectedFont = ref(localStorage.getItem('app-font') || "'Roboto', sans-serif")
const selectedWeight = ref(localStorage.getItem('app-font-weight') || '400')

// 监听字体变化,动态更新CSS变量
watch(selectedFont, (newFont) => {
  document.documentElement.style.setProperty('--v-font-family', newFont)
  localStorage.setItem('app-font', newFont)
})

// 监听字重变化,动态更新CSS变量
watch(selectedWeight, (newWeight) => {
  document.documentElement.style.setProperty('--v-font-weight-regular', newWeight)
  localStorage.setItem('app-font-weight', newWeight)
})
</script>

为什么这个方案可行?

  • CSS变量是运行时生效的,只要修改根元素的变量值,所有引用该变量的地方都会自动更新。
  • 我们是在Vuetify的主题variables里配置的这些CSS变量,Vuetify的所有组件都会继承这些设置,所以是真正的全局生效,不用给每个组件加类。
  • 可以轻松扩展到其他全局属性(比如行高、字间距),只需要在Vuetify主题变量里对应替换成CSS变量即可。

内容的提问来源于stack exchange,提问作者Aagam Vadecha

火山引擎 最新活动