【问题标题】:How would I group together the messages I've sent on the right in blue and the messages I'm receiving on the left in yellow using flexbox and Vue.js?我如何使用 flexbox 和 Vue.js 将我在右侧发送的蓝色消息和我在左侧接收到的黄色消息组合在一起?
【发布时间】:2019-03-12 17:48:57
【问题描述】:

我已经创建了一个带有 vue 和 Laravel 后端的消息系统,我想将我的消息(Jim,我当前登录的人)在右侧分组为蓝色和 Debbie(我的用户) m 与)在左侧使用 flexbox 以黄色显示。喜欢 Facebook 或 Twitter:



模拟 JSON 输出

{
    "0": {
        "name": "Debbie",
        "message": "Good, Thinks for asking."
    },
    "1": {
        "name": "Jim",
        "message": "I'm good, how are you?"
    },
    "2": {
        "name": "Debbie",
        "message": "How are you?"
    },
    "3": {
        "name": "Jim",
        "message": "Hi Debbie"
    },
    "4": {
        "name": "Debbie",
        "message": "Hi Jim"
    }
}

我必须通过我的 JSON API 发送什么来从任何其他用户和他们的消息中识别自己?或者有没有一种方法可以做到这一点而无需更改 JSON 输出?

我将如何使用 flexbox 实现这个 into this messenger system that I've built?我正在使用的主要组件是会话消息组件:

Vue.component('conversation-messages',{
      template: '#conversation-messages',
      props: ['conversationId'],
      data: function() {
        return {
          messages: [],
          url: ''
        }
      },
      mounted() {
        console.log("message mounted")
        this.getOldMessages(this.conversationId);
      },
});

Here's a link to this question being answered only using css.

来自 CSS 链接,了解如何创建像 FB 这样的聊天气泡系统

使用浮动而非 Flexbox 的链接中的 HTML 结构示例

<ul>
 <li class="him">By Other User</li>
 <li class="me">By this User, first message</li>
 <li class="me">By this User, secondmessage</li>
 <li class="me">By this User, third message</li>
 <li class="me">By this User, fourth message</li>
</ul>

链接中答案的 CSS 示例

ul{
  list-style: none;
  margin: 0;
  padding: 0;
}

ul li{
  display:inline-block;
  clear: both;
  padding: 20px;
  border-radius: 30px;
  margin-bottom: 2px;
  font-family: Helvetica, Arial, sans-serif;
}

.him{
  background: #eee;
  float: left;
}

.me{
  float: right;
  background: #0084ff;
  color: #fff;
}

.him + .me{
  border-bottom-right-radius: 5px;
}

.me + .me{
  border-top-right-radius: 5px;
  border-bottom-right-radius: 5px;
}

.me:last-of-type {
  border-bottom-right-radius: 30px;
}

【问题讨论】:

    标签: javascript css vue.js vuejs2 flexbox


    【解决方案1】:

    您可以将名为 msgs 的类分配给包装您的消息的 div,该类由以下规则定义:

    标签:

     <div v-for="message in messages" class="msgs">
    

    风格:

     .msgs{
          display:flex;
          flex-direction:column;
          align-items:center;
          justify-content:space-between;
       }
    

    对于每条消息,您应该检测它是否是您的。如果是,则在末尾对齐,否则通过绑定类并使用 v-ifv-else 之类的方式在开头对齐:

        <div class="p-4 border-b"  v-if='message.name=="Jim"' :class="{me:message.name='Jim'}">
          <p>{{message.message}}</p>
        </div>
        <div class="p-4 border-b" v-else :class="{him:true}">
          <p>{{message.message}}</p>
        </div>    
    

    您可以使用名为itSMe 的数据对象属性来检测连接的用户消息,而不是message.name=="Jim"

    Vue.component('conversations',{
          template: '#conversations',
          data: function(){
            return{
              showConversation: false,
              conversationId: null
            }
          },
    
          methods: {
             getConversation(conversation_id){
               this.conversationId = conversation_id
               this.showConversation = true
               console.log(this.conversationId)
            }
          },
    });
    
    Vue.component('converstations-list',{
          template: '#conversations-list',
          data: function() {
            return {
              conversations: [
                {id: 1, name: "Conversation with Debbie"},
                {id: 2, name: "Conversation with Steve"},
                {id: 3, name: "Conversation with Martin"},
              ]
            }
          },
    
          methods: {
            getConversation(conversation_id){
              this.$emit('open-conversation', conversation_id);
            }
          },
    });
    
    Vue.component('conversation-messages',{
          template: '#conversation-messages',
          props: ['conversationId'],
          data: function() {
            return {
              messages: [],
              url: ''
            }
          },
          mounted() {
            console.log("message mounted")
            this.getOldMessages(this.conversationId);
          },
          methods: {
            getOldMessages(conversation_id){
                  
                  //This will be replaced with backend conversation_id routes
                  if(conversation_id === 1){
                    this.url = 'https://codepen.io/Corbin/pen/YJppoL.js';
                  }else if(conversation_id === 2) {
                    this.url = 'https://codepen.io/Corbin/pen/EdNZjX.js';
                  }else if(conversation_id === 3) {
                    this.url = 'https://codepen.io/Corbin/pen/LgbxGd.js';
                  }
                    
                  setTimeout(function() {
                  axios({
                      method: 'get',
                      url: this.url,
                  }).then(function(response) {
                      //console.log(response.data);
    
                      this.messages = response.data;
                  }.bind(this))
                  .catch(function(error) {
                      
                  });
              }.bind(this))
          },
          }
    });
    
    new Vue({
      el: '#app',
    });
    .border-b{
    padding:0 10px;
    }
    .msgs{
      
      display:flex;
      flex-direction:column;
      align-items:center;
      justify-content:space-between;
    }
    .me{
      align-self:flex-end;
      background: #0084ff;
      color: #fff;
    }
    
    .him{
      align-self:flex-start;
      background: #eee;
      float: left;
      border-radius: 20px 20px 20px 0;
    }
    
    
    
    
    .me {
      border-radius: 20px 0px 20px 20px;
    }
    <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.13/vue.min.js"></script>
    <script src="https://unpkg.com/axios/dist/axios.min.js"></script>
    <link href="https://fonts.googleapis.com/icon?family=Material+Icons"
          rel="stylesheet">
    
    <!-- Conversations -->
    <script type="x/template" id="conversations">
      <div>
        <div class="flex w-full border-b">
           <button v-show="showConversation" class="pl-4 font-bold rounded" @click="showConversation = false" ><i class="material-icons">
            arrow_back_ios
           </i></button>
           <h1 class="py-4  text-center w-full" v-if="showConversation == false">All Conversations</h1>
           <h1 class="py-4 text-center w-full" v-if="showConversation">Conversation With</h1>
        </div>
        <converstations-list v-if="showConversation == false" v-on:open-conversation="getConversation($event)"></converstations-list>
        <conversation-messages :conversation-id="conversationId" v-if="showConversation"></conversation-messages>
      </div>
    </script>
    
    <!--Conversations List -->
    <script type="x/template" id="conversations-list">
      <div>
        <div v-for="conversation in conversations">
          <h3 @click="getConversation( conversation.id)" class="cursor-pointer border-b p-4 hover:bg-blue">{{conversation.name}}</h3>
        </div>
      </div>
    </script>
    
    <!--Conversations Messages -->
    <script type="x/template" id="conversation-messages">
      <div> 
          <div v-for="message in messages" class="msgs">
            <div class="p-4 border-b"  v-if='message.name=="Jim"' :class="{me:message.name='Jim'}">
            
              <p>{{message.message}}</p>
            </div>
         <div class="p-4 border-b" v-else :class="{him:true}">
             
              <p>{{message.message}}</p>
            </div>
          </div>
      </div>
    </script>
    
    <div id="app">
    
      <conversations></conversations>
    
    </div>

    【讨论】:

      猜你喜欢
      • 2018-09-27
      • 1970-01-01
      • 2018-07-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-07-11
      • 1970-01-01
      • 2016-05-11
      相关资源
      最近更新 更多