web 端和小程序设置根元素字体大小区别
在 web 端如果要做全局字体大小切换方案,我们首先会想到用 rem 这样的相对单位来设置字体大小,rem 的原理想必大家都知道的。rem 是响应式的一种,是相对于根元素(即html元素) font-size 计算值的倍数的一个css单位。比如 html 设置字体大小为 16px,那么 2rem 实际大小就是 32 px。这时想做全局字体大小切换,我们只需要动态设置 html 根字号大小,很简单直接设置document.documentElement.style.fontSize = "18px"即可。
html {
font-size: 16px;
}
p {
font-size: 2rem;
}
在小程序中,我们也是可以用 rem 单位的,可以在 app.wxss 中给 page 标签设置字号大小,然后在自定义组件中使用方式和 web 端是一致的。但是至今为止,微信小程序官方并未开放 全局动态设置 page 样式的相关 api,或者直接修改 app.wxss 的 方式,因此这个方案在小程序中是行不通的。值得庆幸的是,虽然没有直接设置 page 样式这样的 api,但是官方在版本号 2.9.0 之后,出了 page-meta 这样的页面属性配置方案,其中 root-font-size 就是页面的根字体大小属性。接下来我们就利用这个配置项来完成小程序的方案。
小程序全局字体大小切换具体实施步骤
组件新增 page-meta 配置
这里需要注意 page-meta 标签,必须写在页面的最上面,只能是页面内的第一个节点。
// my-component.wxml
<page-meta root-font-size="{{fontSize}}rpx"></page-meta>
<view class="intro1">组件</view>
<view class="intro2">组件</view>
<view class="intro3">组件</view>
// my-component.js
Component({
/**
* 组件的初始数据
*/
data: {
fontSize: 100,
},
pageLifetimes: {
show: function() {
console.log("Behavior show 逻辑")
const fz = wx.getStorageSync('font-size');
this.setData({
fontSize: fz
})
}
}
/**
* 组件的方法列表
*/
methods: {
}
})
我们试想一下,每个自定义组件中都要给 data 定义一个 fontSize 属性,在生命周期 show 方法中设置 fontSize 熟悉值,也太麻烦了吧?接下来是时候引入混入的概念了
给每个组件新增混入 behaviors
behaviors 是用于组件间代码共享的特性,类似于 vue 中的 mixin。每个 behavior 可以包含一组属性、数据、生命周期函数和方法。组件引用它时,它的属性、数据和方法会被合并到组件中,生命周期函数也会在对应时机被调用。 behaviors参考文档
- 新增 behavior.js
先在 data 中定义好 fontSize 默认值。如果曾切换过 fontSize,这里就可以用小程序的本地存储功能,类似 web 端的 localStorage ,随后就可以在 生命周期-show (组件展示的时候会执行该函数)方法中重新设置 fontSize 了
module.exports = Behavior({
data: {
fontSize: 100, // 默认 100 方便初始化样式代码时好计算
},
pageLifetimes: {
show: function() {
console.log("Behavior show 逻辑")
// 这里使用了小程序的本地存储功能
const fz = wx.getStorageSync('font-size');
if(fz) {
this.setData({
fontSize: fz
})
}
}
}
})
- 在自定义组件使用 behavior
// my-component.js
var myBehavior = require('behavior')
Component({
behaviors: [myBehavior],
/**
* 组件的方法列表
*/
methods: {
}
})
不过以上步骤,虽然能解决重复定义 fontSize 和 show 的繁琐问题,但每个组件还是都要引入 behavior。我们再想一下,能不能不手动引入,在组件生成的时候自动添加呢?答案是可以的!请接着往下看
改造 Component,自动引入 behavior
下面代码中的 extendComponent 函数,大家是不是看着很熟悉,没错这就是所谓的高阶组件。在 app.js 启动函数中调用
var myBehavior = require('behavior.js')
const OriginalComponent = Component;
/* 扩展原生的 Component,新增 behaviors 属性,避免每个组件都重复写一次*/
function extendComponent(Com) {
return function (options) {
options.behaviors = [myBehavior];
return Com(options);
};
}
App({
onLaunch: function () {
const fz = wx.getStorageSync('font-size');
if (!fz) {
wx.setStorageSync('font-size', 100)
}
Component = extendComponent(OriginalComponent);
},
globalData: {
}
})
至此,主要步骤都介绍完了
注意点:考虑到小程序的 Page 和 Component 配置项是有不同的,我们在定义 page 页面的时候统一用 Component 就可以了。参考链接1 参考链接2