背景
最近在做的项目有老年人模式的需求——也就是动态切换字体大小、元素间距等。
解决方案
项目使用element-ui
、sass
、sass-loader
,在scss文件中定义变量,并利用:export
导出变量,供JS使用。JS中读取变量,使用setProperty
方法设置全局css变量。项目中所有需要动态改变大小的,都不直接使用px,而是使用css变量进行设置。
使用开关动态切换常规/老年人模式变量,以切换全局css变量值。
以下是代码的实现:
目录结构
1 2 3 4 5 6
| src ├── styles │ ├── index.scss │ ├── variables.scss │ └── variables-senior.scss └── App.vue
|
关键代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
|
$main_color: #4077f4;
$variables: ( // 字号 font_size_extra_large: 20px, font_size_large: 18px, font_size_medium: 16px, font_size_base: 14px, font_size_small: 13px, font_size_extra_small: 12px, // checkbox checkbox_after_left: 4px, checkbox_after_top: 1px, // 表单项 form_item_margin_bottom: 16px, search_btn_width: 70px, search_btn_detail_width: 60px ); :export { main_color: $main_color;
@each $name, $value in $variables { #{$name}: #{$value}; } }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
|
$font_size_increment: 5px;
$variables: ( // 字号 font_size_extra_large: 20px + $font_size_increment, font_size_large: 18px + $font_size_increment, font_size_medium: 16px + $font_size_increment, font_size_base: 14px + $font_size_increment, font_size_small: 13px + $font_size_increment, font_size_extra_small: 12px + $font_size_increment, // checkbox checkbox_after_left: 6px, checkbox_after_top: 3px, // 表单项 form_item_margin_bottom: 24px, search_btn_width: 80px, search_btn_detail_width: 80px ); :export { @each $name, $value in $variables { #{$name}: #{$value}; } }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
| <template> <div id="app" :class="{ 'senior-mode': isSeniorMode }"> <el-switch v-model="isSeniorMode" @change="toggleMode"> 老年人模式 </el-switch> <router-view /> </div> </template> <script> import normalVariables from "@/styles/variables.scss" import seniorVariables from "@/styles/variables-senior.scss" export default { name: "app", data() { return { isSeniorMode: false, } }, mounted() { this.setMode() }, methods: { toggleMode() { this.setMode(this.isSeniorMode) }, setMode(isSenior = false) { const vars = isSenior ? seniorVariables : normalVariables for (const [key, value] of Object.entries(vars)) { document.documentElement.style.setProperty(`--${key}`, value) } } } } </script>
|
1 2 3 4 5 6 7 8 9 10 11 12 13
| .el-button { font-size: var(--font_size_base); &--mini { font-size: var(--font_size_extra_small); } &--small { font-size: var(--font_size_base); } &--medium { font-size: var(--font_size_medium); } }
|
结语
这个方案的效果还是比较满意的,衍生出来还可以封装成组件,实现大中小三种字号切换的模式