У меня есть одностраничное приложение для отображения информации датчиков со всего дома. У меня есть компонент, который отображает датчик, использующий библиотеку highcharts. В зависимости от отображаемой информации существует разное количество датчиков для разных помещений. У меня есть параметры для отображения датчиков (max, min, форматирование и т.д. c), хранящихся в массиве состояний 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>
* 1007 console.log там, чтобы проверить идентификатор - я думаю, здесь возникает проблема. Он обновляется только тогда, когда я go со страницы с одним уровнемером до трех (добавляет еще два идентификатора). Есть ли способ уничтожить компонент датчика, когда я покидаю эту часть маршрута?
и теперь родительский компонент, который вызывает компонент датчика:
<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>