[英]how to fix timing of result for getTotalLength() of svg in vuejs?
this.$refs.pathID.getTotalLength()
returns 0
when it should return the length, and returns the legnth when it should return 0
. this.$refs.pathID.getTotalLength()
在应该返回长度时返回0
,在应该返回0
时返回长度。
my vue component is a svg path element, there is a button to toggle the path.我的 vue 组件是一个 svg 路径元素,有一个按钮可以切换路径。 the toggle is accomplished via binding the
d
atttribute of the path to a property called path
.切换是通过将路径的
d
属性绑定到名为path
的属性来完成的。 there is a function that runs on mount
that generates the value for the d
attribute, ive set this value to a property called pathValue
.有一个在
mount
上运行的函数,它为d
属性生成值,我将此值设置为一个名为pathValue
的属性。 so, if clicked == true
then path = pathValue
, else path = null
.所以,如果
clicked == true
那么path = pathValue
,否则path = null
。 this works as expected.这按预期工作。
further i watch
path
so that when there is a change, (onclick) then the path length should be recalculated, and its value set to a css custom variable.我进一步
watch
path
,以便在发生更改时(onclick),然后应重新计算路径长度,并将其值设置为 css 自定义变量。
<template>
<main>
<svg viewBox="0 0 415 200">
<path ref="pathID" :d=path />
</svg>
<button @click="show()">nsr</button>
</main>
</template>
<script>
export default {
data() {
return {
path: null,
clicked: true,
pathValue: null,
pathLength: 0
}
},
methods: {
show() {
if(this.clicked) {
this.path = this.pathValue
this.clicked = !this.clicked
} else {
this.path = null
this.clicked = !this.clicked
}
},
generatePath() {
// generates a string value for the d-attribute were binding to path
let path = "M410 100,"
for(let i = 0; i < 5; i++) {
path += `
h-10,
q-5 -20, -10 0,
h-10,
s-5 -100, -10 -0,
s-5 50, -10 0,
h-10,
q-10 -20, -20 0,
h-5`
}
return path
}
},
mounted() {
this.pathValue = this.generatePath()
},
watch: {
path: function() {
// trigger computed setter here when path is changed onclick
this.calculatePathLength = this.$refs.pathID
},
pathLength: function() {
// set custom variable here
this.$refs.pathID.style.setProperty("--path-length", this.calculatePathLength)
console.log('value of computed property: ' + this.calculatePathLength)
}
},
computed: {
calculatePathLength: {
get: function() {
return this.pathLength
},
set: function(x) {
this.pathLength = x.getTotalLength()
console.log('path length is: ' + this.pathLength)
}
}
}
}
</script>
so when the button is clicked, the value of the d-attribute
should be updated, the watcher should notes the change in path
and the setter of the computed property calculatePathLength
is called, updates the value of pathLength
, then the watcher
for pathLength should call the getter in setting the custom property var(--path-length)
.因此,当单击按钮时,应更新
d-attribute
的值,观察者应注意path
的变化,并调用计算属性calculatePathLength
的设置器,更新pathLength
的watcher
应调用设置自定义属性var(--path-length)
的吸气剂。
so the expected result should be that pathLength should be logged, it is.所以预期的结果应该是应该记录 pathLength,它是。 but when it should be non-zero it is zero, and when it should be zero it is non-zero
但是当它应该是非零时它是零,当它应该是零时它是非零
When you change this.path
you need to give time for the svg element to redraw before the new getTotalLength()
can be calculated.当您更改
this.path
时,您需要给 svg 元素重新绘制的时间,然后才能计算新的getTotalLength()
。
Vue provides the this.$nextTick()
function exactly for this purpose. Vue 正是为此目的提供了
this.$nextTick()
函数。 To make your code above work:要使您的代码在上面工作:
watch: {
path: function() {
// trigger computed setter here when path is changed onclick
this.$nextTick(()=>this.calculatePathLength = this.$refs.pathID);
},
...
this question was answered on the vue forum here , the explanation is that the svg is not given enough time to update before measure the path length, and this is the purpose of the vue.$nextTick()
.这个问题在这里的 vue 论坛上得到了回答,解释是在测量路径长度之前没有给 svg 足够的时间来更新,这就是
vue.$nextTick()
的目的。 here is the code that fixes the above situation:这是解决上述情况的代码:
watch: {
path() {
this.$nextTick(() => this.pathLength = this.$refs.pathID.getTotalLength());
}
},
thank you @wildhart谢谢@wildhart
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.