做大屏项目的注意点和总结

echarts图表参考案例(https://www.makeapie.cn/echa

1.封装图表echarts组件

<template>
  <div class="chart-box">
    <div ref="chartDom" class="chart-wrap"></div>
  </div>
</template>

<script  setup>
import { ref, watchEffect, computed,inject } from 'vue'
import { useEventListener } from '@vueuse/core'
import { deepMerge } from '@/utils'

const props = defineProps({
  option: Object,
  theme: String,
  color: String,
})

// const store = useStore()
// const dark = computed(() => (props.theme || store.state.settings.dark ? 'dark' : 'light'))
const dark =ref('dark')
const optionRef = computed(() => props.option)
const echarts = inject('echarts')
const chartDom = ref(null)
let echartsInstance

const disposeChart = () => {
  echartsInstance && echartsInstance.dispose()
}

const initChart = (container) => {
  const { color: _color = '#fff' } = props
  const color = dark.value === 'dark' ? '#fff' : _color
  const defaultOption = {
    legend: {
      itemWidth: 20,
      itemHeight: 10,
      textStyle: {
        color,
      },
    },
    textStyle: {
      color,
      fontSize: 10,
    },
    backgroundColor: 'transparent',
  }
  const _option = deepMerge(defaultOption, optionRef.value)
  echartsInstance = echarts.init(container, dark.value)
  echartsInstance.setOption(_option)
  
  useEventListener(window, 'resize', function () {
    echartsInstance?.resize()
  })
}

const getEchartsInstance = () => echartsInstance

watchEffect((onCleanup) => {
  if (!chartDom.value || !optionRef.value) return
  onCleanup(disposeChart)
  initChart(chartDom.value)
})

defineExpose({
  getEchartsInstance,
})
</script>

<style lang="scss" scoped>
.chart-box {
  height: 100%;
  .chart-wrap {
    height: 100%;
  }
  // @media screen and (min-width: 3800px) {
  //   .chart-wrap {
  //     height: 50%;
  //     width: 50%;
  //     transform: scale(2);
  //     transform-origin: 0 0;
  //   }
  // }
}
</style>

2.echarts图表字体大小自适应(一般情况下页面实现自适应之后,字体也会随着缩放,不用使用该方法了)

// 字体转换 px -> rem
export function fontChart (res) {
  const clientWidth =
    window.innerWidth ||
    document.documentElement.clientWidth ||
    document.body.clientWidth
  if (!clientWidth) return
  // 此处的3840 为设计稿的宽度,记得修改!
  const fontSize = clientWidth / 1920
  console.log(res * fontSize, '文字')
  return res * fontSize
}

// 字体转换 px -> rem
export function transfromFontSize (res) {
  const clientWidth = window.screen.width

  // 此处的3840 为设计稿的宽度,记得修改!
  const fontSize = clientWidth / 1920

  console.log(res * fontSize, '折线图文字')
  return res * fontSize
}

3.大屏项目自适应

a.这是初版,会出现留白的情况

import { onMounted, onUnmounted } from "vue";
import _ from "lodash";

export default function useScalePage(option = {}) {
  let resizeChange = _.throttle(function () {
    triggerScale();
  }, 100);

  onMounted(function () {
    console.log("useScale onmounted");
    triggerScale();
    window.addEventListener("resize", resizeChange);
  });

  onUnmounted(function () {
    console.log("useScale onUnmounted");
    window.removeEventListener("resize", resizeChange);
  });
  console.log("111", option);
  function triggerScale() {
      // let targetX = option.targetX || 1920;
      // let targetY = option.targetY || 1080;
      // 这里面是设计稿的宽高
      let targetX = 1920
      let targetY = 1080
      let targetRatio = option.targetRatio || 16 / 9

      // 1.拿到当前屏幕的宽高
      let currentX =
          document.documentElement.clientWidth || document.body.clientWidth
      let currentY =
          document.documentElement.clientHeight || document.body.clientHeight

      // 2.计算缩放的比例
      let scaleRatio = currentX / targetX

      // 当前的屏幕宽高比
      let currentRatio = currentX / currentY
      if (currentRatio > targetRatio) {
          scaleRatio = currentY / targetY
          // 3.设置缩放( 类似图片放大 )
          document.body.setAttribute(
              'style',
              `width:${targetX}px;height:${targetY}px;transform: scale(${scaleRatio})  translateX(-50%); left:50%`
          )
      } else {
          // 3.设置缩放( 类似图片放大 )
          document.body.setAttribute(
              'style',
              `width:${targetX}px;height:${targetY}px;transform: scale(${scaleRatio})`
          )
      }
  }
}

b.这是更改的第二版,不会出现留白,但是一些奇怪的分辨率下可能会模糊

import { onMounted, onUnmounted } from "vue";
import _ from "lodash";

export const useScalePageByTransfer = (option = {}) => {
  // screen.availHeight:用来显示浏览器的屏幕的可用高度
  let screenWidth = option.targetX
  //  screen.availWidth:用来显示浏览器的屏幕的可用宽度。
  let screenHeight = option.targetY
  let scaleX = screenWidth / 1920
  let scaleY = screenHeight / 1080
  // transform-origin:left top;(以左上角为基点)
  document.body.setAttribute(
    'style',
    `width:1920px;height:1080px;transformOrigin:left top;transform: scale(${scaleX}, ${scaleY})`
)
}

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Vue项目可视化大屏自适应缩放可以尝试以下几个方案: 1. 使用CSS3的transform属性进行缩放 在Vue组件中设置一个容器元素,通过CSS3的transform属性对容器元素进行缩放,可以实现自适应缩放的效果。在容器元素的父元素中监听resize事件,根据父元素的宽度和高度来计算缩放比例,然后通过CSS3的transform属性对容器元素进行缩放。 示例代码: ```html <template> <div class="container" ref="container"> <!-- 可视化大屏内容 --> </div> </template> <script> export default { mounted() { window.addEventListener('resize', this.handleResize) }, beforeDestroy() { window.removeEventListener('resize', this.handleResize) }, methods: { handleResize() { const container = this.$refs.container const parentWidth = container.parentNode.clientWidth const parentHeight = container.parentNode.clientHeight const contentWidth = container.offsetWidth const contentHeight = container.offsetHeight const scaleX = parentWidth / contentWidth const scaleY = parentHeight / contentHeight container.style.transform = `scale(${Math.min(scaleX, scaleY)})` } } } </script> <style> .container { transform-origin: top left; } </style> ``` 2. 使用Vue的自定义指令进行缩放 在Vue项目中可以创建一个自定义指令,通过该指令来实现自适应缩放的效果。在指令中监听resize事件,根据父元素的宽度和高度来计算缩放比例,然后通过CSS3的transform属性对元素进行缩放。 示例代码: ```html <template> <div class="container" v-resize-scale> <!-- 可视化大屏内容 --> </div> </template> <script> export default { directives: { resizeScale: { inserted(el) { function handleResize() { const parentWidth = el.parentNode.clientWidth const parentHeight = el.parentNode.clientHeight const contentWidth = el.offsetWidth const contentHeight = el.offsetHeight const scaleX = parentWidth / contentWidth const scaleY = parentHeight / contentHeight el.style.transform = `scale(${Math.min(scaleX, scaleY)})` } window.addEventListener('resize', handleResize) handleResize() }, unbind() { window.removeEventListener('resize', this.handleResize) } } } } </script> <style> .container { transform-origin: top left; } </style> ``` 以上两种方案可以根据实际需求进行选择,第一种方案比较简单,但是需要在组件中手动监听resize事件,第二种方案可以通过Vue的自定义指令来实现缩放效果,使得组件代码更加简洁。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值