utils - setFontSize - 设置字体大小
intro


原理
使用 postcss-plugin-px2rem
将 px
转为rem
,在根节点设置font-size
notice
webpack ie 兼容
babel 处理 node_modules 文件
rem 是基于html,不是body
style
postcss-plugin-px2rem
未转换 style
内 px
解决方案
- 调用转换方法
| // xxx.vue |
| <el-table-column |
| :width="pxtorem(100)" |
| ></el-table-column> |
| |
| |
| |
| |
| |
| |
| export function pxtorem(size = 0, base = 16) { |
| let baseSize = formatValue(document.documentElement.style.fontSize); |
| base = formatValue(base); |
| return baseSize === base |
| ? formatValue(size) |
| : (formatValue(size) * baseSize) / base; |
| } |
| |
| export function formatValue(val, offset = 1.03) { |
| let type = Object.prototype.toString.call(val).slice(8, -1), |
| methods = { |
| String: () => Number(val.replace('px', '')), |
| Number: () => val, |
| }; |
| return methods[type] |
| ? (() => { |
| return methods[type]() * offset; |
| })() |
| : (() => { |
| throw new Error( |
| `Params not support ${type}, please use String or Number!!!` |
| ); |
| })(); |
| } |
utils
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| class SetFontSize { |
| constructor(options = {}) { |
| Object.assign( |
| this, |
| { |
| currentType: null, |
| defaultType: null, |
| openResize: true, |
| |
| |
| resizeTarget: 'document', |
| currentResizeKey: null, |
| |
| resizeOptions: { |
| 1366: 'small', |
| 1920: 'medium', |
| }, |
| |
| types: { |
| default: '', |
| large: 18, |
| medium: 16, |
| small: 14, |
| mini: 12, |
| }, |
| change: null, |
| iframeDom: null, |
| }, |
| options |
| ); |
| } |
| init(options = {}) { |
| Object.assign(this, options); |
| |
| this.resizeOptionsToArray(); |
| |
| this.defaultType ? this.set() : this.resize(); |
| if (this.openResize) |
| window.onresize = this.throttle(this.resize.bind(this)); |
| |
| } |
| resize() { |
| let type = this.getResizeType(); |
| if (type !== this.currentType) this.set(type); |
| } |
| resizeOptionsToArray() { |
| this.resizeOptionsArray = Object.entries(this.resizeOptions) |
| .map((v) => { |
| return { |
| size: v[0], |
| type: v[1], |
| }; |
| }) |
| .sort((a, b) => a.size - b.size); |
| } |
| getResizeType() { |
| const widths = { |
| window: () => window.screen.width, |
| document: () => document.body.clientWidth, |
| }; |
| const resizeWidth = widths[this.resizeTarget](); |
| for (let { size, type } of this.resizeOptionsArray) { |
| if (resizeWidth <= size) { |
| this.currentResizeKey = size; |
| return type; |
| } |
| } |
| return 'small'; |
| } |
| set(type = this.defaultType || 'small') { |
| |
| if (!this.types[type]) { |
| console.warn(`${type} fontSize not exist!!!`); |
| return this.resize(); |
| } |
| document.documentElement.style.fontSize = this.types[type] + 'px'; |
| if (type !== this.currentType) { |
| this.currentType = type; |
| if (typeof this.change === 'function') this.change(type); |
| } |
| if (this.iframeDom) this.setIframe(); |
| } |
| initIframe(iframeDom) { |
| this.iframeDom = iframeDom; |
| Object.assign(iframeDom, { |
| onload: this.iframeOnload.bind(this), |
| }); |
| } |
| setIframe(type = this.currentType) { |
| this.iframeDom.contentDocument.documentElement.style.fontSize = this.types[type] + 'px'; |
| } |
| iframeOnload() { |
| this.setIframe(); |
| } |
| throttle(func, delay = 1000) { |
| var timer = null; |
| return function() { |
| var context = this; |
| var args = arguments; |
| if (!timer) { |
| timer = setTimeout(function() { |
| func.apply(context, args); |
| timer = null; |
| }, delay); |
| } |
| }; |
| } |
| } |
| |
| export default new SetFontSize(); |
使用
初始化
| |
| import setFontSize from '@/utils/setFontSize'; |
| import { resizeOptions } from '@/config'; |
| setFontSize.init({ |
| resizeOptions { |
| 1366: 'mini', |
| 1920: 'medium', |
| 1520: 'small', |
| }, |
| defaultType: Cookies.get('size'), |
| change: (size) => { |
| store.commit('config/SET_SIZE', size); |
| }, |
| }); |
change.vue
| <template> |
| <el-dropdown trigger="click" @command="handleSetSize"> |
| <div> |
| <svg-icon class-name="size-icon" icon-class="size" /> |
| </div> |
| <el-dropdown-menu slot="dropdown"> |
| <el-dropdown-item v-for="item of sizeOptions" :key="item.value" :disabled="size===item.value" :command="item.value"> |
| {{ |
| item.label }} |
| </el-dropdown-item> |
| </el-dropdown-menu> |
| </el-dropdown> |
| </template> |
| |
| <script> |
| export default { |
| data() { |
| return { |
| sizeOptions: [ |
| { label: 'Default', value: 'default' }, |
| { label: 'Large', value: 'large' }, |
| { label: 'Medium', value: 'medium' }, |
| { label: 'Small', value: 'small' }, |
| { label: 'Mini', value: 'mini' } |
| ] |
| } |
| }, |
| computed: { |
| size() { |
| return this.$store.state.config.size |
| } |
| }, |
| methods: { |
| handleSetSize(size) { |
| this.$ELEMENT.size = size |
| this.$store.dispatch('config/setSize', size) |
| |
| this.$message({ |
| message: 'Switch Size Success', |
| type: 'success' |
| }) |
| }, |
| refreshView() { |
| |
| this.$store.dispatch('tagsView/delAllCachedViews', this.$route) |
| |
| const { fullPath } = this.$route |
| |
| this.$nextTick(() => { |
| |
| |
| this.$router.replace({ |
| path: '/redirect' + fullPath |
| }) |
| }) |
| } |
| } |
| |
| } |
| </script> |
| |
iframe 同步 rem


| setFontSize.initIframe(this.$refs.iframeDom); |
| |
| initIframe(iframeDom) { |
| this.iframeDom = iframeDom; |
| Object.assign(iframeDom, { |
| onload: this.iframeOnload.bind(this), |
| }); |
| } |
| setIframe(type = this.currentType) { |
| this.iframeDom.contentDocument.documentElement.style.fontSize = this.types[type] + 'px'; |
| } |
| set(type = this.defaultType || 'small') { |
| |
| if (!this.types[type]) { |
| console.warn(`${type} fontSize not exist!!!`); |
| return this.resize(); |
| } |
| document.documentElement.style.fontSize = this.types[type] + 'px'; |
| if (type !== this.currentType) { |
| this.currentType = type; |
| if (typeof this.change === 'function') this.change(type); |
| } |
| if (this.iframeDom) this.setIframe(); |
| } |
store
| |
| import setFontSize from '@/utils/setFontSize' |
| const state = { |
| size: Cookies.get('size') || 'medium', |
| } |
| |
| const mutations = { |
| SET_SIZE: (state, size) => { |
| state.size = size |
| Cookies.set('size', size) |
| } |
| } |
| |
| const actions = { |
| setSize({ commit }, size) { |
| setFontSize.set(size) |
| commit('SET_SIZE', size) |
| } |
| } |
| |
| export default { |
| namespaced: true, |
| state, |
| mutations, |
| actions |
| } |
| |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步