javascript - 为什么 get 属性的工作方式与 Vue 中的函数不同,看起来我必须使用函数而不是 getter 一些未知的幕后原因
问题描述
这会返回错误的值
get scrollTop() {
return window.pageYOffset || document.documentElement.scrollTop
}
但是这个
scrollTop() {
return window.pageYOffset || document.documentElement.scrollTop
}
按预期工作,这是 Vue 或 typescript 或其 javascript 中的一些隐藏的宝石吗?当我不知何故无法解释为什么有时它们不起作用时,我不知道现在如何依赖语法更易读的属性,从而导致我的开发速度变慢,因此始终使用函数更可靠。我可以期待更多这样的情况吗?
<template>
<div :style="computedStyle" class="tooltip">
<div ref="tooltip-background" v-html="svg" class="tooltip-background"/>
<div class="tooltip-content">
<div v-if="nearestItem" class="tooltip-content-values">
<span class="">{{getChartTitle(nearestItem)}}: </span>
<span class="tooltip-content-values-value">{{nearestItem.value}}</span>
</div>
<div class="tooltip-content-date">{{date}}</div>
</div>
</div>
</template>
<style scoped>
.tooltip {
pointer-events: none;
position: absolute;
width: 300px;
}
.tooltip-background {
width: 300px;
position: absolute;
z-index: 1
}
.tooltip-content {
position: absolute;
z-index: 2;
margin-left: 25px;
margin-top: 3px;
padding: 15px;
}
.tooltip-content-values {
margin-top: 2px;
font-family: Work Sans, sans-serif;
font-style: normal;
font-weight: normal;
font-size: 16px;
line-height: 20px;
color: #666666;
}
.tooltip-content-values-value {
font-family: Work Sans, sans-serif;
font-style: normal;
font-weight: normal;
font-size: 16px;
line-height: 20px;
color: #111111;
}
.tooltip-content-date {
margin-top: 3px;
font-family: Work Sans, sans-serif;
font-style: normal;
font-weight: 500;
font-size: 12px;
line-height: 24px;
color: #666666;
opacity: 0.5;
}
</style>
<script lang="ts">
import {Component, Vue} from "vue-property-decorator"
import {BMChartData, BMChartTooltipType, ChartTooltipModel} from "@/components/charts/ChartTypes";
import Chart, {ChartTooltipItem} from "chart.js";
import {is, log, stringify} from "@/extensions/CSLang";
import {CSPoint} from "@/extensions/CSPoint";
@Component
export default class BMChartTooltip extends Vue implements BMChartTooltipType {
chart: Vue | null = null
model: ChartTooltipModel | null = null
data: BMChartData | null = null
lastHover: MouseEvent | null = null
svg = require(`@/assets/img/icons/tooltip-background.svg`)
date: String = "12.Jul, Tuesday, 19:10"
nearestItem: ChartTooltipItem | null = null
get tooltipBackground() {
return this.$refs["tooltip-background"] as HTMLDivElement
}
get computedStyle() {
return {
left: this.tooltipLeft,
top: this.tooltipTop,
visibility: this.nearestItem ? "visible" : "hidden"
}
}
get tooltipLeft() {
if (this.nearestItem) return (this.scrollLeft() + this.chartRect().left + this.nearestItem.x! + 10) + "px"
return `0px`
}
get tooltipTop() {
if (this.nearestItem) return (this.scrollTop() + this.chartRect().top + this.nearestItem.y! - 42) + "px"
return `0px`
}
scrollLeft() { //Cannot be getter because then returns wrong value !!!
return window.pageXOffset || document.documentElement.scrollLeft
}
scrollTop() { //Cannot be getter because then returns wrong value !!!
return window.pageYOffset || document.documentElement.scrollTop
}
chartRect() {
return this.chart!.$el.getBoundingClientRect()
}
get items(): ChartTooltipItem[] {
let items = Array<ChartTooltipItem>()
if (this.model && this.model.dataPoints)
for (let item of this.model.dataPoints)
if (item.x == this.model.caretX) items.push(item)
return items
}
borderColor(value: string) {
for (let element of this.tooltipBackground.children[0].getElementsByTagName("path"))
element.setAttribute("fill", value)
}
onUpdate(chart: Vue, model: ChartTooltipModel, data: BMChartData): void {
if (model && model.dataPoints && model.dataPoints!.length > 0) {
this.chart = chart
this.model = model
this.data = data
this.updateNearestItem()
}
}
onHover(event: MouseEvent, activeElements: Array<{}>) {
this.lastHover = event
this.updateNearestItem()
if (this.nearestItem) {
let lineColor = this.data!.charts[this.nearestItem.datasetIndex!].lineColor
this.borderColor(lineColor)
this.date = this.nearestItem.label ? this.nearestItem.label : ""
}
}
updateNearestItem() {
let nearestDistance = Number.MAX_SAFE_INTEGER
this.nearestItem = null
for (let item of this.items) {
let distance = new CSPoint(item.x! + this.chartRect().left, item.y! + this.chartRect().top)
.distance(CSPoint.fromEvent(this.lastHover!))
if (distance < nearestDistance) {
nearestDistance = distance
this.nearestItem = item
}
}
}
getChartTitle(item: ChartTooltipItem): string {
return this.data ? this.data.charts[item.datasetIndex!].title : ""
}
}
</script>
如您所见,必须将三个方法定义为函数而不是属性 scrollLeft scrollTop 和 chartRect 否则我会得到错误的值...看起来它们是从某种不同的上下文中以某种方式调用的,所以所有从文档 dom 元素中获取的值可能有这种行为的线索。
解决方案
推荐阅读
- r - 将数字字段存储在具有正确小数位的数据文件中
- postgresql - Postgres SQL 查询,它将对嵌套 JSON 对象中的字段进行分组
- javascript - 如何更改 json 响应中的数据
- powershell - 使用 powershell 安装软件
- python - 使用标准缩放器的数据转换警告。Int 转换为 float64,但没有整数
- r - Stargazer 中的指数 CI
- docker - tf_serving docker中的“direct_session_runs”和“graph_runs”有什么区别
- javascript - Facebook Feed 对话框 URL 图片参数未覆盖 og:image
- ios - 如何从主类访问自定义集合视图单元类中的文本视图
- java - 使用 Angular 7 从 Tomcat 错误页面获取错误消息