2017-11-18 5 views
0

필드가 여러 개인 테이블 행이있는 구성 요소가 있습니다. 한 필드를 업데이트하면 여백이나 판매 가격을 기준으로 다른 필드가 업데이트됩니다.VueJs Watchers를 동적으로 관리하기

그러나 모든 분야를 지켜보고있는 중 나는 튀는 효과를 얻고 있습니다. _debounce를 추가하면 문제가 해결되지만 도움이되지는 않습니다. 시도하고 문제를 관리하기 위해 unwatch() 트리거하려면 감시자에게 콜백을 사용하고 있지만 내가 다시 관찰자를 추가 할 때 콜백 멈추지 않는 중지합니다.

나는 코드의 예로 요점을 지었다.

Vue.component('pricing', { 

    template: '#pricing-row', 

    props: ['item'], 

    mounted() { 
    this.addWatchers() 
    }, 

    methods: { 

     resetWatchers() { 
     setTimeout(()=> { 
      this.addWatchers() 
     }, 700) 
    }, 

    addWatchers() { 

     this.updateNet = this.$watch(
     function() { 
      return this.item.net 
     }, 
     function() { 
      // unmount other watchers 
      this.updateMargin() 
      this.updateSell() 
      // calculate sell price and update 
      this.setSellPrice() 
      // re-add watchers 
      this.resetWatchers() 
     } 
    ), 

     this.updateMargin = this.$watch(
     function() { 
      return this.item.margin 
     }, 
     function() { 
      // unmount other watchers which can cause bounce effect 
      this.updateSell() 
      // calculate sell price and update 
      this.setSellPrice() 
      // re-add watchers 
      this.resetWatchers() 
     } 
    ), 

     this.updateSell = this.$watch(
     function() { 
      return this.item.sell 
     }, 
     function(sellPrice) { 
      // unmount other watchers which can cause bounce effect 
      this.updateMargin() 
      // update margin 
      this.setMargin(sellPrice) 
      // re-add watchers 
      this.resetWatchers() 
     } 
    ) 
    }, 

    setSellPrice() { 
     let price = (100/(100 - this.item.margin)) * this.item.net 
     this.item.sell = price.toFixed(2) 
    }, 

    setMargin(sellPrice) { 
     let profit = (sellPrice - this.item.net) 
     let price = (100 * profit)/sellPrice 
     this.item.margin = price.toFixed(2) 
    } 
    } 

}) 

new Vue({ 
    el: '#vue', 
    data: { 
    prices: [ 
     { 
     id: 1, 
     net: 5, 
     margin: 10, 
     sell: 5.56 
     }, 
     { 
     id: 2, 
     net: 7, 
     margin: 10, 
     sell: 7.78 
     },  
    ] 
    } 
}) 

view example gist

은 내가 메소드를 호출 mounted()에 그들을 장착하여 올바르게 전문가를 사용하고 생각합니다. 그리고 그 방법을 리콜하여 다시 초기화합니까?

정말 도움이되기를 바랍니다.

+0

이 매우 불행한 솔루션을 것을 볼 수 있습니다. 'net','margin'과'sell' 속성 사이의 관계 만 설명해 주시겠습니까? – WaldemarIce

+0

기본적으로 판매 가격을 업데이트하면 그물 및 마진을 기준으로 판매 가격이 자동으로 다시 계산됩니다. 다른 필드와 동일합니다. – Lee

+0

이것은 무한 루프입니다. 지금 나는 문제가 어디 있는지 이해하고있다. 가장 단순한 솔루션은'sell' 속성을 원가로 고려하고있다. 직접 사용할 수 없다. 실제 판매 가격은 그물, 마진 및 원가를 기반으로 계산 된 속성을 사용해야한다. – WaldemarIce

답변

0

여기서 계산 된 값을 통하여 추출된다 (순 마진 판매) 계산 값

각 파라미터를 이용한 용액이다. getter가 this.item 값을 반환하면 setter는 this.item 값을 먼저 업데이트 한 다음 관련 값을 업데이트합니다.

이 색상 선택기와 유사한 문제, 여기에이 문제의 더 복잡한 버전 http://jsfiddle.net/Phunky/2enc99r1/

Vue.component('pricing', { 
 
\t template: '#pricing-row', 
 
    props: ['item'], 
 
    computed: { 
 
    \t net:{ 
 
    \t get() { 
 
     \t return Number(this.item.net) 
 
     }, 
 
     set (net) { 
 
     \t this.item.net = Number(net) 
 
     this.setSellPrice() 
 
     } 
 
    }, 
 
    \t margin:{ 
 
    \t get() { 
 
     \t return this.item.margin 
 
     }, 
 
     set (margin) { 
 
     \t this.item.margin = Number(margin) 
 
     this.setSellPrice() 
 
     } 
 
    }, 
 
    \t sell:{ 
 
    \t get() { 
 
     \t return this.item.sell 
 
     }, 
 
     set (sell) { 
 
     \t this.item.sell = Number(sell) 
 
     \t this.setMargin() 
 
     } 
 
    } 
 
    }, 
 
    methods: { 
 
    
 
    setSellPrice() { 
 
     let price = (100/(100 - this.margin)) * this.net 
 
     this.item.sell = price.toFixed(2) 
 
    }, 
 
    
 
    setMargin() { 
 
     let profit = (this.sell - this.net) 
 
     let price = (100 * profit)/this.sell 
 
     this.item.margin = Number(price.toFixed(2)) 
 
    } 
 
    } 
 
    
 
}) 
 

 
new Vue({ 
 
    el: '#vue', 
 
    data: { 
 
    \t prices: [ 
 
    \t { 
 
     \t id: 1, 
 
     net: 5, 
 
     margin: 10, 
 
     sell: 5.56 
 
     }, 
 
    \t { 
 
     \t id: 2, 
 
     net: 7, 
 
     margin: 10, 
 
     sell: 7.78 
 
     },  
 
    ] 
 
    } 
 
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.5/vue.min.js"></script> 
 
<script type="text/x-template" id="pricing-row"> 
 
    <tr> 
 
    \t <td><input v-model="net" /></td> 
 
    <td><input v-model="margin" /></td> 
 
    <td><input v-model="sell" /></td> 
 
    </tr> \t 
 
</script> 
 

 

 
<div id="vue"> 
 
    <table> 
 
    <tr> 
 
     <th>Net</th> 
 
     <th>Margin</th> 
 
     <th>Price</th> 
 
    </tr> 
 
    <tr is="pricing" v-for="(price, index) in prices" :item="price" :key="price.id"></tr> 
 
    </table> 
 
</div>

+0

에 게시 할 것입니다. 나는 똑같이했습니다. 그러나 나는 여전히 튀는 효과를 얻고 있습니다. 스크린 캐스트를 참조하십시오. http://d.pr/i/1l04rR – Lee

+0

좋아,이 모든 시간의 좌절감을 찾은 후에 루트 원인을 찾았습니다. bootstrap-vue를 사용하고 있습니다 ... 입력에 문제가있는 것처럼 보입니다. 나 총이야 !! TY – Lee

+0

https://picturepan2.github.io/spectre/와 같은 CSS 전용 프레임 워크보다 우선적으로이 라이브러리를 사용하지 않거나 추가 된 기능이 필요하면 elemnet.io와 같은 것을 사용하십시오. vue 및 자료 또는 부트 스트랩의 vue 포트처럼 패치되지 않았습니다. – Daniel