Javascript 为什么';t Vuejs寄存器是否启用或禁用我的按钮?
我正在创建一个简单的Vuejs网站,您可以在其中编写会议记录。加载后,它会从服务器上获取会议记录并显示它们。然后,当用户写入内容时,他可以单击“保存”按钮,将文本保存到服务器。将注释保存到服务器时,需要禁用“保存”按钮,并显示一条文字“保存”。当用户再次开始写入文本时,应再次启用按钮并再次显示“保存”。这是一个相当基本的功能,我想说,但我有麻烦 这是我的文本区和保存按钮:Javascript 为什么';t Vuejs寄存器是否启用或禁用我的按钮?,javascript,vue.js,Javascript,Vue.js,我正在创建一个简单的Vuejs网站,您可以在其中编写会议记录。加载后,它会从服务器上获取会议记录并显示它们。然后,当用户写入内容时,他可以单击“保存”按钮,将文本保存到服务器。将注释保存到服务器时,需要禁用“保存”按钮,并显示一条文字“保存”。当用户再次开始写入文本时,应再次启用按钮并再次显示“保存”。这是一个相当基本的功能,我想说,但我有麻烦 这是我的文本区和保存按钮: <textarea v-model="selectedMeeting.content" ref="meetingCon
<textarea v-model="selectedMeeting.content" ref="meetingContent"></textarea>
<button v-on:click="saveMeeting" v-bind:disabled="meetingSaved">
{{ saveMeetingButton.saveText }}
</button>
创建后,我从服务器获取会议记录:
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.meeting保存的设置为false
,然后将this.saveMeeting()设置为
将其设置为true
,添加观察者不会以某种方式禁用按钮
有人知道我做错了什么吗?欢迎提供所有提示
[编辑]
这里是整个页面的粘贴:您有一些事情需要改变
首先,data
属性应该是一个返回对象的函数:
data() {
return {
selectedMeeting: {
content: null
},
meetings: [],
meetingSaved: true,
saveMeetingButton: {
saveText: 'Save Meeting',
savedText: 'Saved',
disabled: true
},
};
}
这样Vue就可以将属性正确绑定到每个实例
另外,selectedMeeting
的content
属性在初始渲染中不存在,因此Vue没有在属性上添加适当的“包装器”以让内容知道它已更新
另一方面,可以使用Vue.set
接下来,我建议您使用async/await
作为您的承诺,因为这样更容易遵守
async created() {
const response = await axios.get('/ajax/meetings');
this.meetings = response.data;
this.selectedMeeting = this.meetings[0];
this.meetingSaved = true;
},
对于您的方法,我还将编写为async/await。您还可以使用Vue修饰符,如单击时使用once
on click,仅在之前没有请求的情况下调用api(考虑快速双击)
代码的其余部分看起来没问题
总结一下,主要问题是在data
函数中没有返回对象,并且没有反应性地绑定属性
接下来,您将希望对触发api调用的文本输入进行debounce
,并限制调用
this.meetingSaved = true;
此
引用的是axios
对象。在调用外部引用vue对象,然后使用它。使用jQuery.ajax()时也会发生同样的情况
在您的watcher中,您正在调用this.saveMeeting()
,这意味着您每次在文本区域键入字符时都将保存和禁用该按钮。这是您想要的吗?顺便说一句,这里有一个codesandbox,显示您可以启用和禁用该按钮:您能检查控制台中是否有任何错误吗?如果在渲染过程中有任何错误,这将意味着它不会提供错误n更新DOM,使其看起来好像什么都没有发生。我的最佳选择是为'this.selectedMeeting'分配一个未定义的值。感谢您的建议。不幸的是,按照您的建议将数据更改为函数并不能解决我的问题。我在问题中添加了整个页面的粘贴。这里也是:没有你有什么新的想法可以告诉你问题是什么?你的pastebin没有数据功能,而且我认为你可能想在$nextTick调用中包装承诺,这样api调用就不会阻塞UI。你可能禁用了按钮,但在UI重新绑定之前它又被启用了。问题是axios响应中的函数e、 这肯定是错误的。我建议使用async/await来避免“回调”地狱或者如果你不想,Artur的答案会起作用。我知道,我还原了它,因为它没有解决任何问题。所以这显然不是问题。@kramer65你仍然应该这样做,这对Vue很重要。很好的捕捉,我在我的答案中错过了这一点,因为我将它切换为异步。
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');
},
},
this.meetingSaved = true;
created() {
var vm = this;
axios.get('/ajax/meetings')
.then(response => {
vm.meetings = response.data;
vm.selectedMeeting = vm.meetings[0];
vm.meetingSaved = true;
});
},