增加字体大小设置

This commit is contained in:
2026-07-03 11:45:16 +08:00
parent 451dd2330b
commit c3bd7960d0
28 changed files with 894 additions and 94 deletions
+297
View File
@@ -0,0 +1,297 @@
<template>
<view class="page-container">
<scroll-view class="page-body" scroll-y>
<view class="settings-section">
<!-- 字体大小调整 -->
<view class="setting-card">
<view class="card-header">
<uni-icons type="font" size="20" color="#722ed1"></uni-icons>
<text class="card-title">字体大小</text>
</view>
<view class="font-preview">
<text class="preview-text" :style="{ fontSize: previewFontSize + 'px' }">预览文字大小</text>
</view>
<view class="slider-section">
<view class="slider-labels">
<text class="label-small"></text>
<text class="label-current">{{ currentFontLabel }}</text>
<text class="label-large"></text>
</view>
<slider
class="font-slider"
:value="sliderValue"
:min="0"
:max="3"
:step="1"
:activeColor="sliderColor"
:backgroundColor="'#e8e8e8'"
block-size="24"
@change="onSliderChange"
@changing="onSliderChanging"
show-value
/>
<view class="slider-values">
<text class="value-text">100%</text>
<text class="value-text">125%</text>
<text class="value-text">150%</text>
<text class="value-text">200%</text>
</view>
</view>
<view class="font-actions">
<button class="btn-reset" @click="resetToDefault">恢复默认</button>
</view>
</view>
<!-- 提示信息 -->
<view class="tip-card">
<uni-icons type="info" size="16" color="#fa8c16"></uni-icons>
<text class="tip-text">调整后会立即生效所有页面的文字大小都会同步变化</text>
</view>
</view>
</scroll-view>
</view>
</template>
<script>
import { mapState, mapGetters } from 'vuex'
export default {
data() {
return {
// 字体大小选项
fontSizeOptions: [
{ label: '默认', value: 1.0, desc: '标准字体', sliderIndex: 0 },
{ label: '大', value: 1.25, desc: '放大 25%', sliderIndex: 1 },
{ label: '较大', value: 1.5, desc: '放大 50%', sliderIndex: 2 },
{ label: '最大', value: 2.0, desc: '放大 100%', sliderIndex: 3 }
],
previewFontSize: 16
}
},
computed: {
// 从 Vuex 读取字体状态
...mapState('font', ['fontScale']),
...mapGetters('font', ['fontScaleLabel']),
// 当前滑块值
sliderValue: {
get() {
const option = this.fontSizeOptions.find(opt => opt.value === this.fontScale)
return option ? option.sliderIndex : 0
},
set(value) {
// 滑块值改变时应用到 Vuex
this.applyFontSetting(value)
}
},
// 当前字体标签
currentFontLabel() {
return this.fontScaleLabel
},
// 滑块颜色
sliderColor() {
const colors = ['#52c41a', '#1890ff', '#fa8c16', '#f5222d']
return colors[this.sliderValue] || '#1890ff'
}
},
onLoad() {
// 初始化时应用当前字体设置到预览
this.updatePreview()
},
methods: {
/**
* 滑块值改变(拖动结束)
*/
onSliderChange(e) {
const index = e.detail.value
this.applyFontSetting(index)
},
/**
* 滑块值改变(拖动中)
*/
onSliderChanging(e) {
const index = e.detail.value
const option = this.fontSizeOptions[index]
if (option) {
// 拖动中只更新预览,不实际应用
this.previewFontSize = 16 * option.value
}
},
/**
* 应用字体设置到 Vuex
*/
applyFontSetting(sliderIndex) {
const option = this.fontSizeOptions[sliderIndex]
if (!option) return
// 通过 Vuex action 设置字体
this.$store.dispatch('font/setFontScale', {
scale: option.value,
label: option.label
})
// 提示用户
uni.showToast({
title: `已设置为${option.label}`,
icon: 'success',
duration: 1500
})
this.updatePreview()
},
/**
* 更新预览字体大小
*/
updatePreview() {
// 基准字体大小 16px,根据缩放比例计算预览大小
this.previewFontSize = 16 * this.fontScale
},
/**
* 恢复默认设置
*/
resetToDefault() {
uni.showModal({
title: '提示',
content: '确定要恢复默认字体大小吗?',
success: (res) => {
if (res.confirm) {
// 通过 Vuex action 重置字体
this.$store.dispatch('font/resetFontScale')
uni.showToast({
title: '已恢复默认',
icon: 'success'
})
this.updatePreview()
}
}
})
}
}
}
</script>
<style lang="scss" scoped>
.settings-section {
padding: $spacing-md;
}
.setting-card {
background: #ffffff;
border-radius: $border-radius-md;
padding: $spacing-lg;
margin-bottom: $spacing-base;
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.05);
}
.card-header {
display: flex;
align-items: center;
gap: $spacing-sm;
margin-bottom: $spacing-lg;
.card-title {
font-size: $font-size-md;
color: $text-primary;
font-weight: 600;
}
}
.font-preview {
background: #f9f9f9;
border-radius: $border-radius-sm;
padding: $spacing-lg;
text-align: center;
margin-bottom: $spacing-lg;
.preview-text {
color: $text-primary;
font-weight: 500;
}
}
.slider-section {
margin-bottom: $spacing-lg;
.slider-labels {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: $spacing-sm;
.label-small,
.label-large {
font-size: $font-size-sm;
color: $text-placeholder;
}
.label-current {
font-size: $font-size-md;
color: $primary-color;
font-weight: 600;
}
}
.font-slider {
margin: $spacing-sm 0;
}
.slider-values {
display: flex;
justify-content: space-between;
padding: 0 $spacing-xs;
.value-text {
font-size: $font-size-xs;
color: $text-placeholder;
}
}
}
.font-actions {
display: flex;
justify-content: center;
.btn-reset {
background: #fff;
color: $text-secondary;
border: 1px solid $border-light;
border-radius: $border-radius-sm;
padding: $spacing-sm $spacing-lg;
font-size: $font-size-sm;
line-height: 1.5;
&::after {
border: none;
}
}
}
.tip-card {
background: #fff7e6;
border-radius: $border-radius-sm;
padding: $spacing-md;
display: flex;
align-items: flex-start;
gap: $spacing-sm;
.tip-text {
font-size: $font-size-sm;
color: #d48806;
line-height: 1.6;
flex: 1;
}
}
</style>