美文网首页
基于vue3+Naive UI开发网页聊天页面

基于vue3+Naive UI开发网页聊天页面

作者: bobokaka | 来源:发表于2023-07-14 16:35 被阅读0次

页面设计如下:


67d40005daa8ebb46e73d6f590382a3.jpg

开发思路

从大到小,组件封装
从死数据到灵活适配
从简单到特殊,由面到点

整体架构

首先分块,再填充内容


image.png

先分为2个块,上面标签下面内容。
再下面内容分为3 大块,结构如上。
因为左侧聊天框和右侧可能以后要扩展拖动功能,所以这里不用Layout布局,通过DIV盒子实现,方便后面调整
(到目前为止不会一个拖动自动变化大小的技巧怎么实现)。

main.js

import { createApp } from 'vue'
import './style.css'
// @ts-ignore
import App from "./App.vue";
/** ssss
 * 项目初始化css
 */
import './styles/index.scss'
import NaiveUi from "naive-ui";
/**
 * 初始化Element Plus的icon图标
 */
const app = createApp(App)
app.use(NaiveUi)
app.mount('#app')

所以我这里新建2个组件。
src/App.vue

<template>
  <div class="bs-wrapper">
    <div class="main">
      <div class="main__title">
        <TabsTitle/>
      </div>
      <div class="main__content">
        <Chat/>
      </div>
    </div>
  </div>
</template>

<script setup lang="ts">
import Chat from "./components/Chat/index.vue"
import TabsTitle from "./components/TabsTitle/index.vue"
</script>
<style lang="scss" scoped>

// 1rem===100px
.bs-wrapper {
  width: 100%;
  height: 100%;
  display: flex;
  justify-content: center;
  //align-items: center;

  .main {
    //text-align: center;
    //clamp:最小值、首选值、最大值
    //width: clamp(2rem, calc(100vw - 3rem), 100vw);
    //height: clamp(2rem, calc(100vh - 3rem), 100vh);
    width: calc(100vw - 3rem);
    height: calc(100vh - 3rem);
    background: #0091ff;
    &__title {
      width: 100%;
      height: 0.8rem;
      background: #0bff00;
    }

    &__content {
      width: 100%;
      height: 100%;
    }
  }
}
</style>

src/components/Chat/index.vue

<template>
  <div class="wrapper__chat">
    <div class="chat__left-people">
    </div>
    <div class="chat__content">
      <div class="chat__content__info">
      </div>
      <div class="chat__content__input">
      </div>
    </div>
  </div>
</template>

<script setup lang="ts">
import LeftLinkMan from "./module/LeftLinkMan/index.vue";
import ShowChatInfo from "./module/ShowChatInfo/index.vue";
import Chat from "@com/TabsTitle/index.vue";
</script>
<style lang="scss" scoped>
.wrapper__chat {
  width: 100%;
  height: 100%;
  display: flex;
  justify-content: center;

  .chat {
    &__left-people {
      flex: 1;
      height: 100%;
      background: #ff4c4c;
    }

    &__content {
      flex: 5;
      height: 100%;
      background: #fff12b;
      display: flex;
      flex-direction: column;

      &__info {
        flex: 5;
        height: 100%;
        background: #40f0ff;
      }

      &__input {
        flex: 2;
        height: 100%;
        background: #f89751;
      }
    }


  }
}
</style>
image.png

顶部Title开发

同样分为3个区域:logo,菜单,右侧按钮


image.png

src/components/TabsTitle/index.vue

<template>
  <div class="wrapper__tabs-title">
    <div class="tabs-title__left"></div>
    <div class="tabs-title__right"></div>
  </div>
</template>

<script setup lang="ts">

</script>
<style lang="scss" scoped>
.wrapper__tabs-title {
  width: 100%;
  height: 100%;
  display: flex;
  justify-content: center;
  background: #535bf2;

  .tabs-title {
    &__left {
      flex: 5;
      width: 100%;
      height: 100%;
      background: #eee222;
    }

    &__right {
      flex: 3;
      width: 100%;
      height: 100%;
      background: #d876de;
    }
  }
}
</style>

image.png

完善按钮:

<template>
  <div class="wrapper__tabs-title">
    <div class="tabs-title__left">

    </div>
    <div class="tabs-title__middle">
      <template v-for="item in btnList" :key="item.code">
        <div class="tabs-btn">{{ item.name }}</div>
      </template>
    </div>
    <div class="tabs-title__right"></div>
  </div>
</template>

<script setup lang="ts">
import {ref} from "vue";

interface TypeTitleTabsMenu {
  code: string,
  name: string
}

const btnList = ref<Array<TypeTitleTabsMenu>>([
  {code: "1", name: "艺术画展"},
  {code: "2", name: "绘画中学"},
  {code: "3", name: "助手中心"}
])
</script>
<style lang="scss" scoped>
.wrapper__tabs-title {
  width: 100%;
  height: 100%;
  display: flex;
  justify-content: center;
  background: #535bf2;

  .tabs-title {
    &__left {
      flex: 1;
      width: 100%;
      height: 100%;
      background: #eee222;
      text-align: left;
    }

    &__middle {
      flex: 6;
      width: 100%;
      height: 100%;
      background: #efa18b;
      text-align: left;
      display: flex;
      align-items: center;

      .tabs-btn {
        font-size: 0.2rem;
        font-weight: 550;
        display: inline-block;
        padding: 0.05rem;
        margin: 0 0.4rem;
        background: #0bff00;
      }
    }

    &__right {
      flex: 1;
      width: 100%;
      height: 100%;
      background: #d876de;
      text-align: right;
    }
  }
}
</style>
image.png

完善logo和,数字积分按钮。

<template>
  <div class="wrapper__tabs-title">
    <div class="tabs-title__left">
      <!--logo在实际业务中一般是图片-->
      <img src="src/assets/logo.png" alt="logo"/>
    </div>
    <div class="tabs-title__middle">
      <template v-for="item in btnList" :key="item.code">
        <div class="tabs-btn">{{ item.name }}</div>
      </template>
    </div>
    <div class="tabs-title__right">
      <div class="btn-score">
        <div class="btn-score__text">数字积分</div>
        <div class="btn-score__image">]
        </div>
      </div>
    </div>
  </div>
</template>

<script setup lang="ts">
import {ref} from "vue";

interface TypeTitleTabsMenu {
  code: string,
  name: string
}

const btnList = ref<Array<TypeTitleTabsMenu>>([
  {code: "1", name: "艺术画展"},
  {code: "2", name: "绘画中学"},
  {code: "3", name: "助手中心"}
])
</script>
<style lang="scss" scoped>
.wrapper__tabs-title {
  width: 100%;
  height: 100%;
  display: flex;
  justify-content: center;
  background: #535bf2;

  .tabs-title {
    &__left {
      flex: 1;
      width: 100%;
      height: 100%;
      background: #eee222;
      display: flex;
      align-items: center;
      justify-content: center;
      margin: 0 0.12rem;
    }

    &__middle {
      flex: 6;
      width: 100%;
      height: 100%;
      background: #efa18b;
      text-align: left;
      display: flex;
      align-items: center;

      .tabs-btn {
        font-size: 0.2rem;
        font-weight: 550;
        display: inline-block;
        padding: 0.05rem;
        margin: 0 0.4rem;
        background: #0bff00;
      }
    }

    &__right {
      flex: 1;
      width: 100%;
      height: 100%;
      background: #d876de;
      text-align: right;
      display: flex;
      align-items: center;
      justify-content: center;

      .btn-score {
        border: 0.01rem solid #6C6D6F;
        border-radius: 0.4rem;
        display: flex;
        align-items: center;
        padding: 0.03rem 0.112rem;
        &__text {
          display: inline-block;
          text-align: left;
          color: #6C6D6F;
        }

        &__image {
          margin-left: 0.08rem;
          display: inline-block;
          width: 0.2rem;
          height: 0.2rem;
          border-radius: 50%;
          object-fit: cover;
          background-color: #0bff00;
        }
      }
    }
  }
}
</style>
image.png

完善图片

<template>
  <div class="wrapper__tabs-title">
    <div class="tabs-title__left">
      <!--logo在实际业务中一般是图片-->
      <img src="src/assets/logo.png" alt="logo"/>
    </div>
    <div class="tabs-title__middle">
      <template v-for="item in btnList" :key="item.code">
        <div class="tabs-btn">{{ item.name }}</div>
      </template>
    </div>
    <div class="tabs-title__right">
      <div class="btn-score">
        <div class="btn-score__text">数字积分</div>
        <div class="btn-score__image">
          <img style="width: 100%;height: 100%" src="src/assets/vue.svg" alt="数字积分"/>
        </div>
      </div>
    </div>
  </div>
</template>

<script setup lang="ts">
import {ref} from "vue";

interface TypeTitleTabsMenu {
  code: string,
  name: string
}

const btnList = ref<Array<TypeTitleTabsMenu>>([
  {code: "1", name: "艺术画展"},
  {code: "2", name: "绘画中学"},
  {code: "3", name: "助手中心"}
])
</script>
<style lang="scss" scoped>
.wrapper__tabs-title {
  width: 100%;
  height: 100%;
  display: flex;
  justify-content: center;
  background: #535bf2;

  .tabs-title {
    &__left {
      flex: 1;
      width: 100%;
      height: 100%;
      background: #eee222;
      display: flex;
      align-items: center;
      justify-content: center;
      margin: 0 0.12rem;
    }

    &__middle {
      flex: 6;
      width: 100%;
      height: 100%;
      background: #efa18b;
      text-align: left;
      display: flex;
      align-items: center;

      .tabs-btn {
        font-size: 0.2rem;
        font-weight: 550;
        display: inline-block;
        padding: 0.05rem;
        margin: 0 0.4rem;
      }
    }

    &__right {
      flex: 1;
      width: 100%;
      height: 100%;
      background: #d876de;
      text-align: right;
      display: flex;
      align-items: center;
      justify-content: center;

      .btn-score {
        border: 0.01rem solid #6C6D6F;
        border-radius: 0.4rem;
        display: flex;
        align-items: center;
        padding: 0.03rem 0.112rem;

        &__text {
          display: inline-block;
          text-align: left;
          color: #6C6D6F;
        }

        &__image {
          margin-left: 0.08rem;
          display: inline-block;
          width: 0.2rem;
          height: 0.2rem;
          border-radius: 50%;
        }
      }
    }
  }
}
</style>
image.png

调整背景色,去掉标识颜色:

<template>
  <div class="wrapper__tabs-title">
    <div class="tabs-title__left">
      <!--logo在实际业务中一般是图片-->
      <img src="src/assets/logo.png" alt="logo"/>
    </div>
    <div class="tabs-title__middle">
      <template v-for="item in btnList" :key="item.code">
        <div class="tabs-btn">{{ item.name }}</div>
      </template>
    </div>
    <div class="tabs-title__right">
      <div class="btn-score">
        <div class="btn-score__text">数字积分</div>
        <div class="btn-score__image">
          <img style="width: 100%;height: 100%" src="src/assets/vue.svg" alt="数字积分"/>
        </div>
      </div>
    </div>
  </div>
</template>

<script setup lang="ts">
import {ref} from "vue";

interface TypeTitleTabsMenu {
  code: string,
  name: string
}

const btnList = ref<Array<TypeTitleTabsMenu>>([
  {code: "1", name: "艺术画展"},
  {code: "2", name: "绘画中学"},
  {code: "3", name: "助手中心"}
])
</script>
<style lang="scss" scoped>
.wrapper__tabs-title {
  width: 100%;
  height: 100%;
  display: flex;
  justify-content: center;
  background-image: linear-gradient(to right,#0D0D0D, #17181A, #18191B, #0D0D0D);

  .tabs-title {
    &__left {
      flex: 1;
      width: 100%;
      height: 100%;
      display: flex;
      align-items: center;
      justify-content: center;
      margin: 0 0.12rem;
    }

    &__middle {
      flex: 6;
      width: 100%;
      height: 100%;
      text-align: left;
      display: flex;
      align-items: center;

      .tabs-btn {
        color: #F9FAFC;
        font-size: 0.2rem;
        font-weight: 550;
        display: inline-block;
        padding: 0.05rem;
        margin: 0 0.4rem;
      }
    }

    &__right {
      flex: 1;
      width: 100%;
      height: 100%;
      text-align: right;
      display: flex;
      align-items: center;
      justify-content: center;

      .btn-score {
        border: 0.01rem solid #F9FAFC;
        border-radius: 0.4rem;
        display: flex;
        align-items: center;
        padding: 0.03rem 0.112rem;

        &__text {
          display: inline-block;
          text-align: left;
          color: #F9FAFC;
        }

        &__image {
          margin-left: 0.08rem;
          display: inline-block;
          width: 0.16rem;
          height: 0.16rem;
          border-radius: 50%;
        }
      }
    }
  }
}
</style>
image.png

调整主页面
src/App.vue

<template>
  <div class="bs-wrapper">
    <div class="main">
      <div class="main__title">
        <TabsTitle/>
      </div>
      <div class="main__content">
        <Chat/>
      </div>
    </div>
  </div>
</template>

<script setup lang="ts">
import Chat from "./components/Chat/index.vue"
import TabsTitle from "./components/TabsTitle/index.vue"
</script>
<style lang="scss" scoped>
@import "/src/styles/viriables";
// 1rem===100px
.bs-wrapper {
  width: $window-width;
  height: $window-height;
  display: flex;
  justify-content: center;
  background-color: #0D0D0D;

  .main {
    width: 100%;
    height: 100%;
    background: #0091ff;

    &__title {
      width: 100%;
      height: $title-height;
    }

    &__content {
      width: 100%;
      height: 100%;
    }
  }
}
</style>
image.png

这里将一些公共scss抽出去:
src/styles/viriables.scss

$title-height: 0.8rem;
$window-width:14rem;
$window-height:7rem;
$content-height: calc($window-height - $title-height);

聊天联系人列表

src/components/Chat/index.vue

<template>
  <div class="wrapper__chat">
    <div class="chat__left-people">
      <LeftLinkMan/>
    </div>
    <div class="chat__content">
      <div class="chat__content__info">
      </div>
      <div class="chat__content__input">
      </div>
    </div>
  </div>
</template>

src/components/Chat/module/LeftLinkMan/index.vue

<template>
  <div  class="wrapper__list-link-man">TabsTitle</div>
</template>

<script setup lang="ts">

</script>
<style lang="scss" scoped>
.wrapper__list-link-man{
  width: 100%;
  height: 100%;
}
</style>
image.png

进一步完善:

<template>
  <div class="wrapper__list-link-man">
    <n-tabs v-model="formData.active" type="line" justify-content="space-evenly" animated>
      <n-tab-pane name="myChat" tab="我的聊天">
      </n-tab-pane>
      <n-tab-pane name="MyAssisted" tab="我协助的">
      </n-tab-pane>
    </n-tabs>
    <ListLinkMan v-if="formData.active==='myChat'"/>

  </div>
</template>

<script setup lang="ts">
import ListLinkMan from "./module/ListLinkMan/index.vue";
import {ref} from "vue";

const formData = ref<any>({
  active: "myChat"
})
</script>
<style lang="scss" scoped>
.wrapper__list-link-man {
  width: 100%;
  height: 100%;
  background: #e3ff1d;
}
</style>

src/components/Chat/module/LeftLinkMan/module/ListLinkMan/index.vue

<template>
  <div>ListLinkMan</div>
</template>

<script setup lang="ts">

</script>
<style scoped>

</style>
image.png

src/components/Chat/module/LeftLinkMan/index.vue

<template>
  <div class="wrapper__list-link-man">
    <n-tabs v-model="formData.active" type="line" justify-content="space-evenly" animated>
      <n-tab-pane name="myChat" tab="我的聊天">
      </n-tab-pane>
      <n-tab-pane name="MyAssisted" tab="我协助的">
      </n-tab-pane>
    </n-tabs>
    <ListLinkMan
      v-if="formData.active==='myChat'"
      :list="selectData.linkList"/>


  </div>
</template>

<script setup lang="ts">
import ListLinkMan from "./module/ListLinkMan/index.vue";
import {ref} from "vue";

const formData = ref<any>({
  active: "myChat"
})
const selectData = ref<any>({
  linkList: [
    {
      userId: "1",
      userName: "泰裤啦小助手&#128522;",
      lastLinkTime: "2023-06-25 03:42:26",
      headerImg: "src/assets/header.png"
    },
    {
      userId: "2",
      userName: "Demo-不愧是我啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦",
      lastLinkTime: "2023-06-25 03:32:26",
      headerImg: "src/assets/header.png"
    },
    {
      userId: "3",
      userName: "程序坞",
      lastLinkTime: "2023-06-25 03:11:26",
      headerImg: "src/assets/header.png"
    },
  ]
})


</script>
<style lang="scss" scoped>
.wrapper__list-link-man {
  width: 100%;
  height: 100%;
  background: #e3ff1d;

}
</style>

src/components/Chat/module/LeftLinkMan/module/ListLinkMan/index.vue

<template>
  <div class="wrapper__list-link-man">
    <n-scrollbar class="list-link-man__scrollbar">
      <template v-for="(item,index) in props.list">
        <LinkManItem :data="item"/>
      </template>
    </n-scrollbar>
  </div>
</template>

<script setup lang="ts">
import LinkManItem from "./module/LinkManItem/index.vue";
const props = defineProps({
  //说明:开始时间提示
  list: {
    type: Array,
    default: () => [],
  }
})
</script>
<style lang="scss" scoped>
.wrapper__list-link-man {
  .list-link-man__scrollbar {
    height: calc(100% - 0.42rem);
  }
}
</style>

src/components/Chat/module/LeftLinkMan/module/ListLinkMan/module/LinkManItem/index.vue

<template>
  <div class="wrapper__link-man-item">
    <div class="link-man-item__header">
      <img style="border-radius:0.13rem;width: 100%;height: 100%" :src="props.data.headerImg"
           :alt="props.data.userName"/>
    </div>
    <div class="link-man-item__name">
      <div class="text__name" v-html="props.data.userName"></div>
      <div class="text__time">{{ props.data.lastLinkTime }}</div>
    </div>
  </div>
</template>

<script setup lang="ts">
import {PropType} from "vue";

const props = defineProps({
  //说明:开始时间提示
  data: {
    type: Object as PropType<any>,
    default: () => {
    },
  }
})
</script>
<style lang="scss" scoped>
@import "/src/styles/viriables";

.wrapper__link-man-item {
  display: flex;
  align-items: center;
  padding: 0.15rem 0.24rem;
  margin: 10px;
  background-color: #0D0D0D;
  border-radius: 0.06rem;

  .link-man-item {
    &__header {
      width: 0.5rem;
      height: 0.5rem;
    }

    &__name {
      width: 100%;
      height: 100%;
      flex: 1;
      color: $text-color;
      text-align: left;
      margin-left: 0.1rem;
      display: flex;
      flex-direction: column;

      .text__name {
        font-size: 0.14rem;
        font-weight: 550;
        /* 裁剪多余的 */
        overflow: hidden;
        /* 多余的以省略号出现 */
        text-overflow: ellipsis;
        /* 将对象作为弹性伸缩盒子模型显示 */
        display: -webkit-box;
        /* 限制再一个块元素再文本显示的行数 */
        -webkit-line-clamp: 1;
        /* 设置或检索伸缩盒对象的子元素的排列方式 */
        -webkit-box-orient: vertical;
      }

      .text__time {
        color: $text-time-color;
      }
    }
  }
}
</style>
image.png

高度超出长度暂不理会。
修改背景颜色:
src/components/Chat/module/LeftLinkMan/module/ListLinkMan/module/LinkManItem/index.vue

<template>
  <div class="wrapper__link-man-item" @click="handleSelectManClick">
    <div class="link-man-item__header">
      <img style="border-radius:0.13rem;width: 100%;height: 100%" :src="props.data.headerImg"
           :alt="props.data.userName"/>
    </div>
    <div class="link-man-item__name">
      <div class="text__name" v-html="props.data.userName"></div>
      <div class="text__time">{{ props.data.lastLinkTime }}</div>
    </div>
  </div>
</template>

<script setup lang="ts">
import {PropType} from "vue";

const props = defineProps({
  //说明:开始时间提示
  data: {
    type: Object as PropType<any>,
    default: () => {
    },
  }
})

const handleSelectManClick = () => {

}
</script>
<style lang="scss" scoped>
@import "/src/styles/viriables";
.wrapper__link-man-item:hover{
  background-color: #35373b;
}
.wrapper__link-man-item {
  display: flex;
  align-items: center;
  padding: 0.15rem 0.24rem;
  margin: 10px;
  background-color: #0D0D0D;
  border-radius: 0.06rem;
  cursor: pointer;
  .link-man-item {
    &__header {
      width: 0.5rem;
      height: 0.5rem;
    }

    &__name {
      width: 100%;
      height: 100%;
      flex: 1;
      color: $text-color;
      text-align: left;
      margin-left: 0.1rem;
      display: flex;
      flex-direction: column;

      .text__name {
        font-size: 0.14rem;
        font-weight: 550;
        /* 裁剪多余的 */
        overflow: hidden;
        /* 多余的以省略号出现 */
        text-overflow: ellipsis;
        /* 将对象作为弹性伸缩盒子模型显示 */
        display: -webkit-box;
        /* 限制再一个块元素再文本显示的行数 */
        -webkit-line-clamp: 1;
        /* 设置或检索伸缩盒对象的子元素的排列方式 */
        -webkit-box-orient: vertical;
      }

      .text__time {
        color: $text-time-color;
      }
    }
  }
}
</style>

src/components/Chat/module/LeftLinkMan/module/ListLinkMan/index.vue

<template>
  <div class="wrapper__list-link-man">
    <n-scrollbar class="list-link-man__scrollbar">
      <template v-for="(item,index) in props.list">
        <LinkManItem :data="item"/>
      </template>
    </n-scrollbar>
  </div>
</template>

<script setup lang="ts">
import LinkManItem from "./module/LinkManItem/index.vue";

const props = defineProps({
  list: {
    type: Array,
    default: () => [],
  }
})
</script>
<style lang="scss" scoped>
@import "/src/styles/viriables";
::v-deep(.n-scrollbar) {
  max-height: calc($content-height - 0.24rem - 0.64rem);
}

.wrapper__list-link-man {
  width: 100%;
  height: 100%;

  .list-link-man {
    &__scrollbar {
      //max-height: calc($content-height - 0.24rem - 0.16rem);
    }
  }
}
</style>

还有测试用的背景去掉,这里不粘贴代码了:


image.png

右侧聊天区域

先调整窗体大小
src/components/Chat/index.vue

.....
<style lang="scss" scoped>
@import "/src/styles/viriables";
.wrapper__chat {
  width: 100%;
  height: 100%;
  display: flex;
  justify-content: center;

  .chat {
    &__left-people {
      width:$left-link-man-width;
      height: 100%;
    }

    &__content {
      flex: 5;
      height: $content-height;
      display: flex;
      flex-direction: column;

      &__info {
        flex: 5;
        height: 100%;
        background: #40f0ff;
      }

      &__input {
        flex: 2;
        height: 100%;
        background: #f89751;
      }
    }


  }
}
</style>

src/styles/viriables.scss

$title-height: 0.8rem;
$window-width: 14rem;
$window-height: 7rem;
$content-height: calc($window-height - $title-height);

//左侧联系人栏宽度
$left-link-man-width:3.5rem;
//文字颜色
$text-color: #F9FAFC;
//时间的文字颜色
$text-time-color: #9A9B9D;

image.png

上部分联调界面开发

src/components/Chat/index.vue

<template>
  <div class="wrapper__chat">
    <div class="chat__left-people">
      <LeftLinkMan/>
    </div>
    <div class="chat__content">
      <div class="chat__content__info">
        <ShowChatInfo/>
      </div>
      <div class="chat__content__input">
        <InputContent/>
      </div>
    </div>
  </div>
</template>

<script setup lang="ts">
import LeftLinkMan from "./module/LeftLinkMan/index.vue";
import ShowChatInfo from "./module/ShowChatInfo/index.vue";
import InputContent from "./module/InputContent/index.vue";
</script>
<style lang="scss" scoped>
@import "/src/styles/viriables";
.wrapper__chat {
  width: 100%;
  height: 100%;
  display: flex;
  justify-content: center;

  .chat {
    &__left-people {
      width:$left-link-man-width;
      height: 100%;
    }

    &__content {
      width: 100%;
      flex: 5;
      height: calc($content-height - 0.12rem);
      display: flex;
      flex-direction: column;
      margin: 0 0.3rem 0.12rem 0.42rem;
      border: 1px solid #272727;
      border-radius: 0.08rem;
      background: #40f0ff;

      &__info {
        width: 100%;
        height: 100%;
        flex: 1;
        background: #c7c174;
      }

      &__input {
        width: 100%;
        height: 2rem;
        background: #f89751;

      }
    }


  }
}
</style>

src/components/Chat/module/ShowChatInfo/index.vue

<template>
  <div class="wrapper__show-chat-info">
    <div class="show-chat-info__title"></div>
    <div></div>
  </div>
</template>

<script setup lang="ts">

</script>
<style lang="scss" scoped>
.wrapper__show-chat-info {
  width: 100%;
  height: 100%;

  .show-chat-info {
    &__title {
      width: 100%;
      height: 0.45rem;
      background-color: #535bf2;
    }
  }
}
</style>
image.png

相关文章

网友评论

      本文标题:基于vue3+Naive UI开发网页聊天页面

      本文链接:https://www.haomeiwen.com/subject/brmvudtx.html