Vuejs为什么不注册启用或禁用我的按钮?

时间:2018-12-04 18:18:23

标签: javascript vue.js

我正在构建一个简单的Vuejs网站,您可以在其中编写有关会议的注释。加载后,它将从服务器获取会议记录并显示它们。用户随后写东西时,他可以单击“保存”按钮,这会将文本保存到服务器。将注释保存到服务器后,需要禁用“保存”按钮,并显示“已保存”文本。然后,当用户再次开始写文本时,应再次启用该按钮并再次显示“保存”。我会说这是一个非常基本的功能,但是我遇到了麻烦。

这是我的文本区域和保存按钮:

<textarea v-model="selectedMeeting.content" ref="meetingContent"></textarea>
<button v-on:click="saveMeeting" v-bind:disabled="meetingSaved">
    {{ saveMeetingButton.saveText }}
</button>

在我的Vue应用中,我首先初始化我的数据:

data: {
    selectedMeeting: {},
    meetings: [],
    meetingSaved: true,
    saveMeetingButton: {saveText: 'Save Meeting', savedText: 'Saved', disabled: true},
},

创建后,我从服务器获取会议记录:

created() {
    axios.get('/ajax/meetings')
        .then(response => {
            this.meetings = response.data;
            this.selectedMeeting = this.meetings[0];
            this.meetingSaved = true;
        });
},

我有一种保存笔记的方法:

methods: {
    saveMeeting: function () {
        axios.post('/ajax/meetings/' + this.selectedMeeting.id, this.selectedMeeting)
            .then(function (response) {
                this.selectedMeeting = response.data;
                console.log('Now setting meetingSaved to true');
                this.meetingSaved = true;
                console.log('Done setting meetingSaved to true');
            });
    },
},

我有一个观察者,以防万一文本发生更改,可以立即保存该文本(我输入的每个字母都会保存,这当然需要更改,但这只是开始。

watch: {
    'selectedMeeting.content': function () {
        this.meetingSaved = false;
        console.log('Changed meeting ', new Date());
        this.saveMeeting();
    }
},

如果我现在输入字母,我会在日志中得到它:

Changed meeting  Tue Dec 04 2018 19:14:43 GMT+0100
Now setting meetingSaved to true
Done setting meetingSaved to true

日志符合预期,但是按钮本身从未禁用。如果删除观察者,则该按钮始终处于禁用状态。即使观察者首先将this.meetingSaved设置为false,然后this.saveMeeting()将其设置为true,添加观察者也不会以任何方式禁用该按钮。

有人知道我在做什么错吗?欢迎所有提示!

[编辑]

以下是整个页面的粘贴内容:https://pastebin.com/x4VZvbr5

2 个答案:

答案 0 :(得分:0)

您正在做的一些事情可能需要进行一些更改。

首先,data属性应该是返回对象的函数:

data() {
    return {
        selectedMeeting: {
            content: null
        },
        meetings: [],
        meetingSaved: true,
        saveMeetingButton: { 
            saveText: 'Save Meeting',
            savedText: 'Saved',
            disabled: true
        },
    };
}

这是为了使Vue可以将属性正确绑定到每个实例。

此外,content的{​​{1}}属性在初始渲染中不存在,因此Vue没有在该属性上添加适当的“包装器”以使事物知道它已更新。

顺便说一句,可以使用selectedMeeting

接下来,我建议您使用Vue.set来兑现您的诺言,因为它使遵循起来更加容易。

async/await

对于您的方法,我还将写为async / await。您还可以在单​​击时使用async created() { const response = await axios.get('/ajax/meetings'); this.meetings = response.data; this.selectedMeeting = this.meetings[0]; this.meetingSaved = true; }, 之类的Vue修饰符,以仅在没有先前请求的情况下调用api(请快速双击)。

once

其余的代码看起来还可以。

总而言之,主要问题是您没有在methods: { async saveMeeting () { const response = await axios.post('/ajax/meetings/' + this.selectedMeeting.id, this.selectedMeeting); this.selectedMeeting = response.data; console.log('Now setting meetingSaved to true'); this.meetingSaved = true; console.log('Done setting meetingSaved to true'); }, }, 函数中返回对象,并且它没有以反应方式绑定属性。

展望未来,您将需要data触发api调用并限制调用的文本输入。

答案 1 :(得分:0)

this.meetingSaved = true;

this引用axios对象。在调用之外引用vue对象,然后使用它。使用jQuery.ajax()时也会发生同样的情况。

created() {
    var vm = this;
    axios.get('/ajax/meetings')
        .then(response => {
            vm.meetings = response.data;
            vm.selectedMeeting = vm.meetings[0];
            vm.meetingSaved = true;
        });
},