【问题标题】:Vue JS - Update selected value of dropdownVue JS - 更新下拉列表的选定值
【发布时间】:2021-10-03 12:31:12
【问题描述】:

我目前在尝试根据复选框的真实性更新下拉列表中的选定项目时遇到困难。未更新所选项目的原因是因为我尝试添加为所选项目的字符串不存在于下拉列表中。因此,当我选中复选框时,我需要将字符串添加到下拉列表中并将其显示为选定项。如果我选择添加下拉列表中已经存在的项目字符串,则所选项目会相应更新。此外,如果我取消选中该复选框,则该字符串应从下拉列表中删除并作为选定项。

为了提供更多背景信息,我有一个表单,用户可以在其中添加他们的工作经验。因此用户可以添加他们的开始年份和结束年份。如果用户目前正在工作,他们可以选中复选框,在该复选框中 endYear 将选择“Present”而不是一年。

为此,我正在使用三个组件:

ExperienceDetails.vue

...form-wrapper

<div class="year-picker">
     <YearPicker :placeholder="'Voeg datum toe'"
          :select-name="'endYear'"
          :title="'Einddatum'"
          :selected="experienceInfo.endYear" // Here experienceInfo.endYear is being updated with my string, however it does not appear as a selected item.
          :earliest-date="currentYear - 50"
          :latest-date="currentYear"
          :callback="setEndYear"
          :present-year="isPresent"/>
</div>

<div class="checkbox">
      <BasicCheckbox
           :label-text="'Dit is mijn huidige functie.'"
           :id="`id`"
           :callback="setPresent"
           :is-checkbox-checked="isPresent"
           class="expires-checkbox"/>
</div>


export default {
  name: "ExperienceDetails",
  components: {YearPicker},
  props: {
    experienceInfo: {
      type: Object,
      required: false
    }
  },
  setup(props, {emit}) {
    const currentYear = ref(0);
    setCurrentYear();

    function setCurrentYear() {
      currentYear.value = new Date().getFullYear();
    }

    const endYear = ref(props.experienceInfo.endYear ? props.experienceInfo.endYear : currentYear.value);

    function setEndYear(year) {
      endYear.value = year;
    }

    const isPresent = ref(undefined);

    function setPresent() {
      isPresent.value = !isPresent.value;
      const endYearPresent = 'Nu';
      if (isPresent.value) {
        setEndYear(endYearPresent);
        props.experienceInfo.endYear = endYearPresent;
      } else {
        props.experienceInfo.endYear = ''
      }
    }

YearPicker.vue

<template>
  <div>
    <h3 class="form-input-title">{{ title }}</h3>
    <select name="startYear" id="startYear" :value="selected" class="form-input" @change="executeCallback">
      <option></option>
      <option v-for="year in validYears" :key="year" :value="year">{{year}}</option>
    </select>
  </div>
</template>

export default {
  name: "YearPicker",
  props: {
    title: {
      type: String,
      required: false
    },
    callback: {
      type: Function,
      required: true
    },
    selected: {
      type: [String, Number],
      required: false
    },
    earliestDate: {
      type: Number,
      required: true
    },
    latestDate: {
      type: [Number, String],
      required: true
    },
    presentYear: {
      type: Boolean,
      required: false
    }
  },
  setup(props) {

    onBeforeMount(calculateDateRange)
    watch(() => props.earlestDate, (newValue, prevValue) => {
      calculateDateRange()
    });
    // If there is a new value passed from the parent, the dropdown should display that new value.
    watch(() => props.latest, (newValue, prevValue) => {
      calculateDateRange()
    });


// Here I watch presentYear. If presentYear is true (checkbox is ticked) I reset validYears as an empty array so that the years will no longer be visible and instead a string 'Present' should be added.
    watch(() => props.presentYear, (newValue, prevValue) => {
      if (newValue) {
        validYears.value = [];
      } else {
        calculateDateRange()
      }
    });

    function executeCallback(event) {
      props.callback(event.target.value);
    }

    const validYears = ref([])
    function calculateDateRange () {
      for(let year = props.latestDate; year >= props.earliestDate; year--){
        validYears.value.push(year)
      }
    }

    return {
      validYears,
      executeCallback,
    }
  }
}

BasicCheckbox.vue - 这里没有发生太多事情。

<template>
  <div class="check-wrapper">
    <label :for="id" class="check-label">
      <input @click="checkCheckbox()"
             :id="id"
             :checked="isCheckboxChecked"
             :value="checkboxValue"
             type="checkbox"
             name="newsletter"/>
      <span v-if="labelText">{{ labelText }}</span>
      <span class="check-mark"></span>
    </label>
  </div>
</template>

<script>
  export default {
    name: 'BasicCheckbox',
    props: {
      labelText: {
        type: String,
        required: false
      },
      callback: {
        type: Function,
        required: false
      },
      id: {
        type: String,
        required: true
      },
      isCheckboxChecked: {
      },
      checkboxData: {
        type: Object,
        required: false,
      },
    },
    data: () => ({
      checkboxValue: false
    }),
    methods: {
      updateValue: function () {
        if (this.$props.callback) {
          this.$props.callback(this.$props.id, this.$props.checkboxData);
        }
      },
      checkCheckbox: function () {
        this.updateValue();
      }
    }
  };

【问题讨论】:

    标签: javascript html vue.js vuejs3 vue-composition-api


    【解决方案1】:

    您是否尝试过使用计算属性来管理您的下拉列表?这样您就可以添加/删除被切换的项目。

    https://vuejs.org/v2/guide/computed.html

    例如

    computed: {
      validYears() {
        if (this.presentYear) {
         return [];
        } else {
          return this.calculateDateRange(); // make this a vue method
        }
      },
    }
    

    我尽量避开观察者,而更喜欢计算的道具和方法(文档也推荐这样做)。

    只要你的 props 改变(presentYear 改变),计算出来的 prop 就会更新,所以你可以根据需要重新渲染你的列表。

    我还会使用v-showv-if 切换组件,因此如果您想用静态文本交换下拉列表,您可以轻松分离逻辑。

    【讨论】:

    • 我没有考虑太多,但我认为这可能对我有帮助。您能否提供一个简短的示例,说明我如何使用计算属性来处理它?
    • 用一个例子和更多细节更新了我的评论!希望对您有所帮助。
    • 谢谢。我还没有完全实现这一点,但你的回答确实激励我度过了这个挑战。
    猜你喜欢
    • 1970-01-01
    • 2015-04-24
    • 1970-01-01
    • 1970-01-01
    • 2015-05-12
    • 1970-01-01
    • 2021-12-31
    • 1970-01-01
    • 2013-10-30
    相关资源
    最近更新 更多