Tích hợp ECharts vào dự án Uni-app sử dụng renderjs

1. Chuẩn bị tài nguyên

Để bắt đầu, bạn cần tải bản phân phối của ECharts (ví dụ: echarts.min.js) từ trang chủ hoặc các CDN uy tín. Sau đó, hãy tạo thư mục và lưu trữ tệp tin theo cấu trúc gợi ý sau:

  • static/lib/echarts.min.js: Thư viện lõi.
  • static/geo/world.json: Dữ liệu bản đồ (nếu bạn cần vẽ bản đồ thế giới).

2. Xây dựng Component ECharts tùy chỉnh

Trong Uni-app, việc thao tác trực tiếp với DOM để khởi tạo ECharts trên môi trường App và H5 yêu cầu sử dụng renderjs. Kỹ thuật này giúp tối ưu hiệu năng bằng cách chạy mã logic đồ họa trực tiếp dưới layer trình duyệt.

<template>
    <view class="chart-container">
        <!-- #ifdef APP-PLUS || H5 -->
        <view class="chart-canvas" 
            :id="viewId" 
            :prop="chartOptions" 
            :change:id="chartService.updateId"
            :change:prop="chartService.refreshChart">
        </view>
        <!-- #endif -->
        
        <!-- #ifndef APP-PLUS || H5 -->
        <view class="error-msg">Môi trường hiện tại không hỗ trợ renderjs</view>
        <!-- #endif -->
    </view>
</template>

<script>
export default {
    props: {
        chartOptions: {
            type: Object,
            default: () => ({})
        },
        onInit: {
            type: Function,
            default: null
        }
    },
    data() {
        return {
            viewId: `canvas_${Math.random().toString(36).substr(2, 9)}`
        };
    },
    methods: {
        emitReady(payload) {
            this.$emit('ready', payload);
        }
    }
}
</script>

<script module="chartService" lang="renderjs">
export default {
    data() {
        return {
            instanceId: '',
            chartInstance: null
        }
    },
    mounted() {
        if (typeof window.echarts === 'object') {
            this.initEngine();
        } else {
            const script = document.createElement('script');
            script.src = 'static/lib/echarts.min.js';
            script.onload = () => this.initEngine();
            document.head.appendChild(script);
        }
    },
    beforeDestroy() {
        if (this.chartInstance) {
            window.removeEventListener('resize', this.onResize);
            this.chartInstance.dispose();
        }
    },
    methods: {
        updateId(newId) {
            this.instanceId = newId;
        },
        initEngine() {
            const container = document.getElementById(this.instanceId);
            if (!container) return;
            
            this.chartInstance = echarts.init(container);
            this.chartInstance.setOption(this.prop || {});
            
            window.addEventListener('resize', this.onResize);
            this.$ownerInstance.callMethod('emitReady', { id: this.instanceId });
        },
        refreshChart(newVal) {
            if (this.chartInstance && newVal) {
                this.chartInstance.setOption(newVal, true);
            }
        },
        onResize() {
            this.chartInstance && this.chartInstance.resize();
        }
    }
}
</script>

<style scoped>
.chart-container {
    width: 100%;
    height: 100%;
}
.chart-canvas {
    width: 100%;
    height: 100%;
    min-height: 200px;
}
</style>

3. Sử dụng Component và đăng ký bản đồ

Dưới đây là cách sử dụng component vừa tạo để hiển thị một bản đồ thế giới đơn giản.

<template>
    <view class="page-wrapper">
        <view class="map-box">
            <base-chart :chartOptions="mapConfig" @ready="onChartInited" />
        </view>
    </view>
</template>

<script>
import worldGeoData from '@/static/geo/world.json';
import BaseChart from '@/components/BaseChart.vue';

export default {
    components: { BaseChart },
    data() {
        return {
            mapConfig: {
                geo: {
                    map: 'world_map',
                    roam: true,
                    itemStyle: {
                        areaColor: '#f2f2f2',
                        borderColor: '#999'
                    }
                },
                series: []
            }
        };
    },
    methods: {
        onChartInited(data) {
            // Đăng ký map dữ liệu cho ECharts thông qua renderjs hoặc inject trực tiếp
            if (typeof echarts !== 'undefined') {
                echarts.registerMap('world_map', worldGeoData);
            }
        }
    }
}
</script>

<style>
.page-wrapper {
    padding: 20px;
}
.map-box {
    width: 100%;
    height: 500px;
}
</style>

Lưu ý kỹ thuật

Khi làm việc với renderjs trong Uni-app, hãy nhớ rằng mã bên trong script renderjs chạy trong môi trường trình duyệt, trong khi script thông thường chạy trong môi trường logic của Uni-app (Service Layer). Sự giao tiếp giữa hai môi trường này được thực hiện thông qua cơ chế prop và callMethod.

Thẻ: UniApp echarts renderjs JavaScript Vue.js

Đăng vào ngày 26 tháng 10 lúc 21:59