-
创建Gmeek组件类VoteBar,定义模板和方法。
-
在init方法中加载配置,获取数据,设置响应式数据。
-
使用Gmeek的模板语法或渲染函数来生成HTML。
-
处理动态更新,可能使用定时器或框架的响应式系统。
-
样式处理,确保样式隔离,可能使用框架的样式解决方案。
-
在config.json中定义可配置参数,如容器选择器、数据源、颜色等。
// vote.js
Gmeek.component('vote-bar', {
template:<div class="gmeek-vote-container"> <div class="vote-item" v-for="(item, index) in processedData" :key="index"> <div class="vote-label"> <span>{{ item.label }}</span> <span v-if="config.showNumbers"> {{ item.value }} ({{ item.percentage.toFixed(1) }}%) </span> </div> <div class="vote-bar"> <div class="vote-fill" :style="{ width: item.percentage + '%', backgroundColor: config.colors[index % config.colors.length] }"> </div> </div> </div> </div>,
config: {
container: '#voteContainer',
dataUrl: './data.json',
colors: ['#FF6B6B', '#4ECDC4', '#45B7D1'],
barHeight: '28px',
showNumbers: true,
refreshInterval: 5000
},
init() {
this.processedData = []
this.total = 0
this.setupStyles()
this.startPolling()
},
async mounted() {
await this.loadData()
},
methods: {
async loadData() {
try {
const response = await Gmeek.http.get(this.config.dataUrl)
this.calculatePercentages(response.data)
} catch (error) {
console.error('[Gmeek Vote] Data load failed:', error)
}
},
calculatePercentages(rawData) {
this.total = rawData.reduce((sum, item) => sum + item.value, 0)
this.processedData = rawData.map(item => ({
...item,
percentage: this.total > 0 ? (item.value / this.total) * 100 : 0
}))
},
setupStyles() {
const styles = `
.gmeek-vote-container {
width: 100%;
max-width: 800px;
margin: 20px auto;
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto;
}
.vote-item {
margin: 18px 0;
}
.vote-label {
display: flex;
justify-content: space-between;
margin-bottom: 8px;
font-size: 14px;
color: #666;
}
.vote-bar {
background-color: #f8f9fa;
height: ${this.config.barHeight};
border-radius: 12px;
overflow: hidden;
box-shadow: inset 0 1px 2px rgba(0,0,0,0.05);
}
.vote-fill {
height: 100%;
transition: width 0.6s cubic-bezier(0.22, 0.61, 0.36, 1);
position: relative;
}
.vote-fill::after {
content: "";
position: absolute;
right: 0;
top: 0;
bottom: 0;
width: 4px;
background: linear-gradient(90deg,
rgba(255,255,255,0.3) 0%,
rgba(255,255,255,0.15) 100%);
}
`
Gmeek.style.inject('gmeek-vote-styles', styles)
},
startPolling() {
if (this.config.refreshInterval > 0) {
this.polling = setInterval(() => {
this.loadData()
}, this.config.refreshInterval)
}
}
},
beforeUnmount() {
clearInterval(this.polling)
Gmeek.style.remove('gmeek-vote-styles')
}
})
// config.json
{
"voteConfig": {
"container": "#mainVoteContainer",
"dataUrl": "/api/vote-data",
"colors": ["#FF6B6B", "#4ECDC4", "#45B7D1", "#96CEB4"],
"barHeight": "32px",
"showNumbers": true,
"refreshInterval": 10000,
"animation": {
"duration": 0.6,
"easing": "cubic-bezier(0.22, 0.61, 0.36, 1)"
},
"responsive": {
"mobileBreakpoint": 768,
"mobileBarHeight": "24px"
}
}
}
#使用Gmeek组件系统注册组件
支持Gmeek生命周期钩子(mounted/beforeUnmount)
集成Gmeek样式管理系统
使用Gmeek HTTP客户端进行数据请求