【问题标题】:VueJS3 : radio v-model doesn't update when switch changedVueJS3:开关更改时收音机 v-model 不更新
【发布时间】:2023-01-27 03:34:29
【问题描述】:

我希望默认选中我的输入收音机以更新 v-model 中的值。但是当我切换计划时,v-model 不会动态更新。我卡住了。也许我必须看看“watch”或“ref”。 我的formValues 是被动的,并在 v 模型中返回了正确的答案。但是当我切换计划时...不会更新检查输出。

<template>
    <!-- Second step -->
    <section id="second-step">

        <div class="row mt-4 px-2">
            <div class="col-12">
                <h1 class="h2 fw-bold">Select your plan</h1>
                <p class="pt-1">
                    You have the option of monthly or yearly billing.
                </p>
            </div>
        </div>

        <!-- Form 2 -->
        <form class="row justify-content-xl-between px-3 pe-xl-0" id="form-plan">

            <!-- Plan 1 -->
            <div class="col-12 col-xl plan mt-3 p-0">
                <label for="arcade-plan" class="plan-label"></label>
                <input v-model="check" type="radio" v-if="formValues.billing.monthly" :value="formValues.plan[0].name" name="plan" id="arcade-plan" checked>
                <input v-model="check" type="radio" v-else="formValues.billing.yearly" :value="formValues.plan[1].name" name="plan" id="arcade-plan" checked>
                <div class="plan-content card ps-2">
                    <div class="plan-icon mt-1">
                        <img src="assets/images/icon-arcade.svg" alt="">
                    </div>
                    <div class="plan-description">
                        <span class="plan-title mb-0">Arcade</span>
                        <div class="price monthly">
                            <div class="amount mb-0 fs-6 fw-medium text-cool-gray">$9/mo</div>
                        </div>
                        <div class="price yearly d-none">
                            <div class="amount fs-6 fw-medium text-cool-gray">$90/yr</div>
                            <div class="billing-msg text-primary">2 months free</div>
                        </div>
                    </div>
                </div>
            </div>


            <!-- Plan 2 -->
            <div class="col-12 col-xl plan mt-3 p-0">
                <label for="advanced-plan" class="plan-label"></label>
                <input v-model="check" type="radio" v-if="formValues.billing.monthly" :value="formValues.plan[2].name" name="plan" id="advanced-plan">
                <input v-model="check" type="radio" v-else="formValues.billing.yearly" :value="formValues.plan[3].name" name="plan" id="advanced-plan">
                <div class="plan-content card ps-2">
                    <div class="plan-icon mt-1">
                        <img src="assets/images/icon-advanced.svg" alt="">
                    </div>
                    <div class="plan-description">
                        <span class="plan-title mb-0">Advanced</span>
                        <div class="price monthly">
                            <div class="amount mb-0 fs-6 fw-medium text-cool-gray">$12/mo</div>
                        </div>
                        <div class="price yearly d-none">
                            <div class="amount fs-6 fw-medium text-cool-gray">$120/yr</div>
                            <div class="billing-msg text-primary">2 months free</div>
                        </div>
                    </div>
                </div>

            </div>

            <!-- Plan 3 -->
            <div class="col-12 col-xl plan mt-3 p-0">
                <label for="pro-plan" class="plan-label"></label>
                <input v-model="check" type="radio" v-if="formValues.billing.monthly" :value="formValues.plan[4].name" name="plan" id="pro-plan">
                <input v-model="check" type="radio" v-else="formValues.billing.yearly" :value="formValues.plan[5].name" name="plan" id="pro-plan">
                <div class="plan-content card ps-2">
                    <div class="plan-icon mt-1">
                        <img src="assets/images/icon-pro.svg" alt="">
                    </div>
                    <div class="plan-description">
                        <span class="plan-title mb-0">Pro</span>
                        <div class="price monthly">
                            <div class="amount mb-0 fs-6 fw-medium text-cool-gray">$15/mo</div>
                        </div>
                        <div class="price yearly d-none">
                            <div class="amount fs-6 fw-medium text-cool-gray">$150/yr</div>
                            <div class="billing-msg text-primary">2 months free</div>
                        </div>
                    </div>
                </div>

            </div>



            <!-- Switch billing -->
            <div class="col-12 py-3 rounded">
                <div class="row bg-alabaster justify-content-center px-2">
                    <div class="col-10 col-sm-8 col-md-6">
                        <div class="switch-wrapper py-2 mb-0">
                            <input id="monthly" type="radio" name="switch" checked>
                            <input id="yearly" type="radio" name="switch">
                            <label id="billing-monthly" for="monthly" class="mx-sm-5">Monthly</label>
                            <label id="billing-yearly" for="yearly" class="mx-sm-5">Yearly</label>
                            <span class="toggler"></span>
                        </div>
                    </div>
                </div>
            </div>
        </form>

    </section>
    <div class="container">
        Selected :
        {{ check }}
    </div>
</template>

<script>
import { onMounted } from 'vue';
export default {
    data() {
        return {
            check: 'Arcade (Monthly)'
        }
    },
    props: {
        step: Number,
        formValues: Object
    },
    setup(props) {
        onMounted(() => {
            const switchInputs = document.querySelectorAll(".switch-wrapper input");
            const prices = document.querySelectorAll(".price");
            const toggleClass = "d-none";
            /* Switch */
            for (const switchInput of switchInputs) {
                switchInput.addEventListener("input", function () {
                    for (const price of prices) {
                        price.classList.add(toggleClass);
                    }
                    const activePrices = document.querySelectorAll(
                        `.price.${switchInput.id}`
                    );
                    for (const activePrice of activePrices) {
                        activePrice.classList.remove(toggleClass);
                    }

                    /* Change billing type */
                    props.formValues.updateBilling()
                    console.log(props.formValues.billing.yearly)

                })
            }
        })
}
}





</script>

我还没有找到关于这个问题的任何消息来源。我想我可以用手表或裁判做点什么。

【问题讨论】:

    标签: vuejs3 v-model


    【解决方案1】:

    这是一个非常基本的 Radio 输入绑定示例:

    const { createApp } = Vue;
        
    const App = {
      data() {
          return {
              check: 'Arcade (Monthly)',
              items: ['Arcade (Monthly)', 'Advanced (Monthly)']
          }
      }
    }
    
    const app = createApp(App)
    app.mount('#app')
    <div id="app">  
      <div>Picked: {{ check }}</div><br />  
      <div v-for="(item, index) in items">
        <input type="radio" :id="`item_${index}`" :value="item" v-model="check" />
        <label :for="`item_${index}`">{{item}}</label>
      </div>
    </div>
    <script src="https://unpkg.com/vue@3/dist/vue.global.prod.js"></script>

    【讨论】:

    • 何好,这是一个很好的例子。但我的问题是当我切换计划时(参见演示)。事实上,选择的计划不会自动更新。我会继续测试其他解决方案。但是谢谢你的时间亲爱的。
    【解决方案2】:

    我认为你把事情复杂化了。

    当您需要组合多个响应式属性时,会使用计算属性。在这种情况下,它将是所选计划 + 期间的消息输出。

    这是working example in CodeSandbox

    此外,您没有正确使用条件渲染,这可能是您的数据未正确更新的原因。

    v-if="logical expression"
    v-else-if="logical expression"
    v-else
    

    参考:

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-06-26
      • 2021-11-30
      • 2022-10-15
      • 1970-01-01
      • 1970-01-01
      • 2017-09-22
      • 1970-01-01
      • 2017-09-09
      相关资源
      最近更新 更多