slider icon indicating copy to clipboard operation
slider copied to clipboard

Vue 3 with setup don't work to change v-model from outside?

Open seriiserii825 opened this issue 11 months ago • 0 comments

Hi, thanks for plugin.

I am using composition api with setup.

<script lang="ts" setup>
import Slider from "@vueform/slider";
import { onMounted, ref } from "vue";

const emits = defineEmits(["emit_change"]);

const props = defineProps({
  label: {
    type: String,
    required: true,
  },
  value_range: {
    type: Array,
    required: true,
  },
  min: {
    type: Number,
    required: true,
  },
  max: {
    type: Number,
    required: true,
  },
  min_label: {
    type: String,
    required: false,
    default: "",
  },
  max_label: {
    type: String,
    required: false,
    default: "",
  },
  alternate_options: {
    type: Array,
    required: false,
  },
});

const proportions = ref(1);

const value = ref([1, 10]);

const type = "Range";
const changed_values = ref([]);
const min_value = ref(0);
const max_value = ref(0);

function onChange(args) {
  changeValues(args);
  const min = args[0];
  const max = args[1];
  emits("emit_change", [min, max]);
}

function changeValues(values) {
  changed_values.value = values;
  if (props.alternate_options && props.alternate_options.length) {
    min_value.value = props.alternate_options[values[0] - 1].name;
    max_value.value = props.alternate_options[values[1] - 1].name;
  } else {
    min_value.value = clearPrice(String(values[0]));
    max_value.value = clearPrice(String(values[1]));
  }
}

function clearPrice(price) {
  /**
   * Number.prototype.format(n, x, s, c)
   *
   * @param integer n: length of decimal
   * @param integer x: length of whole part
   * @param mixed   s: sections delimiter
   * @param mixed   c: decimal delimiter
   */
  Number.prototype.format = function (n, x, s, c) {
    let re = "\\d(?=(\\d{" + (x || 3) + "})+" + (n > 0 ? "\\D" : "$") + ")",
      num = this.toFixed(Math.max(0, ~~n));

    return (c ? num.replace(".", c) : num).replace(
      new RegExp(re, "g"),
      "$&" + (s || ","),
    );
  };

  const myString = Number(price.replace(/\D/g, ""));

  return myString.format(-3, 3, ".", ","); // "12.345.678,90"
}

onMounted(() => {
  min_value.value = props.min;
  max_value.value = props.max;
  proportions.value = 100 / props.max;
  changed_values.value = props.value_range;
});
</script>
<template>
  <div class="v-popup__label">{{ label }}</div>
  <div v-if="changed_values && changed_values.length" class="range-slider">
    <Slider
      v-model="changed_values"
      :min="min"
      :max="max"
      @update="onChange"
      :tooltips="false"
    />
  </div>
  <div class="v-popup__info">
    <span>{{ min_value }} {{ min_label }} </span> -
    <span>{{ max_value }} {{ max_label }}</span>
  </div>
</template>

And when i change min and max with props from outside, v-model(changed_values) is note changed.

v-model

seriiserii825 avatar Aug 07 '23 08:08 seriiserii825