GitHub:https://github.com/baiyuliang/Qrobot_Vue

The layout looks something like this:

We need to define at least three components: 1. Main interface component: chat.vue 2. 3. Right dialog box Item component: rightitem.vue

Maybe some students think that this simple small project does not need routing, so there is no need to define so many components, directly in app.vue can be all done! This is true, but doing so makes the project less readable, and it comes across as rude, not elegant!

Chat. Vue:

<template>
    <div class="container">
        <div class="list" id="list" ref="list" >
            <ul>
                <li v-for="(item,index) in msglist" :key="index">
                    <RightItem :id="item.id" :type="item.type" :content="item.content" v-if="item.me"></RightItem>
                    <LeftItem :id="item.id" :type="item.type" :content="item.content" v-else></LeftItem>
                </li>
            </ul>
        </div>
        <div class="bottom">
            <div class="line"></div>
            <div class="input-send">
                <van-field v-model="text" placeholder="Please enter the chat content..." class="input" @keyup.enter="send"/>
                <van-button plain type="info" class="send" @click="send">send</van-button>
            </div>

        </div>

    </div>
</template>

<style scoped lang="scss">
    .container {
        ul {
            padding: 0;
            margin: 0;
        }

        li {
            list-style: none;

        }

        .list {
            width: 100%;
            height: 100%;
            margin-bottom: 45px;
        }

        .bottom {
            width: 100%;
            position: fixed;
            bottom: 0;

            .line {
                width: 100%;
                height: 1px;
                background-color: #ddd;
            }

            .input-send {
                display: flex;
                justify-content: space-between;
                background-color: #fff;

                .input {
                    padding-right: 10px;
                }

                .send {
                    width: 80px;
                    height: 30px;
                    margin-top: 7px;
                    margin-right: 10px; }}}}</style>
Copy the code

Very simple, top Li, bottom input box!

LeftItem.vue:

<template>
    <div class="container">
        <img class="head" src="https://pp.myapp.com/ma_icon/0/icon_42284557_1517984341/96"/>

        <div class="content">
            <div class="text" v-if="type===1">
                {{content}}
            </div>
            <img class="img" :src="content" v-else-if="type===2" @click="preview(content)"/>
        </div>

    </div>
</template>

<script>
    import ImagePreview from "vant/lib/image-preview";

    export default {
        name: "LeftItem".props: ['id'.'type'.'content'].methods: {
            preview(url){
                ImagePreview([url])
            }
        }
    }
</script>

<style scoped lang="scss">
    .container {
        display: flex;
        padding: 10px 15px;
        margin-right: 60px;


        .head {
            width: 40px;
            height: 40px;
            border-radius: 50%;
            border: 1px solid #eee;
        }

        .content {
            margin-left: 10px;
            margin-top: 10px;

            .text {
                background-color: deepskyblue;
                border-bottom-right-radius: 10px;
                padding: 5px 5px;
                font-size: 14px;
                color: #fff;
            }

            .img {
                width: 100px;
                border-bottom-right-radius: 10px;
                border-top-right-radius: 10px;
                border-bottom-left-radius: 10px; }}}</style>
Copy the code

Node-sass and sass-loader plug-ins need to be installed when SCSS style syntax is selected:

npm i node-sass sass-loader -D
Copy the code

Flex is used as the main layout method. The default value of Flex-direction is row, horizontal and left as the baseline. Some students may want to use float or position for layout. Therefore, avoid both layouts!

In addition, this component uses custom properties:

 props: ['id'.'type'.'content']
Copy the code

Type for the message types: one word, 2 as the picture, the content is text or image links, when v – if = “type = = = 1” shows the text content, when v – else – if = “type = = = 2” display picture content!

When using this component:

<LeftItem :id="item.id" :type="item.type" :content="item.content"></LeftItem>
Copy the code

“” Indispensable!

RightItem.vue:

<template>
    <div class="container">
        <img class="head"
             src="Https://dss0.bdstatic.com/70cFuHSh_Q1YnxGkpoWK1HF6hhy/it/u=1068485212, & FM = 111 & 3292662520 gp = 0. JPG"/>
        <div class="content">
            <div class="text" v-if="type===1" style="word-break: break-all;">
                {{content}}
            </div>
            <img class="img" :src="content" v-else-if="type===2"/>
        </div>
    </div>
</template>

<script>

    export default {
        name: "RightItem".props: ['id'.'type'.'content']}</script>

<style scoped lang="scss">
    .container {
        display: flex;
        padding: 10px 15px;
        margin-left: 60px;
        flex-direction: row-reverse;

        .head {
            width: 40px;
            height: 40px;
            border-radius: 50%;
            border: 1px solid #eee;
        }

        .content {
            margin-right: 10px;
            margin-top: 10px;

            .text {
                background-color: #eee;
                border-bottom-left-radius: 10px;
                padding: 5px 5px;
                font-size: 14px;
                color: # 000;
            }

            .img {
                width: 100px;
                border-bottom-right-radius: 10px;
                border-top-right-radius: 10px;
                border-bottom-left-radius: 10px; }}}</style>
Copy the code

LeftItem is not different from LeftItem, except that flex-direction is row-reverse, which means that horizontal axis is aligned to the right.

HelloWorld. Vue in App:

<template>
    <div id="app">
        <Chat></Chat>
    </div>
</template>

<script>
    import Chat from './components/Chat.vue'

    export default {
        name: 'App'.components: {
            Chat
        }
    }
</script>

<style scoped>
  
</style>

Copy the code

You can then fake some data in data to see the effect:

 msglist: [{
            id: 1.type: 1.content: 'Welcome! '.me: false},... ]Copy the code

Everything is ready only owe dongfeng, the next access to the interface data, you can complete the project!