最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Vue JS How to bind the onChange event to change the value in input - Stack Overflow

programmeradmin1浏览0评论

I am using npm package vue-range-ponent with which I change the value with a slider and then that value is reactively changed in the input

My problem is that I can’t apply the onChange event for inputs, I need to be able to change the value in the input, for example, put the number 70, and then this number was applied to the vue-range-ponent, something like that

Here is my sandbox code

<template>
  <div class="app-content">
    <div>
        <input type="text" v-model="value[0]" />
        <input type="text" v-model="value[1]" />
    </div>

    <vue-range-slider
      v-model="value"
      :min="min"
      :max="max"
      :formatter="formatter"
      style="margin-top: 40px"
    ></vue-range-slider>

    <div class="multi-range-value-container">
        <p>{{ value[0] }}</p>
        <p>{{ value[1] }}</p>
    </div>
    </div>
</template>

<script>
import "vue-range-ponent/dist/vue-range-slider.css";
import VueRangeSlider from "vue-range-ponent";

export default {
  data() {
    return {
      value: [0, 100],
    };
  },

  methods: {
    onChange(event) {
      console.log(event.target.value);
    },
  },

  ponents: {
    VueRangeSlider,
  },
  created() {
    this.min = 0;
    this.max = 1000;
    this.formatter = (value) => `$${value}`;
  },
};
</script>

I am using npm package vue-range-ponent with which I change the value with a slider and then that value is reactively changed in the input

My problem is that I can’t apply the onChange event for inputs, I need to be able to change the value in the input, for example, put the number 70, and then this number was applied to the vue-range-ponent, something like that

Here is my sandbox code

<template>
  <div class="app-content">
    <div>
        <input type="text" v-model="value[0]" />
        <input type="text" v-model="value[1]" />
    </div>

    <vue-range-slider
      v-model="value"
      :min="min"
      :max="max"
      :formatter="formatter"
      style="margin-top: 40px"
    ></vue-range-slider>

    <div class="multi-range-value-container">
        <p>{{ value[0] }}</p>
        <p>{{ value[1] }}</p>
    </div>
    </div>
</template>

<script>
import "vue-range-ponent/dist/vue-range-slider.css";
import VueRangeSlider from "vue-range-ponent";

export default {
  data() {
    return {
      value: [0, 100],
    };
  },

  methods: {
    onChange(event) {
      console.log(event.target.value);
    },
  },

  ponents: {
    VueRangeSlider,
  },
  created() {
    this.min = 0;
    this.max = 1000;
    this.formatter = (value) => `$${value}`;
  },
};
</script>
Share Improve this question asked Apr 12, 2021 at 8:36 SynchroSynchro 1,2694 gold badges25 silver badges61 bronze badges 2
  • There are limitations regarding array reactivity in Vue. Assign a new array instead of mutating its elements – Estus Flask Commented Apr 12, 2021 at 8:52
  • please show me some example code – Synchro Commented Apr 12, 2021 at 9:11
Add a ment  | 

2 Answers 2

Reset to default 3

One caveat of Vue's reactivity system is that you cannot detect changes to an array when you directly set the value of an item via its index.

As explained in the link, there are two main methods of making array modifications reactive:

// Vue.set
Vue.set(vm.items, indexOfItem, newValue)

// Array.prototype.splice
vm.items.splice(indexOfItem, 1, newValue)

Using these methods forces the VueJS reactivity system to update its state.

To implement this solution in your example, you can use a watcher on a modelled value, an @change event or a @keyup event.

A watcher is likely the most resource intensive approach. I would suggest using @keyup (which would fire on every keypress as opposed to when you unfocus the input with @change) and then debouncing the input if the value is used to filter/sort/load anything.

If you wanted to as well, you could also directly set the entire array.

For example instead of setting value[0] = something you could do value = [...value, something];and this would be reactive.

It is indeed Vue reactivity issuse

You can fix it by not using v-model syntactic sugar but split it like this:

From:

<input type="text" v-model="value[0]" />

to:

<input type="text" :value="value[0]" @input="changeRange(0, $event.target.value)" />

define a method:

methods: {
  changeRange(index, value) {
    const v = parseInt(value, 10) // value from input is always string
    this.$set(this.value, index, v)
  }
}

Update

Above code is a fix you would need anyway but unfortunately the vue-range-ponent has a different issue as it blocks all user keyboard input to any input element on the same page - see this and this issue

It was already fixed by this pull request but it wasn't released yet to npm

You can use some of the workarounds described in the issues BUT given the way how the maintainer (not) handles the issue, it would be probably better for you to look around for another ponent with similar functionality...

发布评论

评论列表(0)

  1. 暂无评论