uniapp+vue3+vite使用echarts指南

4,040 阅读4分钟

想要在uniapp上使用原汁原味的echarts推荐使用DCloud插件市场的这个插件:echarts

正常使用的话直接看这个插件的文档即可,没啥好说的,用起来好是好,就是有个最大的问题。

echarts实在是太大了,那么很容易想到进行分包是吧,但是很多时候主包就是需要用到图表展示内容,那有什么办法既把echarts分离到单独的分包中,又可以在主包中使用呢?

我当时也是搜了一些内容确实没怎么找到关于这一套uniapp+vue3+vite搭建下来的如何处理的文章,那么就自己记录一下,核心利用的就是微信小程序的分包异步化,目前uniapp也是支持的。

想了解更多分包异步化的可以看这篇文章:微信小程序分包异步化实践

下面开始正文:

1.下载echarts

首先是下载上面推荐的echarts插件,下载后我们专门创建一个文件夹名为echarts用来对echarts进行分包,保留截图中的这些文件

image.png

这是pages.json中的代码:专门分一个包并且开启预加载

image.png

{
	"subPackages": [
		{
			"root": "echarts",
			"pages": [
				{
					"path": "index",
					"style": {
						"navigationBarTitleText": "echarts测试"
					}
				}
			]
		}
	],
	"preloadRule": {
		"pages/home/index": {
			"network": "all",
			"packages": [
				"echarts"
			]
		}
	}
}

如何确保h5和app端也可以正常渲染,由于vite的原因不支持使用require方式导入echarts,所以为了其他端也可以保持一致我们需要通过npm安装echarts

npm i echarts

2.封装echarts成组件使用

我们通过uniapp的条件编译区分导入方式,下面是对echarts组件的简单封装,使用只需要导入这个后传入options即可渲染了,改变options即可刷新echarts

<template>
  <LEchart class="w-100% h-100%" ref="chartRef" />
</template>

<script setup>
import LEchart from './l-echart/l-echart.vue'
import { ref, watch, nextTick, onMounted } from 'vue'

// #ifdef MP
const echarts = require('./static/echarts.min')
// #endif

// #ifndef MP
import * as echarts from 'echarts'
// #endif

const props = defineProps({
  options: {
    type: Object,
    default: () => ({})
  }
})

const chartRef = ref(null)

const initData = async (data) => {
  await nextTick()
  console.log('chartRef.value',chartRef.value);
  if (chartRef.value) {
    const myChart = await chartRef.value.init(echarts)
    myChart.setOption(data)
  }
}

onMounted(()=>{
    setTimeout(()=>{
        initData(props.options)
    },200)
})

watch(() => props.options, (newValue) => {
  initData(newValue)
}, {
  deep: true
})

</script>

<style lang="scss" scoped></style>

我们需要创建一个index页来确保该分包有被使用到(pages.json有引用该index),否则不会打包进微信小程序中

3.分包中正常使用echarts

以下是echarts/index,即一般使用echarts的方式

<template>
  <div class="w-100% h-100%">
    <div class="w-100% h-300rpx">
      <BaseCharts :options="options" />
    </div>
  </div>
</template>

<script setup>
import { ref } from 'vue'
import BaseCharts from './BaseCharts.vue'

const options = ref({
  grid: {
    left: '3%',
    right: '6%',
    bottom: '3%',
    top: '8%',
    containLabel: true
  },
  tooltip: {
    trigger: 'axis',
    confine: true
  },
  xAxis: {
    boundaryGap: false,
    type: 'category',
    axisLabel: {
      color: '#999999'
    },
    axisTick: {
      show: false
    },
    axisLine: {
      show: false
    },
    data: ['03:00', '06:00', '07:00', '12:00', '15:00', '18:00', '21:00']
  },
  yAxis: {
    type: 'value',
    axisLabel: {
      color: '#999999'
    }
  },
  series: [
    {
      smooth: true,
      symbolSize: 0,
      lineStyle: {
        normal: {
          color: '#8dadfa' // 线条颜色
        }
      },
      data: [150, 224, 218, 135, 147, 113, 211],
      type: 'line'
    }
  ]
})

setTimeout(() => {
  options.value.series[0].data = [15, 24, 18, 13, 47, 13, 21]
}, 3000)

</script>

<style lang="scss" scoped>

</style>

那么此时echarts已经可以正常在分包中使用了,那主包中某些页面要使用如何操作?

4.主包中使用分包的echarts

比如下面主包的这个页面我想使用echarts,红圈框起来的部分是重点,即分包异步化

image.png

在每个需要使用的页面都需要写上下面的这个,名称可以自己换,但需要保持 xx-xx 的形式

"componentPlaceholder": {
        "base-chart": "view"
}

下面是这个测试页的内容截图,即pages/use-charts页,必须要导入echarts中封装好的组件,注意重命名后的组件需要跟componentPlaceholder定义的名称保持一致,然后template中使用的就是componentPlaceholder中定义好的base-chart

image.png

这样就可以在主包中正常使用啦,且不会打包进主包,下面是build到微信小程序后的截图,可以看到echarts都在主包中。

image.png

5.各端的显示正常

这是微信开发者工具中显示的主包的pages/use-charts页,echarts正常渲染 image.png

这是h5的显示,也没问题,app同样也是正常的

image.png

好了,本篇文章的记录就到此结束啦,如果有帮到各位可以给我点个赞🤭🤭

demo地址:gitee.com/monsterwx/u…

--------------------------------------------2024-06-06更新-----------------------------------

这个方案唯一的问题就是比如你在主包中又包装了一层将这个作为一个组件使用,那么在微信小程序上是无法渲染的,解决方案就是在分包中去封装成一个组件,然后主包中异步加载这个组件。 比如: 我把它抽离成组件引入它,微信小程序不会渲染

image.png

image.png

但是如果我直接写在分包中作为组件

image.png

加载组件

image.png

就可以正确渲染

image.png

这是唯一的坑点