gpt4 book ai didi

javascript - vue.js:HTML 元素显示-如果不切换更改

转载 作者:行者123 更新时间:2023-12-01 01:38:34 25 4
gpt4 key购买 nike

我最初通过 API 调用渲染一些对象到我的数据库,它们被序列化,最初看起来像这样:

<h3>Messages on Database</h3>
<p v-if="messages.length ===0">No Messages</p>
<div class="msg" v-for="(msg, index) in messages" :key="index">
<p class="msg-index">[{{index}}]</p>

<p class="msg-subject" v-html="msg.subject" v-if="!msg.editing"></p>
<p><input type="text" v-model="msg.subject" v-if="msg.editing" ></p>
<p>{{msg.editing}}</p>
<p class="msg-body" v-html="msg.body" v-show="!messages[index].editing"></p>
<p><input type="text" v-model="msg.body" v-show="messages[index].editing" ></p>

<input type="submit" @click="deleteMsg(msg.pk)" value="Delete" />
<input type="submit" @click="EditMsg(index)" value="Edit" />
<input type="submit" @click="updateMsg(msg.pk)" value="Update" />
</div>
</div>
</template>

<script>
export default {
name: "Messages",
data() {
return {
subject: "",
msgBody: "",
messages: [],
};

},

每条消息如下所示:

enter image description here

请注意,bodypksubject 是 Django 模型字段。数组中的每一项代表一个数据库对象。

我想要使用 vue.js 做的是允许用户编辑每个项目。如果用户单击某个项目的 edit 按钮,我想将其元素从 p 转换为 input,并将其提交到数据库。

为了允许编辑单个项目,我需要在数组中的每个项目中都有一个editing字段,所以我在我的mounted中执行此操作() 属性:

  mounted() {
this.fetchMessages();
},
methods: {
fetchMessages() {
this.$backend.$fetchMessages().then(responseData => {
this.messages = responseData;
this.messages.forEach(function (value) {
value['editing'] = false;
});
console.log(this.messages);
});
},

现在,当我在控制台中加载数组时,我会看到以下内容:

enter image description here

所以我假设现在,当用户单击Edit按钮时,EditMsg被调用,并且字段将根据v-if<进行转换/v-show 指令:

EditMsg(msgIdx) {
this.messages[msgIdx].editing = true;
console.log(this.messages);
},

但这并没有发生。实际发生的情况是这样的:在 console/vue-developer-tools 窗口中,项目的 editing 标志更改为 true,但 HTML 中没有任何变化。

我错过了什么?

完整代码:

<template>
<div class="hello">
<img src='@/assets/logo-django.png' style="width: 250px" />
<p>The data below is added/removed from the Postgres Database using Django's ORM and Restframork.</p>
<br/>
<p>Subject</p>
<input type="text" placeholder="Hello" v-model="subject">
<p>Message</p>
<input type="text" placeholder="From the other side" v-model="msgBody">
<br><br>
<input type="submit" value="Add" @click="postMessage" :disabled="!subject || !msgBody">

<hr/>
<h3>Messages on Database</h3>
<p v-if="messages.length ===0">No Messages</p>
<div class="msg" v-for="(msg, index) in messages" :key="index">
<p class="msg-index">[{{index}}]</p>

<p class="msg-subject" v-html="msg.subject" v-if="!msg.editing"></p>
<p><input type="text" v-model="msg.subject" v-if="msg.editing" ></p>
<p>{{msg.editing}}</p>
<p class="msg-body" v-html="msg.body" v-show="!messages[index].editing"></p>
<p><input type="text" v-model="msg.body" v-show="messages[index].editing" ></p>

<input type="submit" @click="deleteMsg(msg.pk)" value="Delete" />
<input type="submit" @click="EditMsg(index)" value="Edit" />
<input type="submit" @click="updateMsg(msg.pk)" value="Update" />
</div>
</div>
</template>

<script>
export default {
name: "Messages",
data() {
return {
subject: "",
msgBody: "",
messages: [],
};
},
mounted() {
this.fetchMessages();
},
methods: {
fetchMessages() {
this.$backend.$fetchMessages().then(responseData => {
this.messages = responseData;
this.messages.forEach(function (value) {
value['editing'] = false;
});
console.log(this.messages);
});
},
postMessage() {
const payload = { subject: this.subject, body: this.msgBody };
this.$backend.$postMessage(payload).then(() => {
this.msgBody = "";
this.subject = "";
this.fetchMessages();
});
},
deleteMsg(msgId) {
this.$backend.$deleteMessage(msgId).then(() => {
this.messages = this.messages.filter(m => m.pk !== msgId);
this.fetchMessages();
});
},
EditMsg(msgIdx) {
this.messages[msgIdx].editing = true;
console.log(this.messages);
},
updateMsg(msgId) {
console.log(this.subject, this.msgBody);
const payload = { subject: this.subject, body: this.msgBody };
this.$backend.$putMessage(msgId, payload).then(() => {
this.fetchMessages();
}
)
}
}
};
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
hr {
max-width: 65%;
}

.msg {
margin: 0 auto;
max-width: 30%;
text-align: left;
border-bottom: 1px solid #ccc;
padding: 1rem;
}

.msg-index {
color: #ccc;
font-size: 0.8rem;
/* margin-bottom: 0; */
}

img {
width: 250px;
padding-top: 50px;
padding-bottom: 50px;
}

</style>

最佳答案

根据Vue internals :

Vue observes data by converting properties with Object.defineProperty. However, in ECMAScript 5 there is no way to detect when a new property is added to an Object, or when a property is deleted from an Object.

因此,当您将响应数据绑定(bind)到 this.messages 时,Vue 不再将数组属性的任何突变视为 react 性的。

相反,如果您在将 responseData 属性绑定(bind)到 Vue 数据属性之前对其进行丰富,则所有数组都会保持响应式。我的意思是这样的:

fetchMessages() {
this.$backend.$fetchMessages().then(responseData => {
let editableMessages = responseData;
editableMessages.forEach(function (value) {
value['editing'] = false;
});
this.messages = editableMessages;
});
}

这里有一个small example基于您的域。

关于javascript - vue.js:HTML 元素显示-如果不切换更改,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52622907/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com