Vue 计算属性函数永远不会被调用
Posted
技术标签:
【中文标题】Vue 计算属性函数永远不会被调用【英文标题】:Vue computed property functions are never called 【发布时间】:2020-11-22 12:05:55 【问题描述】:我尝试做自己的Google Science Journal,但是使用 MQTT 协议的 web 版本,但是我的代码有很多错误。
关于我的代码的一些说明:
google.charts.load
在父组件中调用,然后回调调用子组件
time
props 是一个区间,每秒在true
和false
之间切换以收集数据。
我需要观察具有多个依赖关系的数据的变化。
我的代码是如何工作的?
-
创建新实例时,会出现一个空的谷歌图表
图表开始每秒显示一次数据。
选择了新选项卡时图表更改了图表更改,并且图表数据被删除。
这段代码有问题,是函数调用的顺序(用google chart产生一些问题),但我修复了它,将函数从计算移动到方法并按顺序调用。
我只是想知道为什么这个计算函数不起作用,我的意思是,它们不是从不调用的。
<template>
<v-card>
<v-tabs
v-model="active_tab"
background-color="red lighten-2"
dark
show-arrows
>
<v-tab
v-for="(n) in tabs"
:key="n.id"
>
n.text
<v-icon>n.icon</v-icon>
</v-tab>
</v-tabs>
<div ref="char_div"></div>
</v-card>
</template>
<script>
import debounce from 'debounce'
export default
name: 'charts',
props:
time:
type: Boolean,
default: false
,
data()
return
chart: null,
options: null,
value: 0,
previus: null,
data: null,
tabs: [
id: 0, text: "Aceleración lineal", unit: "(m/s²)", icon: "",
id: 1, text: "Aceleración en x", unit: "(m/s²)", icon: "",
id: 2, text: "Aceleración en y", unit: "(m/s²)", icon: "",
id: 3, text: "Aceleración en z", unit: "(m/s²)", icon: "",
id: 4, text: "Velocidad lineal", unit: "(m/s)", icon: "",
id: 5, text: "Luz ambiental", unit: "(lux)", icon: "",
id: 6, text: "Intensidad sonora", unit: "(dB)", icon: "",
id: 7, text: "Tono", unit: "(Hz)", icon: "",
id: 8, text: "Barómetro", unit: "(hPa)", icon: "",
id: 9, text: "Brujula", unit: "grados", icon: "",
id: 10, text: "Magnetómetro", unit: "µT", icon: "",
id: 11, text: "Humedad", unit: "%", icon: "",
id: 12, text: "Temperatura ambiente", unit: "°C", icon: ""
],
active_tab: 0
,
computed:
newData: function()
switch (this.active_tab)
case 0:
this.value = Math.sqrt(this.$state.lin_acel.x^2 + this.$state.lin_acel.y^2 + this.$state.lin_acel.z^2)
break
case 1:
this.value = this.$state.lin_acel.x
break
case 2:
this.value = this.$state.lin_acel.y
break
case 3:
this.value = this.$state.lin_acel.z
break
case 4:
if (this.previus != null)
//var cons = Math.sqrt(this.$state.lin_acel.x^2 + this.$state.lin_acel.y^2 + this.$state.lin_acel.z^2)
var ax = this.$state.lin_acel.x,
ay = this.$state.lin_acel.y,
az = this.$state.lin_acel.z
var nuevo = Date.now()
var vx = ax * ((nuevo - this.previus)/1000),
vy = ay * ((nuevo - this.previus)/1000),
vz = az * ((nuevo - this.previus)/1000)
//this.value += (cons)*((nuevo - this.previus)/1000)
this.value += Math.sqrt(vx^2 + vy^2 + vz^2)
this.previus = nuevo
else
this.value = Math.sqrt(this.$state.lin_acel.x^2 + this.$state.lin_acel.y^2 + this.$state.lin_acel.z^2)
this.previus = Date.now()
case 5:
this.value = this.$state.lux
break
case 6:
this.value = this.$state.noise
break
case 7:
this.value = this.$state.noise
break
case 8:
this.value = this.$state.presion
break
case 9:
var vector = Math.sqrt(this.$state.magneto.x^2 + this.$state.magneto.y^2 + this.$state.magneto.z^2)
break
case 10:
this.value = Math.sqrt(this.$state.magneto.x^2 + this.$state.magneto.y^2 + this.$state.magneto.z^2)
break
default:
this.value = 0
break
,
newOptions()
console.log("new options")
this.options =
tittle: this.tabs[this.active_tab].text,
crosshair: orientation: 'vertical', trigger: 'both',
legend: 'none',
hAxis:
format:'mm:ss'
,
drawchart()
console.log("chart is drawing")
this.chart.draw(this.data, google.charts.Line.convertOptions(this.options));
,
,
watch:
time:
immediate: false,
handler()
this.addData()
,
active_tab:
inmediate: false,
handler()
this.updatetable()
,
methods:
addData()
this.data.addRows([[new Date(Date.now()),0]])
,
updatetable()
this.data = null
this.data = new google.visualization.DataTable(
cols:
[label: 'tiempo', id: 'x', type: 'date',
label: String(this.tabs[this.active_tab].text), id: 'y', type: 'number'])
,
mounted()
this.chart = new google.charts.Line(this.$refs.char_div)
this.newOptions
this.updatetable()
this.drawchart
</script>
<style>
</style>
【问题讨论】:
计算属性函数并不意味着改变任何data
属性,而是应该return
一个值。建议你仔细阅读文档~vuejs.org/v2/guide/computed.html#Computed-Properties
@Phil 谢谢,我再次阅读了这个文档一百万次,但他们从未指定计算需要返回一个值或不用于更改 data
,此外,我需要观看多个data
的依赖关系,这对于 vue2 中的 watch
属性是不可能的。例如,从加速度计观察 x、y、z 轴的变化并重新评估向量。
您是否在渲染中引用了您的计算数据?是的,计算属性就像一个数据字段,它需要有一个值返回。
【参考方案1】:
正如Phil 所说,“计算属性函数并不意味着改变任何data
属性,而是应该return
一个值”。是因为计算的 watch 只作为回报而改变,例如:
//Computed watch this
return this.a + this.b
//...
//Not this
this.c = this.a + this.b
我在这里和 Vue 论坛中找到了改进此代码的方法: 如果您需要观察具有多个依赖关系的数据,您可以执行以下操作:
computed:
multi()
return [this.a, this.b].join()
,
watch:
multi:
handler():
this.c = this.a + this.b
我能找到的最好的解决方案是:
created()
this.$watch(
(this) => (vm.x, vm.y, vm.z, Date.now()),
function ()
// Executes if `x`, `y`, or `z` have changed.
)
这最后还返回函数unwatch()
,它停止观察者属性,如果我做this.watcher = this.$watch(/*data and callback here*/)
,那么我可以做this.watcher()
停止观察者并新建一个,非常适合提高这段代码的性能。
【讨论】:
以上是关于Vue 计算属性函数永远不会被调用的主要内容,如果未能解决你的问题,请参考以下文章