2017-03-09 6 views
1

v-for를 사용하여 동적으로 목록에 요소를 추가하고 있습니다.Vuejs를 사용하여 v-for에 의해 동적으로 추가 된 HTML 요소에 스타일 적용

<ol> 
    <li v-for="light in lights"> 
     <input type="range" min="0" max="255" v-model="light.currentBrightness" v-on:change="setBrightness(light)" /> 
    </li> 
</ol> 

rangeslider을 사용하여 슬라이더를 장식하고 싶습니다.

문제는 DOM을 초기화 한 후에 새 요소를 추가하면 rangeslider.js에 지정된 스타일을 사용하지 않는 것입니다. 이 문제를 해결할 방법은 rangeslider.js의 reinitialize 메서드를 호출하여 모든 슬라이더 요소를 다시 장식하는 것입니다.

런타임 중에 요소가 동적으로 추가 될 때 javascript 메서드를 호출하는 방법을 모르겠습니다. 그것을하는 방법 누군가가 있습니까? 나에게는 매우 일반적인 문제인 것처럼 보이지만 Google 검색으로 해결 방법을 찾을 수 없습니다.

내 문제는 github에서 논의한 내용과 같습니다.

+0

을 내가 확실히 문제를 이해하지 않지만, 가능한 해결책은 어쩌면 것 'mounted()'lifecycle hook 내에서 범위 슬라이더를 초기화하십시오. 다른 방법으로 조명 배열을 볼 수 있습니다 (배열이라고 생각합니다). 변경이 감지되면, 당신은 범위 라이저 j를 초기화하는 메소드를 실행할 수 있습니다. –

+0

이 예를 살펴보십시오. https://vuejs.org/v2/examples/select2.html –

+0

'watch : {lights() {$ ('input [type = "range"]'). 범위 라이더()}}'가능합니까? –

답변

2

JavaScript 및 Vue를 처음 사용하는 경우라면 깊은 곳에서 다이빙을 할 수 있습니다. rangeslider는 CSS와 같은 단순한 스타일링이 아니라 내장 된 범위 입력을 대체하는 위젯입니다.

Vue의 기본 아이디어 중 하나는 DOM을 제어하고 모델 만 수정한다는 것입니다. 그러나 신중하게 제어되는 예외가 있습니다. 구성 요소에는 구성 요소가 소유 한 DOM 요소를 삽입하고 수정할 수있는 lifecycle hooks이 있습니다.

:

그래서 V-모델로 작업 할 수있는 구성 요소에 대해, 그것은 (이러한 가 2.2.0+에서 구성 할 수 있습니다)한다

:

  • 가치도
  • 소품 동의
  • 새 값으로 입력 이벤트를 내 보냅니다.

그래서 우리는 템플릿이 범위 입력 요소 인 구성 요소를 만듭니다. 우리는 value 소품을 제공합니다. mounted 후크에서 입력 요소 (el으로 사용 가능)에서 범위 슬라이드를 초기화 한 다음 변경시 input 이벤트를 발생하도록 설정합니다.

new Vue({ 
 
    el: '#app', 
 
    data: { 
 
    lights: [{ 
 
     currentBrightness: 10 
 
     }, 
 
     { 
 
     currentBrightness: 30 
 
     } 
 
    ] 
 
    }, 
 
    methods: { 
 
    addRange: function() { 
 
     this.lights.push({ 
 
     currentBrightness: 50 
 
     }); 
 
    } 
 
    }, 
 
    components: { 
 
    rangeSlider: { 
 
     props: ['value', 'min', 'max'], 
 
     template: '<input min="{{min}}" max="{{max}}" type=range />', 
 
     mounted: function() { 
 
     var vm = this 
 
     $(this.$el) 
 
      .val(this.value) 
 
      // init rangeslider 
 
      .rangeslider({ 
 
      polyfill: false 
 
      }) 
 
      // emit event on change. 
 
      .on('change', function() { 
 
      vm.$emit('input', this.value) 
 
      }) 
 
     } 
 
    } 
 
    } 
 
});
<link href="//cdnjs.cloudflare.com/ajax/libs/rangeslider.js/2.3.0/rangeslider.css" rel="stylesheet" /> 
 
<script src="//cdnjs.cloudflare.com/ajax/libs/vue/2.2.2/vue.min.js"></script> 
 
<script src="//ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> 
 
<script src="//cdnjs.cloudflare.com/ajax/libs/rangeslider.js/2.3.0/rangeslider.min.js"></script> 
 
<div id="app"> 
 
    <ol> 
 
    <li v-for="light in lights"> 
 
     <range-slider v-model="light.currentBrightness" min="0" max="255"></range-slider> 
 
     <div>{{light.currentBrightness}}</div> 
 
    </li> 
 
    </ol> 
 
    <button @click="addRange">Add Range</button> 
 
</div>

+0

이 예제를 작성하는 데 시간을 내 주셔서 감사합니다. 이 배경 개념을 완전히 이해하기 위해서는 더 많은 것을 배워야 할 것처럼 보입니다. 다시 한 번 감사드립니다! – Abhijeet

0

당신은 HTML5 범위 입력에 약간의 stylings가를 적용하는 CSS 코드 아래를 사용할 수 있습니다

body { 
    padding: 30px; 
} 
input[type=range] { 
    /*removes default webkit styles*/ 
    -webkit-appearance: none; 

    /*fix for FF unable to apply focus style bug */ 
    border: 1px solid white; 

    /*required for proper track sizing in FF*/ 
    width: 300px; 
} 
input[type=range]::-webkit-slider-runnable-track { 
    width: 300px; 
    height: 5px; 
    background: #ddd; 
    border: none; 
    border-radius: 3px; 
} 
input[type=range]::-webkit-slider-thumb { 
    -webkit-appearance: none; 
    border: none; 
    height: 16px; 
    width: 16px; 
    border-radius: 50%; 
    background: goldenrod; 
    margin-top: -4px; 
} 
input[type=range]:focus { 
    outline: none; 
} 
input[type=range]:focus::-webkit-slider-runnable-track { 
    background: #ccc; 
} 

input[type=range]::-moz-range-track { 
    width: 300px; 
    height: 5px; 
    background: #ddd; 
    border: none; 
    border-radius: 3px; 
} 
input[type=range]::-moz-range-thumb { 
    border: none; 
    height: 16px; 
    width: 16px; 
    border-radius: 50%; 
    background: goldenrod; 
} 

/*hide the outline behind the border*/ 
input[type=range]:-moz-focusring{ 
    outline: 1px solid white; 
    outline-offset: -1px; 
} 

input[type=range]::-ms-track { 
    width: 300px; 
    height: 5px; 

    /*remove bg colour from the track, we'll use ms-fill-lower and ms-fill-upper instead */ 
    background: transparent; 

    /*leave room for the larger thumb to overflow with a transparent border */ 
    border-color: transparent; 
    border-width: 6px 0; 

    /*remove default tick marks*/ 
    color: transparent; 
} 
input[type=range]::-ms-fill-lower { 
    background: #777; 
    border-radius: 10px; 
} 
input[type=range]::-ms-fill-upper { 
    background: #ddd; 
    border-radius: 10px; 
} 
input[type=range]::-ms-thumb { 
    border: none; 
    height: 16px; 
    width: 16px; 
    border-radius: 50%; 
    background: goldenrod; 
} 
input[type=range]:focus::-ms-fill-lower { 
    background: #888; 
} 
input[type=range]:focus::-ms-fill-upper { 
    background: #ccc; 
}