简体   繁体   English

将样式应用于 v-for 使用 Vuejs 动态添加的 HTML 元素

[英]Apply style to an HTML element added dynamically by v-for using Vuejs

I'm adding elements to a list dynamically using v-for.我正在使用 v-for 动态地将元素添加到列表中。

<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>

I want to decorate the slider using rangeslider .我想使用rangeslider来装饰滑块。

Problem is, when a new element is added after the DOM is initialized, it's not taking the style specified in rangeslider.js.问题是,在 DOM 初始化后添加新元素时,它不会采用 rangeslider.js 中指定的样式。 Way to fix this is to call the reinitialize method in rangeslider.js which will redecorate all the slider elements.解决此问题的方法是调用 rangeslider.js 中的 reinitialize 方法,该方法将重新装饰所有滑块元素。

I'm not sure how to call the javascript method when the element is added dynamically during the runtime.我不确定在运行时动态添加元素时如何调用 javascript 方法。 Does anyone how to do it?有人怎么做吗? To me, it seems like a very common problem but I could not find a solution by Googling.对我来说,这似乎是一个非常普遍的问题,但我无法通过谷歌搜索找到解决方案。

My issue is same as discussed in github .我的问题与github中讨论的问题相同。

If you're new to JavaScript and Vue, you're diving in pretty close to the deep end.如果您是 JavaScript 和 Vue 的新手,那么您已经接近深入。 The rangeslider isn't just styling (like CSS), it's a widget that replaces the built-in range input. rangeslider 不仅仅是样式(如 CSS),它是一个替换内置范围输入的小部件。

One basic idea behind Vue is that it controls the DOM and you only modify your model, but there are some carefully controlled exceptions. Vue 背后的一个基本思想是它控制 DOM,你只修改你的模型,但是有一些小心控制的例外。 Components have lifecycle hooks where you are allowed to insert and modify DOM elements owned by the component.组件具有生命周期钩子,您可以在其中插入和修改组件拥有的 DOM 元素。

Some instructions for v-model support : v-model 支持的一些说明

So for a component to work with v-model, it should (these can be configured in 2.2.0+):因此,对于使用 v-model 的组件,它应该(这些可以在 2.2.0+ 中配置):

  • accept a value prop接受一个价值道具
  • emit an input event with the new value发出具有新值的输入事件

So we make a component whose template is a range input element.所以我们制作了一个模板是范围输入元素的组件。 We give it a value prop.我们给它一个value道具。 In the mounted hook, we initialize the rangeslider on the input element (made available as el ), then set it up to emit input events on change.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>

You can use the below CSS codes to apply some stylings in the html5 range input:您可以使用以下 CSS 代码在 html5 范围输入中应用一些样式:

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;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM