uni-app小程序中动态修改字体大小,实现切换老年模式

发布于:2025-04-05 ⋅ 阅读:(27) ⋅ 点赞:(0)

uni-app中动态修改字体大小

最近在一个uni-app的小程序项目要做一个字体大小修改功能,动态切换大字模式,相当于老年模式。由于在小程序中无法直接通过修改根节点下的font-size,在网上搜索了一圈,说可以通过动态设置page-meta下的root-font-size来实现。但由于项目已经写了几十个页面了,在代码各处已经通过text-xx的unocss的预设样式设置好了字体大小,在每个页面中再去添加page-meta侵入太大,也不可能去再去每处设置字体大小的地方修改。经过一番摸索,发现直接通过修改scss下动态变量的方式就可轻松实现。

创建font-base

主要配置便是在unocss.config.js中添加test-xx到rules,用于动态替换默认预设的text-xx的字体大小样式:

import { defineConfig } from 'unocss'
import transformerDirectives from '@unocss/transformer-directives'
import presetWeapp from 'unocss-preset-weapp'
import { presetShades } from '@viarotel-org/unocss-preset-shades'
import { presetUni } from '@uni-helper/unocss-preset-uni'
import { primaryColor } from '@/configs'

const presetMain = presetUni({ attributify: false })

const presets = [
  presetMain,
  presetShades(primaryColor),
]
const transformers = [ transformerDirectives() ]
const rules = []

presets.push(presetWeapp({
     transform: true
  }))

  const arr = [
  ... 关键配置...
    [ /^text-(\d+)$/, ([ , d ]) => ({ 'font-size': `calc(var(--font-base) * ${d / 10})` }) ],
  ]
rules.push(...arr)

export default defineConfig({
  theme: {
    colors: {
      primary: 'var(--primary-color, #FFA011)',
    },
  },
  presets,
  transformers,
  rules,

  shortcuts: {
    'text-title': 'font-bold text-16 text-grey-222',
  },
})

在rules中添加 [ /^text-(\d+)$/, ([ , d ]) => ({ 'font-size': calc(var(--font-base) * ${d / 10})}) ] 规则,表示将text-xx后面的数字*10来变更字体的大小。如text-12即表示font-size:var(--font-base)*1.2 ,text-16即表示font-size:var(--font-base)*1.6 , 这样就不用修改原页面中通过text-12或text-16设置的样式了,只用动态修改–font-base的大小即可。

添加–font-base

–font-base即这里面的基准字体大小,可以在App.vue下预设,如:

page {

  :root {
    --font-base: 10px;
    /* H5基准 */
  }

  @media (platform: mp-weixin) {
    :root {
      --font-base: 20rpx;
      /* 小程序基准 */
    }
  }
}

这里设置了 --font-base为10px,在小程序下设为20rpx,具体可以参照UI设计稿尺寸,以便直接使用设计稿上字体大小,由于这里参照的UI设计稿使用的375px的尺寸,故直接设置为10px和20rpx,这样在设计稿上为16px大小字体直接使用text-16即可。

动态修改–font-base

最关键的步骤便是如何动态修改这里的–font-base了。通过前面两步已经预设了字体大小,现在要动态修改字体大小来实现切换老年模式即可。但小程序中没有document节点,无法直接通过document.documentElement.style.setProperty('--font-base', size)的方式来修改。这里只有折中在每个页面的根节点里添加一个style='--font-base:30rpx'来实现动态修改。但由于每个页面都这样的样式太麻烦,也无法动态修改。我们可能封装一个base-page的组件来包裹,并使用vuex或pinia来实现状态管理即可。完整代码如下:

import { defineStore } from 'pinia'
import storage from '@/utils/storages'

export const useAppStore = defineStore({
  id: 'app',
  state () {
    return {
      themeConfig: storage.get('app/themeConfig') || {
        fontBaseSize:'20rpx',
      },
    }
  },
  getters: {
    fontBaseSize: state => state.themeConfig?.fontBaseSize,
  },
  actions: {
    updateFontBaseSize (size) {
      this.themeConfig.fontBaseSize = size
      storage.set('app/themeConfig', this.themeConfig)
    },
})

封装base-page:

<template>
  <view class="page" :style="styles">
    <slot></slot>
  </view>
</template>

<script setup>
import { useAppStore } from '@/store/app'
import { storeToRefs } from 'pinia'
import { computed } from 'vue'

const appStore = useAppStore()
const { fontBaseSize } = storeToRefs(appStore)
const styles = computed(() => [
  { '--font-base': fontBaseSize.value },
])
</script>

<style lang="scss" scoped></style>

然后在页面中的根节点直接使用base-page即可:

<template>
  <base-page class="w-full flex-col">
    <view class="w-full row justify-between items-center">
      <view class="flex-1">
        <text>老年模式</text>
      </view>
      <view class="row items-center">
        <uv-switch @change="clickFontMode"></uv-switch>
      </view>
    </view>
  </base-page>
</template>
<script setup>
import { useAppStore } from '@/store/app'

const appStore = useAppStore()

const clickFontMode = v => {
  appStore.updateFontBaseSize(v ? ‘30rpx’ : '20rpx')
}
</script>
<style lang="scss" scoped></style>

可直接预设大字模式下的字体大小,也可通过滑块动态改变。