【问题标题】:Computed property was assigned to but it has no setter - a toggle component已分配计算属性,但它没有设置器 - 切换组件
【发布时间】:2019-08-01 11:41:50
【问题描述】:

我正在 Vue 中创建一个简单的开关切换组件,它有一个 v-model 和 @updated。但是当用户切换开关时,我似乎无法更改模型。首先,我收到错误以避免直接改变道具。但现在我又遇到了另一个错误。

[Vue 警告]:计算属性“isSwitchOn”已分配给但它有 没有二传手。

组件就是这样使用的

<iswitch v-model="switchGender" @updated="handleUpdatedGender" />

这是组件本身

export default {
    template: `
        <span
            @click="toggleSwitch"
            :class="{ active: isSwitchOn }">

            <span class="toggle-knob"></span>
        </span>
    `,

    props: ['value'],

    methods:
    {
        toggleSwitch()
        {
            this.isSwitchOn = !this.isSwitchOn

            this.$emit('input', this.isSwitchOn)
            this.$emit('updated')
        }
    },

    computed:
    {
        isSwitchOn()
        {
            return this.value
        }
    },
};

【问题讨论】:

    标签: javascript vue.js


    【解决方案1】:

    错误由以下语句触发:this.isSwitchOn = !this.isSwitchOn。您正在尝试为计算属性赋值,但未提供 setter

    您需要按如下方式定义您的计算属性,以使其用作gettersetter

    computed:
    {
        isSwitchOn:
        {
            get()
            {
                return this.value
            },
            set(value)
            {
                this.value = value
            }
        }
    }
    

    另外,不建议直接改变道具。您可以做的是添加一个新的数据属性并使用观察器将其与value 属性同步。

    我认为这样的事情会起作用:

    props: ['value'],
    data()
    {
        return {
           val: null
        }
    },
    computed:
    {
        isSwitchOn:
        {
            get()
            {
                return this.val
            },
            set(value)
            {
                this.val = value
            }
        }
    },
    watch: {
       value(newVal) {
           this.val = newVal
       }
    }
    

    【讨论】:

    • 谢谢,我确实需要一个值守者。
    【解决方案2】:

    默认情况下,计算属性只有 getter,但您也可以在需要时提供 setter。检查official documentation

    computed:
    {
        isSwitchOn() {
            get() { return this.value }
            set(val) { this.value = val }
        }
    }
    

    替代方式:

    在你的父组件中:

    <iswitch ref="switcher" @input="methodForInput" v-model="switchGender" @updated="handleUpdatedGender" />
    
    methods: {
      methodForInput(event){
        this.$refs.switcher.isSwitchOn = event;
      }
    }
    

    在您的子组件中:

    export default {
        template: `
            <span
                @click="toggleSwitch"
                :class="{ active: isSwitchOn }">
    
                <span class="toggle-knob"></span>
            </span>
        `,
    
        data() {
          return {
            isSwitchOn: false
          };
        },
    
        methods:
        {
            toggleSwitch()
            {
                this.isSwitchOn = !this.isSwitchOn
    
                this.$emit('input', this.isSwitchOn)
                this.$emit('updated')
            }
        }
    };
    

    更新 3:抱歉,一开始没有包含父组件。

    【讨论】:

    • 通过设置 this.value 你正在改变一个道具。
    • @Liga 我已经用另一种方式进行了更新,不确定它是否会有所帮助。
    • 我找到了解决方案。我必须为 value 道具添加一个 value() 观察者。谢谢!
    猜你喜欢
    • 2019-05-21
    • 2020-10-04
    • 2018-09-26
    • 2020-11-07
    • 2020-10-23
    • 2018-02-16
    • 2018-11-02
    • 2020-07-09
    • 2021-03-17
    相关资源
    最近更新 更多