298 lines
7.0 KiB
Vue
298 lines
7.0 KiB
Vue
<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>
|