Vue组件中的SVG属性stroke-dasharray

时间:2018-08-14 18:41:08

标签: svg vue.js

帮助我将此元素表示为vue组件,其中 .circle-chart-percent文本(用户定义的值)== .circle-chart-circle stroke-dasharray。

<svg class="circle-chart" viewbox="0 0 33.83098862 33.83098862" width="200" height="200" xmlns="http://www.w3.org/2000/svg">
    <circle class="circle-chart-background" stroke="#cccccc" stroke-width="0.35" stroke-dasharray="100" fill="none" cx="16.91549431" cy="16.91549431" r="15.91549431" />
    <circle class="circle-chart-circle" stroke="#4f5357" stroke-width="0.5" stroke-dasharray="90" stroke-linecap="round" fill="none" cx="16.91549431" cy="16.91549431" r="15.91549431" />
    <g class="circle-chart-info">
        <text class="circle-chart-percent" x="16.91549431" y="15.5" alignment-baseline="central" text-anchor="middle" font-size="8">30%</text>
        <text class="circle-chart-subline" x="16.91549431" y="20.5" alignment-baseline="central" text-anchor="middle" font-size="2">name</text>
    </g>
</svg>

<script>
var svg = document.querySelector('.circle-chart-circle');
    att = svg.getAttribute('stroke-dasharray');
    text = document.querySelector('text.circle-chart-percent');

if (att === '100') { 
    text.textContent = 'full'; 
}
else {
    text.textContent = att + '%';
} 
</script>

<style>
.circle-chart-circle {
  animation: circle-chart-fill 2s reverse;
  transform: rotate(-90deg);
  transform-origin: center;
}
.circle-chart-info {
  animation: circle-chart-appear 2s forwards;
  opacity: 0;
  transform: translateY(0.3em);
}
@keyframes circle-chart-fill {
   to { 
      stroke-dasharray: 0 100; 
   }
}
@keyframes circle-chart-appear { 
   to {                                      
      opacity: 1;                            
      transform: translateY(0);           
   }
 }
</style>

https://codepen.io/pershay/pen/gjyKme

1 个答案:

答案 0 :(得分:0)

遵循Vue Guide: style-binding,那么您将轻松达到目标。

下面是一个简单的演示:

  1. 绑定:stroke-dasharray="progress"

  2. 创建一个计算所得的property = computedText以返回进度说明(在您的代码中为text.textContent = 'full'; or att+'%'

Vue.component('svg-circle', {
  template: `<svg class="circle-chart" viewBox="0 0 33.83098862 33.83098862" width="200" height="200" xmlns="http://www.w3.org/2000/svg">
  
    <circle class="circle-chart-background" stroke="#cccccc" stroke-width="0.35" stroke-dasharray="100" fill="none" cx="16.91549431" cy="16.91549431" r="15.91549431" />
    <circle class="circle-chart-circle" stroke="#4f5357" stroke-width="0.5" :stroke-dasharray="progress" stroke-linecap="round" fill="none" cx="16.91549431" cy="16.91549431" r="15.91549431" />
    <g class="circle-chart-info">
        <text class="circle-chart-percent" x="16.91549431" y="15.5" alignment-baseline="central" text-anchor="middle" font-size="8">{{computedText}}</text>
        <text class="circle-chart-subline" x="16.91549431" y="20.5" alignment-baseline="central" text-anchor="middle" font-size="2">name</text>
    </g>
</svg>
             `,
  props: ['progress'],
  computed: {
    computedText: function () {
      let description = ''
      let progress = this.progress < 0 ? 0 : (this.progress > 100 ? 100 : this.progress)
      if (progress === '100') { 
          description = 'full'; 
      }
      else {
          description = progress + '%';
      } 
      return description
    }
  }
})

new Vue({
  el: '#app',
  data() {
    return {
      progress: 10
    }
  },
  methods:{
    changeProgress: function () {
      this.progress += 10
    }
  }
})
.circle-chart-circle {
  animation: circle-chart-fill 2s reverse;
  transform: rotate(-90deg);
  transform-origin: center;
}
.circle-chart-info {
  animation: circle-chart-appear 2s forwards;
  opacity: 0;
  transform: translateY(0.3em);
}
@keyframes circle-chart-fill {
  to { stroke-dasharray: 0 100; 
  }
}                                 @keyframes circle-chart-appear { 
  to {                                      opacity: 1;                            transform: translateY(0);           }
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.16/vue.js"></script>
<div id="app">
  <button v-on:click="changeProgress()">Change Progress - {{progress}}</button>
  <div>
  <svg-circle :progress="progress">
  </svg-circle>
  </div>
</div>