基于Vuetify的简易聊天布局:实现聊天记录自下而上增长
Vuetify 极简聊天布局(自下而上消息流)
我太懂这种被CSS布局折腾到心态爆炸的感觉了!下面这个方案完全贴合你的需求——几乎全用Vuetify原生组件和指令,只加了一丢丢必要的自定义CSS,完美实现自下而上增长的聊天记录,还包含你要的三主列布局+底部输入栏。
<template> <v-app> <!-- 全屏主容器 --> <v-container fluid class="pa-0" style="height: 100vh;"> <v-row no-gutters class="h-100"> <!-- 左侧联系人侧边栏 --> <v-col cols="3" class="bg-gray-light"> <v-card class="h-100"> <v-card-title class="text-h6">联系人</v-card-title> <v-list dense> <v-list-item active> <v-list-item-title>张三</v-list-item-title> </v-list-item> <v-list-item> <v-list-item-title>李四</v-list-item-title> </v-list-item> </v-list> </v-card> </v-col> <!-- 中间核心聊天区域 --> <v-col cols="6" class="d-flex flex-column"> <!-- 聊天头部 --> <v-card class="mb-0"> <v-card-title> <span class="text-h6">与张三聊天</span> </v-card-title> </v-card> <!-- 聊天记录容器(自下而上核心) --> <v-card-text class="chat-messages-container flex-grow-1 overflow-auto" ref="chatContainer" > <div class="chat-messages"> <!-- 静态示例消息 --> <v-chip class="message mb-2" color="blue-lighten-3" text-color="black"> 今天天气不错啊! </v-chip> <v-chip class="message mb-2 self" color="green-lighten-3" text-color="black"> 确实~ 终于把聊天布局搞定了😭 </v-chip> <!-- 动态消息列表(替换静态示例) --> <!-- <v-chip v-for="msg in messages" :key="msg.id" class="message mb-2" :class="{ self: msg.isSelf }" :color="msg.isSelf ? 'green-lighten-3' : 'blue-lighten-3'" text-color="black" > {{ msg.content }} </v-chip> --> </div> </v-card-text> <!-- 底部输入栏 --> <v-card class="mt-0"> <v-container fluid class="pa-2"> <v-row align="center"> <v-col cols="10"> <v-text-field v-model="newMessage" placeholder="输入消息..." outlined dense @keyup.enter="sendMessage" ></v-text-field> </v-col> <v-col cols="2"> <v-btn color="primary" block @click="sendMessage">发送</v-btn> </v-col> </v-row> </v-container> </v-card> </v-col> <!-- 右侧用户资料侧边栏 --> <v-col cols="3" class="bg-gray-light"> <v-card class="h-100"> <v-card-title class="text-h6">张三的资料</v-card-title> <v-card-text> <p>昵称:张三</p> <p>在线状态:在线</p> </v-card-text> </v-card> </v-col> </v-row> </v-container> </v-app> </template> <script> export default { data() { return { newMessage: '', messages: [ { id: 1, content: '今天天气不错啊!', isSelf: false }, { id: 2, content: '确实~ 终于把聊天布局搞定了😭', isSelf: true } ] } }, methods: { sendMessage() { if (!this.newMessage.trim()) return // 添加自己的消息 this.messages.push({ id: Date.now(), content: this.newMessage.trim(), isSelf: true }) // 模拟对方回复(可选) setTimeout(() => { this.messages.push({ id: Date.now() + 1, content: '哈哈,CSS布局确实坑!', isSelf: false }) this.$nextTick(() => this.$refs.chatContainer.scrollTop = 0) }, 1000) this.newMessage = '' // 发送后自动滚动到最新消息 this.$nextTick(() => this.$refs.chatContainer.scrollTop = 0) } }, mounted() { // 初始化时滚动到最新消息 this.$nextTick(() => this.$refs.chatContainer.scrollTop = 0) } } </script> <style scoped> /* 仅需这几行自定义CSS实现核心需求 */ .chat-messages-container { display: flex; flex-direction: column-reverse; } .chat-messages { display: flex; flex-direction: column; } /* 消息对齐样式:对方左对齐,自己右对齐 */ .message { max-width: 70%; align-self: flex-start; } .message.self { align-self: flex-end; } </style>
核心设计亮点
- 自下而上消息流:通过
flex-direction: column-reverse让聊天容器的内容从底部开始堆叠,新消息添加到DOM末尾后,视觉上自动出现在底部,完美解决“自下而上增长”的需求,比手动计算滚动高度简单100倍。 - 最大化复用Vuetify组件:全程用
v-app、v-container、v-row、v-col实现响应式三列布局,v-card、v-text-field、v-btn构建聊天界面,几乎没有自定义组件,保持Vuetify风格一致性。 - 自动滚动到最新消息:利用Vue的
$nextTick确保DOM更新完成后,将滚动条设置到容器顶部(因为column-reverse布局,顶部对应视觉上的最新消息位置),避免了复杂的滚动监听逻辑。 - 最小化自定义CSS:只写了8行样式——实现reverse布局、消息对齐,其余全靠Vuetify内置类(比如
flex-grow-1让聊天区域占满剩余高度,overflow-auto提供滚动能力)。
可扩展优化建议
- 若需要更精致的消息气泡,可以把
v-chip换成v-card,调整border-radius和padding即可。 - 侧边栏可以替换为
v-navigation-drawer组件,实现可折叠的侧边栏效果。 - 当消息数量过多时,推荐使用Vuetify的
v-virtual-scroll组件实现虚拟滚动,提升页面性能。
内容的提问来源于stack exchange,提问作者Lucien Chardon
相关产品推荐
相关产品推荐

