【发布时间】:2020-11-02 16:05:09
【问题描述】:
我有一个单页应用程序来显示房子周围的传感器信息。我有一个组件可以呈现使用 highcharts 库的仪表。根据显示的信息,不同房间有不同数量的仪表。我有显示存储在 vuex 状态数组中的仪表(最大值、最小值、格式等)的选项。房间在我的应用程序中都是不同的路线,在导航栏中都有自己的链接。
如果我点击第一个房间(比如办公室),则会呈现三个仪表 - 都很好。但是,如果我现在单击车库(只有一个仪表),那么第一个仪表的选项不会与办公室之前的显示有所不同。就好像组件被保存在内存中并且其设置没有更新。
这是帮助我解释的代码,首先是仪表组件:
<template>
<div :ref="'gauge-'+_uid" class="border gauge-container"></div>
</template>
<script>
module.exports = {
props: {
'gValue': {type: Number, default: 20},
'gMin': {type: Number, default: 0},
'gMax': {type: Number, default: 100},
'gUnits': {type: String, default: ""},
},
data: function () {
return {
// Data for chart
chart: null,
gaugeOptions: {
chart: {
type: 'solidgauge'
},
title: null,
pane: {
size: 200,
center: ['50%', '75%'],
startAngle: -90,
endAngle: 90,
background: {
backgroundColor:
Highcharts.defaultOptions.legend.backgroundColor || '#EEE',
innerRadius: '60%',
outerRadius: '100%',
shape: 'arc'
}
},
tooltip: {
enabled: false
},
// the value axis
yAxis: {
stops: [
[0.1, '#55BF3B'], // green
[0.5, '#DDDF0D'], // yellow
[0.9, '#DF5353'] // red
],
lineWidth: 0,
tickWidth: 0,
minorTickInterval: null,
tickAmount: 0,
title: {
y: -70
},
labels: {
y: 16
},
min: this.gMin,
max: this.gMax,
title: null,
},
plotOptions: {
solidgauge: {
dataLabels: {
y: 5,
borderWidth: 0,
useHTML: true
}
}
},
credits: {
enabled: false
},
series: [{
data: [this.gValue],
dataLabels: {
format:
'<div style="text-align:center">' +
'<span style="font-size:14px">{y} ' + this.gUnits + '</span>' +
'</div>'
},
}],
}
}
},
mounted: function () {
console.log(this._uid) // Look at the id that is generated -- this is not being updated!
Highcharts.setOptions(
{
chart: {
style: {
fontFamily: 'roboto'
}
}
}
)
this.chart = Highcharts.chart(
this.$refs['gauge-' + this._uid],
this.gaugeOptions
)
},
watch: {
gValue: function (val) {
this.chart.series[0].points[0].update(val)
},
}
}
</script>
<style scoped>
.gauge-container {
max-width: 250px;
height: 180px;
}
</style>
我已经在其中放置了一个 console.log 来检查 id - 我认为这就是问题所在。只有当我从一个仪表的页面变为三个时它才会更新(它添加了另外两个 id)。当我离开那部分路线时,有没有办法破坏仪表组件?
现在是调用仪表组件的父组件:
<template>
<div v-if="hasRooms" id="room">
<b-container>
<h2>{{ roomName }}</h2>
<b-row align-h="center">
<b-col sm="3" class="text-center p-0 ml-1 mr-1" v-for="device in deviceList" v-bind:key="deviceList.name">
<p>{{ device.name }} - {{ device.function }}</p>
<highchart v-if="device.format == 'default'" :g-value="device.value">
<template v-slot:title>
{{ device.function | capitalize }}
</template>
</highchart>
<highchart v-else
v-bind:g-value="device.value"
v-bind:g-min="device.format.min"
v-bind:g-max="device.format.max"
v-bind:g-units="device.format.units"
>
<template v-slot:title>
{{ device.function | capitalize }}
</template>
</highchart>
</b-col>
</b-row>
</b-container>
</div>
</template>
<script>
module.exports = {
name: 'room',
/** Load external component files
* Make sure there is no leading / in the name
* To load from the common folder use like: 'common/component-name.vue' */
components: {
'highchart': httpVueLoader('components/HighCharts.vue'),
}, // --- End of components --- //
data() {
return {
};
},
computed: {
hasRooms() {
return this.$store.getters['rooms/nRooms'] > 0;
},
roomName() {
return this.$store.getters['rooms/getRoomById'](this.$route.params.roomId);
},
deviceList() {
return this.$store.getters['rooms/getDevicesinRoom'](this.$route.params.roomId);
},
},
filters: {
capitalize: function (value) {
if (!value) return ''
value = value.toString()
return value.charAt(0).toUpperCase() + value.slice(1)
},
tonumber: function (value){
if (!value) return ''
return parseFloat(value)
}
},
}
</script>
房间由路由器生成并从以下位置渲染:
<template>
<div id="rooms">
<b-alert variant="info" :show="!hasRooms">
<p>
There are no rooms available yet. Pass a message that defines a room id and device id
to the uibuilder node first. See <router-link :to="{name: 'usage_info'}">the setup information</router-link>
for instructions on how start using the interface.
</p>
</b-alert>
<router-view></router-view>
</div>
</template>
<script>
module.exports = {
name: 'RoomsOverview',
data() {
return {
};
},
computed: {
hasRooms() {
return this.$store.getters['rooms/nRooms'] > 0;
},
roomList() {
return this.$store.getters['rooms/getAllRooms'];
},
},
}
</script>
【问题讨论】:
-
你不应该使用
_uidgithub.com/vuejs/vue/issues/5886。 -
使用动态引用的原因是什么?
-
嗨,谢谢。由于页面上有多个组件,我认为我需要一个唯一的 id 来渲染仪表(我使用的是静态 id,只会出现一个仪表)。有更好的方法吗?我需要一个 id 来在模板中生成图表。
-
more than one component on a page无论如何,静态引用应该没问题,只要确保该组件中只有一个(实际上多个也可以,你会得到一个数组)。
标签: vue.js vue-component