代码之家  ›  专栏  ›  技术社区  ›  zerohedge

vue.js:html元素显示是否切换更改

  •  0
  • zerohedge  · 技术社区  · 6 年前

    我最初是从对数据库的API调用中呈现一些对象,它们是序列化的,最初看起来像这样:

    数据库上的消息 <p v-if=“messages.length==0”>无消息</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=“!消息编辑“></p> <p><input type=“text”v-model=“msg.subject”v-if=“msg.editing”></p> <p>消息.编辑</p> <p class=“msg body”v-html=“msg.body”v-show=“!消息[索引]。编辑“></p>” <p><input type=“text”v-model=“msg.body”v-show=“messages[index].编辑“></p> <input type=“submit”@click=“deleteMsg(msg.pk)”value=“删除”/> <input type=“submit”@单击“editmsg(index)”value=“edit”/> <input type=“submit”@click=“updateMsg(msg.pk)”value=“更新”/> &L/DIV & GT; &L/DIV & GT; </template> 脚本& GT; 导出默认值{ 名称:“消息”, 数据() 返回{ 主题:“ MsgBoo:“ 消息: }; < /代码>

    },

    每条消息如下所示:

    请注意, body , pk and subject are the django model fields.数组中的每个项都表示一个数据库对象。

    我想用vue.js做的是允许用户编辑每个项目。如果用户单击某个项目的“编辑”按钮,我想将其元素从“编辑”按钮转换为“输入”,然后将其提交到数据库。

    为了允许编辑 单个的项目,我需要数组中每个项目中的 editing field,因此我在my mounted()中执行此操作。 property:。

    mounted()。{
    this.fetchmessages();
    }
    方法:{
    fetchmessages()。{
    此。$backend.$fetchmessages()。然后(responsedata=>){
    this.messages=响应数据;
    this.messages.foreach(函数(值){
    值['编辑']=false;
    (});
    console.log(this.messages);
    (});
    }
    < /代码> 
    
    

    现在,当我在控制台中加载数组时,我看到了:

    因此,我假设现在,当用户单击edit>button时,editmsgis called,and the fields will transform according to thev-if/v-showdirectives:。

    editmsg(msgidx){
    this.messages[msgidx].编辑=真;
    console.log(this.messages);
    }
    < /代码> 
    
    

    但这不会发生。实际发生的是:在控制台/Vue开发人员工具窗口中,该项的editing标志更改为true

    我错过了什么?

    完整代码:

    <template>
    <div class=“hello”>
    <img src='@/assets/logo django.png'style=“width:250px”/>
    <p>下面的数据是使用Django的ORM和Restframork从Postgres数据库中添加/删除的。</p>
    & BR/>
    <P>主题</P>
    <input type=“text”placeholder=“hello”v-model=“subject”>
    <P>消息</P>
    <input type=“text”placeholder=“from the other side”v-model=“msgBody”>
    <br><br>
    <input type=“submit”value=“add”@click=“postmessage”:disabled=“!主题>“MSGBORD”& GT;
    
    & HR/GT;
    <H3>数据库上的消息</H3>
    <p v-if=“messages.length==0”>无消息</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=“!消息编辑“></p>
    <p><input type=“text”v-model=“msg.subject”v-if=“msg.editing”></p>
    <p>消息.编辑</p>
    <p class=“msg body”v-html=“msg.body”v-show=“!消息[索引]。编辑“></p>”
    <p><input type=“text”v-model=“msg.body”v-show=“messages[index].编辑“></p>
    
    <input type=“submit”@click=“deleteMsg(msg.pk)”value=“删除”/>
    <input type=“submit”@单击“editmsg(index)”value=“edit”/>
    <input type=“submit”@click=“updateMsg(msg.pk)”value=“更新”/>
    &L/DIV & GT;
    &L/DIV & GT;
    </template>
    
    脚本& GT;
    导出默认值{
    名称:“消息”,
    数据()
    返回{
    主题:“
    MsgBoo:“
    消息:
    };
    }
    安装(){
    this.fetchmessages();
    }
    方法:{
    fetchmessages()。{
    此。$backend.$fetchmessages()。然后(responsedata=>){
    this.messages=响应数据;
    this.messages.foreach(函数(值){
    值['编辑']=false;
    (});
    console.log(this.messages);
    (});
    }
    邮政消息()
    const payload=主题:this.subject,主体:this.msgBody_
    此。$backend.$postmessage(有效负载)。然后(()=>){
    this.msgbody=“”;
    this.subject=“”;
    this.fetchmessages();
    (});
    }
    删除消息(msgid){
    此。$backend.$deleteMessage(msgid)。然后(()=>){
    this.messages=this.messages.filter(m=>m.pk!)= MSGID);
    this.fetchmessages();
    (});
    }
    编辑消息(msgidx){
    this.messages[msgidx].编辑=真;
    console.log(this.messages);
    }
    更新消息(msgid){
    console.log(this.subject,this.msgbody);
    const payload=主题:this.subject,主体:this.msgBody_
    此。$backend.$putmessage(msgid,有效负载)。然后(()=>){
    this.fetchmessages();
    }
    )
    }
    }
    };
    & /脚本& GT;
    
    &!--添加“scoped”属性以将CSS仅限于此组件-->
    <样式范围
    HR
    最大宽度:65%;
    }
    
    MSG {
    保证金:0自动;
    最大宽度:30%;
    文本对齐:左对齐;
    边框底部:1px实心CCC;
    填料:1雷姆;
    }
    
    MSG索引{
    颜色:
    字体大小:0.8rem;
    /*下边距:0;。*/
    }
    
    IMG{
    宽度:250px;
    填充顶部:50px;
    垫底:50px;
    }
    
    &风格/风格;
    < /代码> <

    }

    每条消息如下:

    enter image description here

    注意到body,pksubject是Django模型字段。数组中的每个项表示一个数据库对象。

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

    以便编辑个人物品,我需要一个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);
        },
    

    但这不会发生。实际发生的情况是:编辑项的标志更改为true在console/vue开发人员工具窗口中,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>
    
    1 回复  |  直到 6 年前
        1
  •  2
  •   P3trur0    6 年前

    根据 Vue internals :

    Vue通过转换属性来观察数据 Object.defineProperty . 但是,在EcmaScript 5中,无法检测何时将新属性添加到对象,或何时从对象中删除属性。

    因此,当您将响应数据绑定到 this.messages 任何对数组属性的突变都不再被Vue认为是反应性的。

    相反,如果你丰富 responseData 属性在将其绑定到Vue数据属性之前,所有数组都保持被动。我的意思是这样:

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

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