Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
120 views
in Technique[技术] by (71.8m points)

vue.js - Wrote a program on Vue 3 based on inputs type: range, doesn't work as supposed

The task is: you have total votes. In this case 22. And you vote with inputs which has type: range. Every input can make 10 votes. Lets say we have 5 inputs in sum it's 50 votes, but you have only 22, then after spending your votes max input value reduces to 0. I wrote it, it works but it has a glitch. Can anybody see how to correct it ?

PS at the end I need to create object with key -> users id and value -> how many votes he got. This object is objRes

Here is url for sandBox, but it doesn't work as supposed

Here is parent :

<template>
  <div class="vote">
    <div class="vote__title">Left: <span>{{ hmLeft }}</span> votes</div>
    <div class="vote__body">
      <div v-for="user in activeInnerPoll" :key="user._id">
        <userVoteFor :hmLeft="hmLeft" @cntCount="cntCount"  :id="user._id"/>
      </div>
    </div>
  </div>
</template>

<script>
import { mapGetters } from "vuex"
import userVoteFor from "@/components/userVoteFor";

export default {
  name: "Vote.vue",
  components: {
    userVoteFor
  },
  data(){
    return {
      votes: 22, // maximum votes
      objRes: {} // result object
    }
  },
  computed: {
    ...mapGetters("polls", ["activeInnerPoll"]), // Getting object with all users it has 
                                                // {"_id": "random string"}
    hmLeft(){ // hm left votes
      let sum = 0;

      for(let key in this.objRes){
        sum += this.objRes[key];
      }

      return this.votes - sum;
    }
  },
  methods: { // setting votes to result object
    cntCount(id, cnt){
      this.objRes[id] = parseInt(cnt);
    }
  }
}
</script>

<style scoped lang="scss">
@import "@/assets/vars.scss";
@import "@/assets/base.scss";

.vote{
    &__title{
      @include center;
      margin-top: 15px;
      span{
        font-size: 20px;
        margin: 0 5px;
        color: $pink;
      }
  }
}
</style>

Here is child:

<template>
  <div class="vote__component">
    <label class="vote__component__label" :for="id">{{ playerNameById( id )}}</label>
    <div>
      <input @input="stepCount"
             ref="input"
             class="vote__component__input"
             :id="id"
             :style="style"
             type="range"
             min="0"
             v-model="cnt"
             :max="max">
      <div class="vote__component__res">{{ cnt }}</div>
    </div>
  </div>
</template>

<script>
import { mapGetters } from "vuex";

export default {
  name: "userVoteFor.vue",
  props: {
      id: {
        type: String,
        required: true
      },
     hmLeft: {
        type: Number,
        required: true
      }
    },
  emits: ["cntCount"],
  data() {
    return {
      defaultMax: 10,
      cnt: 0,
    }
  },
  computed: {
    ...mapGetters("user", ["playerNameById"]),
    max(){ // formula is simple, take 10 if enough to vote if not then hmLeft
      return this.defaultMax - this.cnt <= this.hmLeft ? this.defaultMax : this.hmLeft;
    },
    style(){ //adding styles to input
      return `width: ${this.max * 12 + 20}px`;
    }
  },
  methods: {
    stepCount(){
      this.$emit("cntCount", this.id, this.cnt);
    }
  }
}
</script>

<style scoped lang="scss">
  .vote__component{
    width: 80%;
    margin: 10px auto;
    position: relative;
    display: flex;
    justify-content: right;
    padding: 10px 0;
    font-size: 15px;
    &__cover{
      width: 100%;
      height: 100%;
      position: absolute;
      top: 0;
      right: 0;
    }
    &__input{
      margin-left: auto;
      margin-right: 20px;
    }
    &__res{
      position: absolute;
      top: 20%;
      right: 0;
    }
    &__label{
    }
  }
</style>
question from:https://stackoverflow.com/questions/65915631/wrote-a-program-on-vue-3-based-on-inputs-type-range-doesnt-work-as-supposed

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

Your code uses Vue 3, and you've tagged it , but your demo actually uses Vue 2, which cannot detect object key addition/deletion (Change detection caveats).

In Vue 2, the workaround is to use vm.$set():

// this.objRes[id] = parseInt(cnt)
this.$set(this.objRes, id, parseInt(cnt))

Vue 2 demo

In Vue 3, your code already adds the object keys correctly (no need for vm.$set).

Vue 3 demo


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...