如何在vuejs中修复svg的getTotalLength()结果的时间安排?

时间:2019-02-15 19:57:24

标签: svg vue.js

this.$refs.pathID.getTotalLength()在应返回长度时返回0,并在应返回0时返回整数。

我的vue组件是svg路径元素,有一个按钮可以切换路径。切换是通过将路径的d属性绑定到名为path的属性来完成的。有一个在mount上运行的函数为d属性生成值,将该值设置为名为pathValue的属性。因此,如果clicked == true,则path = pathValue,否则path = null。这按预期工作。

我进一步watch path,以便在发生更改时(单击),应重新计算路径长度,并将其值设置为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>

因此,当单击按钮时,d-attribute的值应更新,观察者应注意path中的更改,并调用计算属性calculatePathLength的设置方法,更新pathLength的值,然后pathLength的watcher应该在设置自定义属性var(--path-length)时调用getter。

,因此预期结果应该是应该记录pathLength。但是当它应该为非零时为零,而当它应该为零时则为非零

2 个答案:

答案 0 :(得分:1)

更改this.path时,需要等待一段时间才能重新绘制svg元素,然后才能计算出新的getTotalLength()

Vue为此提供了this.$nextTick()函数。为了使您的代码能够正常工作:

watch: {
    path: function() {
        // trigger computed setter here when path is changed onclick
        this.$nextTick(()=>this.calculatePathLength = this.$refs.pathID);
    },
    ...

答案 1 :(得分:0)

这个问题在vue论坛here上得到了回答,原因是svg在测量路径长度之前没有足够的时间进行更新,这就是vue.$nextTick()的目的。这是解决上述情况的代码:

    watch: {

      path() {
        this.$nextTick(() => this.pathLength = this.$refs.pathID.getTotalLength());
      }
    },

谢谢@wildhart