在【微信开发者工具】的真机调试没有问题,但是上线后就无法显示了,图片如图:图1是上线后的,图2是真机模拟的。


<template>
<view style="height: 600rpx">
<view class="chart-container" :style="{height: '600rpx'}">
<l-echart
v-if="isAppReady && isEchartsReady && !chartInitError"
ref="chart"
:canvas-id="canvasId"
></l-echart>
</view>
</view>
<view class="container">
<view class="main-content">
<view class="stats-section">
<view class="section-header">
<view class="section-title">
<text>全国省份数据分析</text>
</view>
<view class="time-filter">
<view class="filter-tabs">
<view
class="filter-tab"
:class="{ active: timeRange === 'day' }"
@click="changeTimeRange('day')"
>
今日
</view>
<view
class="filter-tab"
:class="{ active: timeRange === 'week' }"
@click="changeTimeRange('week')"
>
本周
</view>
<view
class="filter-tab"
:class="{ active: timeRange === 'month' }"
@click="changeTimeRange('month')"
>
本月
</view>
</view>
</view>
</view>
<view class="total-machine-count">
<text class="total-label">总数据量</text>
<text class="total-value">{{ animatedTotalMachines }}</text>
</view>
<view class="machine-type-filter">
<view
class="type-tab"
:class="{ active: selectedType === 'all' }"
@click="changeMachineType('all')"
>
全部
</view>
<view
class="type-tab"
:class="{ active: selectedType === 'province' }"
@click="changeMachineType('province')"
>
省份
</view>
<view
class="type-tab"
:class="{ active: selectedType === 'city' }"
@click="changeMachineType('city')"
>
直辖市
</view>
<view
class="type-tab"
:class="{ active: selectedType === 'special' }"
@click="changeMachineType('special')"
>
特别行政区
</view>
</view>
<view class="chart-container">
<view class="horizontal-chart">
<view class="horizontal-bars">
<view
class="horizontal-bar-item"
v-for="(item, index) in animatedChartData"
:key="index"
>
<view class="bar-label-horizontal">{{ item.shortLabel }}</view>
<view class="bar-container-horizontal">
<view
class="bar-fill-horizontal"
:style="{
width: `${item.animatedPercentage}%`,
backgroundColor: item.animatedColor,
minWidth: '10rpx',
borderRadius: '0 6rpx 6rpx 0',
transformOrigin: 'left',
boxShadow: '2rpx 0 8rpx rgba(0,0,0,0.1)'
}"
></view>
<view class="bar-value-horizontal">{{ item.animatedValue }}</view>
</view>
</view>
</view>
</view>
</view>
</view>
</view>
<view class="safe-area-bottom"></view>
</view>
</template>
<script>
let echartsCache = null;
export default {
data() {
return {
isAppReady: false,
isEchartsReady: false,
isLoading: true,
chartInitError: false,
errorMessage: '',
canvasId: 'chart_' + Date.now() + '_' + Math.random().toString(36).substr(2, 9),
chartInstance: null,
retryCount: 0,
maxRetries: 3,
retryTimer: null,
timeRange: 'day',
chartData: [],
animatedChartData: [],
totalMachines: 0,
animatedTotalMachines: 0,
selectedType: 'all',
animationDuration: 500,
isAnimating: false,
colorPalettes: {
'province': ['#4E79A7', '#A0CBE8'],
'city': ['#59A14F', '#8CD17D'],
'special': ['#B07AA1', '#D4A6C8'],
'default': ['#499894', '#86BCB6']
},
provinces: [
{ name: '北京市', type: 'city', shortName: '北京' },
{ name: '天津市', type: 'city', shortName: '天津' },
{ name: '上海市', type: 'city', shortName: '上海' },
{ name: '重庆市', type: 'city', shortName: '重庆' },
{ name: '河北省', type: 'province', shortName: '河北' },
{ name: '山西省', type: 'province', shortName: '山西' },
{ name: '辽宁省', type: 'province', shortName: '辽宁' },
{ name: '吉林省', type: 'province', shortName: '吉林' },
{ name: '黑龙江省', type: 'province', shortName: '黑龙江' },
{ name: '江苏省', type: 'province', shortName: '江苏' },
{ name: '浙江省', type: 'province', shortName: '浙江' },
{ name: '安徽省', type: 'province', shortName: '安徽' },
{ name: '福建省', type: 'province', shortName: '福建' },
{ name: '江西省', type: 'province', shortName: '江西' },
{ name: '山东省', type: 'province', shortName: '山东' },
{ name: '河南省', type: 'province', shortName: '河南' },
{ name: '湖北省', type: 'province', shortName: '湖北' },
{ name: '湖南省', type: 'province', shortName: '湖南' },
{ name: '广东省', type: 'province', shortName: '广东' },
{ name: '海南省', type: 'province', shortName: '海南' },
{ name: '四川省', type: 'province', shortName: '四川' },
{ name: '贵州省', type: 'province', shortName: '贵州' },
{ name: '云南省', type: 'province', shortName: '云南' },
{ name: '陕西省', type: 'province', shortName: '陕西' },
{ name: '甘肃省', type: 'province', shortName: '甘肃' },
{ name: '青海省', type: 'province', shortName: '青海' },
{ name: '台湾省', type: 'province', shortName: '台湾' },
{ name: '内蒙古自治区', type: 'province', shortName: '内蒙古' },
{ name: '广西壮族自治区', type: 'province', shortName: '广西' },
{ name: '西藏自治区', type: 'province', shortName: '西藏' },
{ name: '宁夏回族自治区', type: 'province', shortName: '宁夏' },
{ name: '新疆维吾尔自治区', type: 'province', shortName: '新疆' },
{ name: '香港特别行政区', type: 'special', shortName: '香港' },
{ name: '澳门特别行政区', type: 'special', shortName: '澳门' }
]
};
},
onLoad() {
console.log('页面开始加载,检查App状态...');
this.checkAppStatus();
setTimeout(() => {
this.updateChartData();
}, 500);
},
onUnload() {
if (this.retryTimer) {
clearTimeout(this.retryTimer);
this.retryTimer = null;
}
if (this.chartInstance) {
try {
this.chartInstance.dispose();
} catch (e) {
console.warn('清理图表实例失败:', e);
}
this.chartInstance = null;
}
},
methods: {
checkAppStatus() {
try {
const app = getApp();
console.log('getApp()返回:', app);
if (app && app.$vm) {
console.log('App实例已准备好,$vm存在');
this.isAppReady = true;
this.loadEcharts();
} else {
console.log('App实例未完全准备好,等待...');
const delay = Math.min(1000, 100 * Math.pow(2, this.retryCount));
this.retryTimer = setTimeout(() => {
this.retryCount++;
if (this.retryCount <= this.maxRetries) {
console.log(`第${this.retryCount}次重试检查App状态...`);
this.checkAppStatus();
} else {
this.showError('应用初始化超时,请稍后重试');
}
}, delay);
}
} catch (error) {
console.error('检查App状态时出错:', error);
this.showError('应用状态检查失败: ' + error.message);
}
},
async loadEcharts() {
try {
console.log('开始加载ECharts...');
if (echartsCache) {
console.log('从缓存获取ECharts');
this.isEchartsReady = true;
this.initChartWithEcharts(echartsCache);
return;
}
const echartsModule = await this.loadEchartsModule();
if (echartsModule && echartsModule.default) {
echartsCache = echartsModule.default;
this.isEchartsReady = true;
this.initChartWithEcharts(echartsCache);
} else {
throw new Error('ECharts模块加载失败');
}
} catch (error) {
console.error('加载ECharts失败:', error);
this.showError('图表库加载失败: ' + error.message);
}
},
loadEchartsModule() {
return new Promise((resolve, reject) => {
const loadAttempts = [
() => {
try {
const echarts = require('../../../uni_modules/lime-echart/static/app/echarts.min.js');
resolve({ default: echarts });
} catch (e) {
throw new Error('Require加载失败: ' + e.message);
}
},
() => {
import('../../../uni_modules/lime-echart/static/app/echarts.min.js')
.then(resolve)
.catch(e => {
throw new Error('Import加载失败: ' + e.message);
});
}
];
const attemptLoad = (index) => {
if (index >= loadAttempts.length) {
reject(new Error('所有加载方式都失败了'));
return;
}
try {
loadAttempts[index]();
} catch (error) {
console.warn(`加载方式${index + 1}失败:`, error.message);
setTimeout(() => attemptLoad(index + 1), 300);
}
};
attemptLoad(0);
});
},
initChartWithEcharts(echarts) {
this.$nextTick(() => {
setTimeout(() => {
try {
if (!this.$refs.chart) {
throw new Error('图表组件引用不存在');
}
console.log('开始初始化图表组件...');
this.$refs.chart.init(echarts, async (chart) => {
this.chartInstance = chart;
await this.renderChartData(chart, echarts);
});
} catch (error) {
console.error('初始化图表组件失败:', error);
this.showError('图表初始化失败: ' + error.message);
}
}, 100);
});
},
async renderChartData(chart, echarts) {
try {
chart.showLoading();
const baseOption = {
title: {
text: '加载中国地图数据...',
left: 'center'
},
graphic: {
type: 'text',
left: 'center',
top: 'middle',
style: {
text: '数据加载中',
fill: '#999',
fontSize: 16
}
}
};
chart.setOption(baseOption);
const mapData = await this.fetchMapData();
if (!mapData || typeof mapData !== 'object') {
throw new Error('获取的地图数据格式不正确');
}
echarts.registerMap('china', mapData);
const fullOption = this.getChartOption();
chart.setOption(fullOption, true);
chart.hideLoading();
this.isLoading = false;
console.log('图表渲染完成');
} catch (error) {
console.error('渲染图表数据失败:', error);
chart.hideLoading();
const fallbackOption = {
title: {
text: '数据加载失败',
subtext: error.message || '请检查网络连接',
left: 'center',
top: 'center',
textStyle: {
color: '#f56c6c',
fontSize: 16
}
}
};
chart.setOption(fallbackOption, true);
this.showError('数据加载失败: ' + error.message);
}
},
fetchMapData() {
return new Promise((resolve, reject) => {
const timeout = 10000;
const timeoutId = setTimeout(() => {
reject(new Error('请求超时'));
}, timeout);
uni.request({
url: 'https://www.isqqw.com/asset/get/areas_v3/country/china.json',
timeout: 8000,
success: (res) => {
clearTimeout(timeoutId);
if (res.statusCode === 200 && res.data) {
resolve(res.data);
} else {
reject(new Error(`请求失败,状态码: ${res.statusCode}`));
}
},
fail: (err) => {
clearTimeout(timeoutId);
reject(new Error(`网络请求失败: ${err.errMsg || '未知错误'}`));
}
});
});
},
getChartOption() {
return {
title: {
text: '各省机器分布情况',
left: 'center',
textStyle: {
fontSize: 14
}
},
tooltip: {
trigger: 'item',
formatter: '{b} : {c}'
},
grid: {
left: '0%',
right: '0%',
top: '10%',
bottom: '0%',
containLabel: true
},
series: [{
name: '机器数量',
type: 'map',
map: 'china',
roam: false,
layoutCenter: ['50%', '50%'],
layoutSize: '130%',
label: {
show: true,
fontSize: 10
},
emphasis: {
label: {
show: true
}
},
}],
visualMap: {
show:false,
min: 0,
max: 1000,
text: ['数量'],
realtime: false,
calculable: true,
inRange: {
color: ['lightskyblue', 'yellow', 'orangered']
},
left: 'left',
top: 'bottom'
},
series: [{
name: '机器数量',
type: 'map',
map: 'china',
roam: false,
label: {
show: true,
fontSize: 10
},
emphasis: {
label: {
show: true
}
},
data: [
{ name: '北京', value: 112 },
{ name: '天津', value: 316 },
{ name: '河北', value: 300 },
{ name: '山西', value: 400 },
{ name: '内蒙古', value: 100 },
{ name: '辽宁', value: 200 },
{ name: '吉林', value: 150 },
{ name: '黑龙江', value: 344 },
{ name: '上海', value: 40 },
{ name: '江苏', value: 900 },
{ name: '浙江', value: 800 },
{ name: '安徽', value: 300 },
{ name: '福建', value: 700 },
{ name: '江西', value: 930 },
{ name: '山东', value: 310 },
{ name: '河南', value: 520 },
{ name: '湖北', value: 900 },
{ name: '湖南', value: 1000 },
{ name: '广东', value: 100 },
{ name: '广西', value: 10 },
{ name: '海南', value: 200 },
{ name: '重庆', value: 450 },
{ name: '四川', value: 710 },
{ name: '贵州', value: 299 },
{ name: '云南', value: 909 },
{ name: '西藏', value: 303 },
{ name: '陕西', value: 209 },
{ name: '甘肃', value: 180 },
{ name: '青海', value: 500 },
{ name: '宁夏', value: 180 },
{ name: '新疆', value: 380 },
{ name: '台湾', value: 506 },
{ name: '香港', value: 700 },
{ name: '澳门', value: 900 },
{ name: '南海诸岛', value: 900 },
]
}]
};
},
safeRetry() {
if (this.retryTimer) {
clearTimeout(this.retryTimer);
this.retryTimer = null;
}
if (this.chartInstance) {
try {
this.chartInstance.dispose();
} catch (e) {
}
this.chartInstance = null;
}
this.retryCount = 0;
this.chartInitError = false;
this.isLoading = true;
this.isAppReady = false;
this.isEchartsReady = false;
setTimeout(() => {
this.checkAppStatus();
}, 500);
},
showError(message) {
this.errorMessage = message;
this.chartInitError = true;
this.isLoading = false;
console.error('图表错误:', message);
},
changeTimeRange(range) {
if (this.timeRange === range || this.isAnimating) return;
this.timeRange = range;
this.updateChartData();
},
changeMachineType(type) {
if (this.selectedType === type || this.isAnimating) return;
this.selectedType = type;
this.updateChartData();
},
generateGradientColor(baseColor, intensity) {
const colors = {
'#4E79A7': ['#A0CBE8', '#4E79A7', '#2C5E9E'],
'#59A14F': ['#8CD17D', '#59A14F', '#2E7D32'],
'#B07AA1': ['#D4A6C8', '#B07AA1', '#8C5A7B'],
'#499894': ['#86BCB6', '#499894', '#2A6D6A']
};
const palette = colors[baseColor] || colors['#499894'];
if (intensity < 0.5) {
return this.interpolateColor(palette[0], palette[1], intensity * 2);
} else {
return this.interpolateColor(palette[1], palette[2], (intensity - 0.5) * 2);
}
},
interpolateColor(color1, color2, factor) {
const hex = color => {
const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(color);
return result ? {
r: parseInt(result[1], 16),
g: parseInt(result[2], 16),
b: parseInt(result[3], 16)
} : { r: 0, g: 0, b: 0 };
};
const c1 = hex(color1);
const c2 = hex(color2);
const r = Math.round(c1.r + (c2.r - c1.r) * factor);
const g = Math.round(c1.g + (c2.g - c1.g) * factor);
const b = Math.round(c1.b + (c2.b - c1.b) * factor);
return `#${r.toString(16).padStart(2, '0')}${g.toString(16).padStart(2, '0')}${b.toString(16).padStart(2, '0')}`;
},
getTypeBaseColor(type) {
return this.colorPalettes[type] ? this.colorPalettes[type][0] : this.colorPalettes.default[0];
},
updateChartData() {
if (this.isAnimating) return;
let provinceData = [];
if (this.timeRange === 'day') {
provinceData = this.provinces.map((province, index) => ({
name: province.name,
value: Math.floor(Math.random() * 100) + 10
}));
} else if (this.timeRange === 'week') {
provinceData = this.provinces.map((province, index) => ({
name: province.name,
value: Math.floor(Math.random() * 500) + 50
}));
} else if (this.timeRange === 'month') {
provinceData = this.provinces.map((province, index) => ({
name: province.name,
value: Math.floor(Math.random() * 1000) + 200
}));
}
if (this.selectedType !== 'all') {
provinceData = provinceData.filter(item => {
const provinceInfo = this.provinces.find(p => p.name === item.name);
return provinceInfo && provinceInfo.type === this.selectedType;
});
}
const newTotal = provinceData.reduce((sum, item) => sum + item.value, 0);
const maxValue = Math.max(...provinceData.map(item => item.value), 1);
const minValue = Math.min(...provinceData.map(item => item.value));
const newChartData = provinceData.map(item => {
const provinceInfo = this.provinces.find(p => p.name === item.name);
const baseColor = this.getTypeBaseColor(provinceInfo?.type || 'default');
const colorIntensity = maxValue > minValue ?
(item.value - minValue) / (maxValue - minValue) : 0.5;
return {
label: item.name,
shortLabel: provinceInfo?.shortName || item.name,
value: item.value,
percentage: maxValue > 0 ? (item.value / maxValue) * 100 : 0,
baseColor: baseColor,
colorIntensity: colorIntensity,
type: provinceInfo?.type || 'default'
};
});
this.animateChartData(newChartData, newTotal);
},
animateChartData(newChartData, newTotal) {
this.isAnimating = true;
this.animatedChartData = newChartData.map(item => ({
...item,
animatedValue: item.value,
animatedPercentage: item.percentage,
animatedColor: this.generateGradientColor(item.baseColor, item.colorIntensity)
}));
this.animatedTotalMachines = newTotal;
this.chartData = newChartData;
this.totalMachines = newTotal;
setTimeout(() => {
this.isAnimating = false;
}, this.animationDuration);
}
}
};
</script>
<style lang="scss" scoped>
.chart-container {
width: 100%;
position: relative;
}
.loading-state,
.error-state {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
background-color: rgba(255, 255, 255, 0.9);
z-index: 10;
}
.spinner {
width: 40px;
height: 40px;
border: 3px solid #f3f3f3;
border-top: 3px solid #007aff;
border-radius: 50%;
animation: spin 1s linear infinite;
margin-bottom: 10px;
}
@keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
.loading-text {
font-size: 14px;
color: #666;
}
.error-text {
font-size: 14px;
color: #f56c6c;
margin-bottom: 15px;
text-align: center;
padding: 0 20px;
}
.retry-btn {
background-color: #007aff;
color: white;
border: none;
padding: 8px 16px;
border-radius: 4px;
font-size: 14px;
}
.chart-container {
width: 100%;
position: relative;
}
.loading-state,
.error-state {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
background-color: rgba(255, 255, 255, 0.9);
z-index: 10;
}
.spinner {
width: 40px;
height: 40px;
border: 3px solid #f3f3f3;
border-top: 3px solid #007aff;
border-radius: 50%;
animation: spin 1s linear infinite;
margin-bottom: 10px;
}
@keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
.loading-text {
font-size: 14px;
color: #666;
}
.error-text {
font-size: 14px;
color: #f56c6c;
margin-bottom: 15px;
text-align: center;
padding: 0 20px;
}
.retry-btn {
background-color: #007aff;
color: white;
border: none;
padding: 8px 16px;
border-radius: 4px;
font-size: 14px;
}
.container {
min-height: 100vh;
background: linear-gradient(135deg, #f5f7fa 0%, #e4e7ed 100%);
padding-bottom: env(safe-area-inset-bottom);
}
.main-content {
padding: 20rpx;
}
.stats-section {
background: #fff;
border-radius: 16rpx;
padding: 20rpx;
box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.08);
.section-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 30rpx;
}
.section-title {
font-size: 30rpx;
font-weight: 500;
color: #333;
text {
position: relative;
padding-left: 16rpx;
&::before {
content: '';
position: absolute;
left: 0;
top: 50%;
transform: translateY(-50%);
width: 6rpx;
height: 24rpx;
background: linear-gradient(135deg, #52c41a, #389e0d);
border-radius: 3rpx;
}
}
}
}
.total-machine-count {
display: flex;
justify-content: center;
align-items: center;
padding: 10rpx;
background: linear-gradient(135deg, #f0f9ff 0%, #e6f7ff 100%);
border-radius: 12rpx;
margin-bottom: 30rpx;
border: 1rpx solid #e6f7ff;
.total-label {
font-size: 26rpx;
color: #666;
margin-right: 10rpx;
}
.total-value {
font-size: 36rpx;
color: #1890ff;
font-weight: bold;
transition: all 1s cubic-bezier(0.25, 0.46, 0.45, 0.94); /* 使用CSS transition */
}
}
// 竖形图表样式
.chart-container {
margin-bottom: 30rpx;
/* 创建新的图层,减少重排影响 */
transform: translateZ(0);
}
// 横向图表样式 - 优化动画性能
.horizontal-chart {
.horizontal-bars {
display: flex;
flex-direction: column;
gap: 30rpx;
padding: 20rpx 0;
.horizontal-bar-item {
display: flex;
align-items: center;
height: 60rpx;
.bar-label-horizontal {
width: 80rpx;
font-size: 22rpx;
color: #666;
text-align: right;
padding-right: 20rpx;
transition: all 1s ease; /* 添加过渡效果 */
}
.bar-container-horizontal {
flex: 1;
display: flex;
align-items: center;
height: 100%;
background: #f5f5f5;
border-radius: 6rpx;
position: relative;
overflow: hidden; /* 确保动画内容不溢出 */
.bar-fill-horizontal {
height: 100%;
background: linear-gradient(135deg, #4E79A7, #A0CBE8);
display: flex;
align-items: center;
padding-left: 20rpx;
color: white;
font-size: 20rpx;
font-weight: 500;
border-radius: 0 6rpx 6rpx 0;
transform-origin: left;
box-shadow: 2rpx 0 8rpx rgba(0,0,0,0.1);
/* 使用CSS transition替代JS动画 */
transition:
width 1s cubic-bezier(0.25, 0.46, 0.45, 0.94),
background-color 1s cubic-bezier(0.25, 0.46, 0.45, 0.94),
transform 0.3s ease;
/* 启用GPU加速 */
transform: translateZ(0);
backface-visibility: hidden;
perspective: 1000px;
/* 减少重排重绘 */
will-change: transform, width;
}
.bar-value-horizontal {
position: absolute;
right: 20rpx;
font-size: 22rpx;
color: #333;
font-weight: 500;
transition: all 1s cubic-bezier(0.25, 0.46, 0.45, 0.94); /* 使用CSS transition */
/* 启用GPU加速 */
transform: translateZ(0);
backface-visibility: hidden;
}
}
}
}
}
.machine-type-filter {
display: flex;
justify-content: space-around;
margin-top: 30rpx;
padding: 10rpx;
background: #f5f5f5;
border-radius: 20rpx;
.type-tab {
font-size: 24rpx;
color: #666;
padding: 12rpx 20rpx;
border-radius: 16rpx;
transition: all 0.3s;
&.active {
background: #fff;
color: #1890ff;
box-shadow: 0 2rpx 8rpx rgba(24, 144, 255, 0.2);
font-weight: 500;
}
}
}
.time-filter {
.filter-tabs {
display: flex;
background: #f5f5f5;
border-radius: 20rpx;
padding: 6rpx;
}
.filter-tab {
font-size: 24rpx;
color: #666;
padding: 12rpx 20rpx;
border-radius: 16rpx;
transition: all 0.3s;
&.active {
background: #fff;
color: #1890ff;
box-shadow: 0 2rpx 8rpx rgba(24, 144, 255, 0.2);
font-weight: 500;
}
}
}
.safe-area-bottom {
height: env(safe-area-inset-bottom);
}
/* 优化动画关键帧 - 使用transform和opacity实现高性能动画 */
@keyframes barGrowth {
from {
opacity: 0.1;
transform: scaleY(0);
}
to {
opacity: 1;
transform: scaleY(1);
}
}
@keyframes barGrowthHorizontal {
from {
opacity: 0.1;
transform: scaleX(0);
}
to {
opacity: 1;
transform: scaleX(1);
}
}
/* 高性能动画类 */
.bar-fill {
animation: barGrowth 0.5s ease-out;
/* 启用GPU加速 */
transform: translateZ(0);
backface-visibility: hidden;
perspective: 1000px;
/* 减少重排重绘 */
will-change: transform, height;
}
.bar-fill-horizontal {
animation: barGrowthHorizontal 0.5s ease-out;
/* 启用GPU加速 */
transform: translateZ(0);
backface-visibility: hidden;
perspective: 1000px;
/* 减少重排重绘 */
will-change: transform, width;
}
/* 添加高性能过渡类 */
.smooth-transition {
transition: all 1s cubic-bezier(0.25, 0.46, 0.45, 0.94);
}
/* 优化渲染性能 */
.optimized-render {
/* 创建独立的合成层 */
transform: translateZ(0);
/* 避免重绘 */
will-change: transform, opacity;
/* 优化动画性能 */
backface-visibility: hidden;
perspective: 1000px;
}
</style>
开发版可以显示 正式版不行吗?