首页 > 解决方案 > 根据输入类型在 Vue 3 上编写了一个程序:范围,不能按预期工作

问题描述

任务是:你有总票数。在本例中为 22。您使用类型为范围的输入进行投票。每个输入可以投 10 票。假设我们有 5 个输入,总共有 50 个投票,但你只有 22 个,然后在花费你的投票后,最大输入值减少到 0。我写了它,它可以工作,但它有一个小故障。任何人都可以看到如何纠正它?

PS 最后我需要使用键创建对象 -> 用户 ID 和值 -> 他获得了多少票。这个对象是objRes

这是沙盒的网址,但它不能按预期工作

这是父母:

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

这是孩子:

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

标签: vue.jsinputrangevuejs3

解决方案


您的代码使用 Vue 3,并且您已将其标记为,但您的演示实际上使用 Vue 2,它无法检测对象键的添加/删除(更改检测警告)。

在 Vue 2 中,解决方法是使用vm.$set()

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

Vue 2 演示

在 Vue 3 中,您的代码已经正确添加了对象键(不需要vm.$set)。

Vue 3 演示


推荐阅读