位置: IT常识 - 正文

【移动端聊天功能模板】Vue实现H5聊天系统,实现上下固定中间滚动布局,微信授权功能,自动滚动到底部【详细注释,一看就会】(移动有聊天室平台吗)

编辑:rootadmin
【移动端聊天功能模板】Vue实现H5聊天系统,实现上下固定中间滚动布局,微信授权功能,自动滚动到底部【详细注释,一看就会】 前言

推荐整理分享【移动端聊天功能模板】Vue实现H5聊天系统,实现上下固定中间滚动布局,微信授权功能,自动滚动到底部【详细注释,一看就会】(移动有聊天室平台吗),希望有所帮助,仅作参考,欢迎阅读内容。

文章相关热门搜索词:移动有聊天室平台吗,移动有个聊天软件叫什么,移动端设备 找聊天记录,移动端设备 找聊天记录,移动即时聊天,移动即时聊天,移动即时聊天,移动聊天工具,内容如对您有帮助,希望把文章链接给更多的朋友!

最近刚好在做这方面的功能,就网上看了下,发现很多种写法,但是有些写的很乱, 我也看的很麻烦,干脆就自己写一个简单的静态版本放在这, 以后需要用到的时候可以直接拿着改改就能用。 后面我还会继续更新有交互逻辑的模拟聊天室, 包括pc端的聊天室也会写,这里就先从移动端的微信聊天窗口开始。

pc版本的也有了

我也写了个pc版本的聊天功能模板,包含websocket功能,需要的点击下面跳转或者直接去我主页查看 点击这里 跳转PC端聊天功能模板

小程序版本也有了【移动端聊天功能模板】Vue实现H5聊天系统,实现上下固定中间滚动布局,微信授权功能,自动滚动到底部【详细注释,一看就会】(移动有聊天室平台吗)

小程序版本搭配websocket写法发布了 点击这里

效果图

1,这个是聊天窗的大体样式布局,我们通过flex布局让他分左右 其实思路也简单,就是后期后端返回的数据中有一个字段是左右, 后端判断是你自己的信息就右边,别人发的信息就左边。 我们拿到字段调用对应不同的样式就行了。 2,这里是输入框,当他输入到超过一定高度的时候就会出现滚动条。 这里可以调整,是vant的组件。

注意事项

因为我这里用了百分比的高度。这样可以自适应好一点。 但有可能会出现一个问题,就是你使用这个代码,发现高度不对。 那你需要看一下你的html和body有没有设置高百分百,不然这里无法继承到。 如何设置呢,就是直接去app.vue页面,然后这样,把html,body和#app都设置一下百分百高度就可以了

<style>* { padding: 0; margin: 0;}html,body,#app { height: 100%; width: 100%;}</style>

这里用了一些vant框架的组件,所以如果没有下载的安装一下vant就可以了 这是vue2版本的,如果想要vue3的自己去官网下载安装

npm i vant@latest-v2 -S

然后main.js引入

import Vue from 'vue';import Vant from 'vant';import 'vant/lib/index.css';Vue.use(Vant);代码部分(目前静态页面)<template> <div class="wrap"> <div class="title"> <div> <van-icon name="arrow-left" size="20" style="margin-left: 10px" @click="onClickLeft" /> </div> <div>{{ userName }}</div> <div> <van-icon name="ellipsis" size="22" style="margin-right: 10px" @click="onClickRight" /> </div> </div> <div class="content_box" id="box" ref="scrollBox"> <div class="timer">2022-08-02 11:08:07</div> <div :class="item.position == 'left' ? 'userbox2' : 'userbox'" v-for="(item, index) in chatList" :key="index" > <div :class="item.position == 'left' ? 'nameInfo2' : 'nameInfo'"> <div style="font-size: 14px">{{ item.username }}</div> <div :class="item.position == 'left' ? 'contentText2' : 'contentText'" > {{ item.content }} </div> </div> <div> <van-image round width="50px" height="50px" :src="item.url" /> </div> </div> </div> <div class="bottom"> <van-field v-model="inputValue" center type="textarea" :autosize="{ maxHeight: 100, minHeight: 25 }" placeholder="请输入内容" rows="1" > <template #button> <van-button size="small" type="primary" @click="sendOut">发送</van-button> </template> </van-field> </div> </div></template><script>export default { data() { return { //聊天数据 chatList: [ { url: "https://www.yuucn.com/wp-content/uploads/2023/05/1683878137-cd3745170198b3f.jpeg", username: "张三", content: "模拟数据123模拟数据123模拟数据123模拟数据123", position: "left", }, { url: "https://www.yuucn.com/wp-content/uploads/2023/05/1683878144-cd3745170198b3f.jpeg", username: "李四", content: "模拟数据123模拟数据123模拟数据123模拟数据123模拟数据123", position: "right", }, { url: "https://www.yuucn.com/wp-content/uploads/2023/05/1683878137-cd3745170198b3f.jpeg", username: "张三", content: "模拟数据123", position: "left", }, { url: "https://www.yuucn.com/wp-content/uploads/2023/05/1683878144-cd3745170198b3f.jpeg", username: "李四", content: "模拟数据123模拟数据", position: "right", }, { url: "https://www.yuucn.com/wp-content/uploads/2023/05/1683878137-cd3745170198b3f.jpeg", username: "张三", content: "模拟数据123", position: "left", }, { url: "https://www.yuucn.com/wp-content/uploads/2023/05/1683878144-cd3745170198b3f.jpeg", username: "李四", content: "模拟数据123模拟数据", position: "right", }, { url: "https://www.yuucn.com/wp-content/uploads/2023/05/1683878137-cd3745170198b3f.jpeg", username: "张三", content: "模拟数据123", position: "left", }, { url: "https://www.yuucn.com/wp-content/uploads/2023/05/1683878144-cd3745170198b3f.jpeg", username: "李四", content: "模拟数据123模拟数据", position: "right", }, { url: "https://www.yuucn.com/wp-content/uploads/2023/05/1683878137-cd3745170198b3f.jpeg", username: "张三", content: "模拟数据123", position: "left", }, { url: "https://www.yuucn.com/wp-content/uploads/2023/05/1683878144-cd3745170198b3f.jpeg", username: "李四", content: "模拟数据123模拟数据", position: "right", }, { url: "https://www.yuucn.com/wp-content/uploads/2023/05/1683878137-cd3745170198b3f.jpeg", username: "张三", content: "模拟数据123", position: "left", }, { url: "https://www.yuucn.com/wp-content/uploads/2023/05/1683878144-cd3745170198b3f.jpeg", username: "李四", content: "模拟数据123模拟数据", position: "right", }, { url: "https://www.yuucn.com/wp-content/uploads/2023/05/1683878137-cd3745170198b3f.jpeg", username: "张三", content: "模拟数据123", position: "left", }, { url: "https://www.yuucn.com/wp-content/uploads/2023/05/1683878144-cd3745170198b3f.jpeg", username: "李四", content: "模拟数据123模拟数据", position: "right", }, ], //用户名 userName: "张三", //输入内容 inputValue: "", //滚动条距离顶部距离 scrollTop:0 }; }, mounted(){ this.setPageScrollTo() //创建监听内容部分滚动条滚动 this.$refs.scrollBox.addEventListener('scroll',this.srTop) }, methods: { //返回 onClickLeft() { console.log("返回"); }, //更多 onClickRight() { console.log("按钮"); }, //滚动条默认滚动到最底部 setPageScrollTo(s, c) { //获取中间内容盒子的可见区域高度 this.scrollTop = document.querySelector("#box").offsetHeight; setTimeout((res) => { //加个定时器,防止上面高度没获取到,再获取一遍。 if (this.scrollTop != this.$refs.scrollBox.offsetHeight) { this.scrollTop = document.querySelector("#box").offsetHeight; } }, 100); //scrollTop:滚动条距离顶部的距离。 //把上面获取到的高度座位距离,把滚动条顶到最底部 this.$refs.scrollBox.scrollTop = this.scrollTop; }, //滚动条到达顶部 srTop(){ //判断:当滚动条距离顶部为0时代表滚动到顶部了 if(this.$refs.scrollBox.scrollTop==0){ //逻辑简介: //到顶部后请求后端的方法,获取第二页的聊天记录,然后插入到现在的聊天数据前面。 //如何插入前面:可以先把获取的数据保存在 A 变量内,然后 this.chatList=A.concat(this.chatList)把数组合并进来就可以了 //拿聊天记录逻辑: //第一次调用一个请求拉历史聊天记录,发请求时参数带上页数 1 传过去,拿到的就是第一页的聊天记录,比如一次拿20条。你显示出来 //然后向上滚动到顶部时,触发新的请求,在请求中把分页数先 +1 然后再请求,这就拿到了第二页数据,然后通过concat合并数组插入进前面,依次类推,功能完成! console.log('到顶了,滚动条位置 :',this.$refs.scrollBox.scrollTop); } }, sendOut(){ console.log('发送成功'); } },};</script><style scoped>.wrap { height: 100%; width: 100%; position: relative;}.title { height: 40px; width: 100%; background-color: #eaeaea; display: flex; justify-content: space-between; align-items: center;}.bottom { min-height: 50px; width: 100%; border-top: 1px solid #eaeaea; position: fixed; bottom: 0;}.content_box { /* 中间栏计算高度,110是包含了上下固定的两个元素高度90 这里padding:10px造成的上下够加了10,把盒子撑大了,所以一共是20要减掉 然后不知道是边框还是组件的原因,导致多出了一些,这里再减去5px刚好。不然会出现滚动条到顶或者底部的时候再滚动的话就会报一个错,或者出现滚动条变长一下的bug */ height: calc(100% - 115px); overflow: auto; padding: 10px;}.timer { text-align: center; color: #c2c2c2;}/* 发送的信息样式 *//* 右边消息思路解释:首先大盒子userbox内放两个盒子,一个放头像,一个放用户名和发送的内容,我们先用flex让他横向排列。然后把写文字的大盒子设置flex:1。这个属性的意思就是让这个元素撑满父盒子剩余位置。然后我们再把文字盒子设置flex,并把他对齐方式设置为尾部对齐就完成了基本的结构,然后微调一下就可以了*/.userbox { width: 100%; display: flex; margin-bottom: 10px;}.nameInfo { /* 用flex:1把盒子撑开 */ flex: 1; margin-right: 10px; /* 用align-items把元素靠右对齐 */ display: flex; flex-direction: column; align-items: flex-end;}.contentText { background-color: #9eea6a; /* 把内容部分改为行内块元素,因为盒子flex:1把盒子撑大了,所以用行内块元素让内容宽度不根据父盒子来 */ display: inline-block; /* 这四句是圆角 */ border-top-left-radius: 10px; border-top-right-radius: 0px; border-bottom-right-radius: 10px; border-bottom-left-radius: 10px; /* 最大宽度限定内容输入到百分61换行 */ max-width: 61%; padding: 5px 10px; /* 忽略多余的空白,只保留一个空白 */ white-space: normal; /* 换行显示全部字符 */ word-break: break-all; margin-top: 3px; font-size: 14px;}/* 接收的信息样式 *//* 左边消息思路解释:跟上面一样,就是换一下位置,首先通过把最外层大盒子的排列方式通过flex-direction: row-reverse;属性翻转,也就是头像和文字盒子换位置然后删除掉尾部对齐方式,因为不写这个默认是左对齐的。我们写的左边就没必要再写了。*/.userbox2 { width: 100%; display: flex; flex-direction: row-reverse; margin-bottom: 10px;}.nameInfo2 { /* 用flex:1把盒子撑开 */ flex: 1; margin-left: 10px;}.contentText2 { background-color: #9eea6a; /* 把内容部分改为行内块元素,因为盒子flex:1把盒子撑大了,所以用行内块元素让内容宽度不根据父盒子来 */ display: inline-block; /* 这四句是圆角 */ border-top-left-radius: 0px; border-top-right-radius: 10px; border-bottom-right-radius: 10px; border-bottom-left-radius: 10px; /* 最大宽度限定内容输入到百分61换行 */ max-width: 61%; padding: 5px 10px; /* 忽略多余的空白,只保留一个空白 */ white-space: normal; /* 换行显示全部字符 */ word-break: break-all; margin-top: 3px; font-size: 14px;}</style>

到这里静态页面结束

H5实战项目版本,更新2022-11-8

这里注意点: 1,v-cloak防止页面闪烁的 2,滚动条方法要用nextTick不能用定时器,不然会页面闪烁 3,微信授权方法,记得改appid,redirect_uri,state。具体不会的可以看我另一个帖子,微信登录授权。

<!DOCTYPE html><html><head> <meta charset='UTF-8'> <meta name="viewport" content="width=device-width,initial-scale=1.0"> <meta name="viewport" content="maximum-scale=1.0,minimum-scale=1.0,user-scalable=0,width=device-width,initial-scale=1.0" /> <meta name="format-detection" content="telephone=no,email=no,date=no,address=no"> <meta name="viewport" content="width=device-width,minimum-scale=1.0,maximum-scale=1.0,user-scalable=no" /> <!-- vue --> <script src="/statics/vue_element/vue.js"></script> <script src="/statics/vue_element/element.js"></script> <script src="/statics/vue_element/axios.js"></script> <!-- 滚动 --> <link rel="stylesheet" href="/statics/vue_element/new.css"> <link rel="stylesheet" href="/statics/vue_element/index.css"> <link rel="stylesheet" href="/statics/vue_element/element.css"> <title>在线咨询</title></head><body> <div id="app"> <div class="wrap" v-cloak> <div class="content_box" id="box" ref="scrollBox"> <div class="timer">{{add_time}}</div> <div :class="item.uid == wechatInfo.tag_uid ? 'userbox' : 'userbox2'" v-for="(item, index) in chatList" :key="index" :id='"item"+index'> <div :class="item.uid == wechatInfo.tag_uid ? 'nameInfo' : 'nameInfo2'"> <!-- <div style="font-size: 14px">{{ item.nickname }}</div> --> <div :class="item.uid == wechatInfo.tag_uid ? 'contentText' : 'contentText2'"> {{ item.msn }} </div> <div style="display: inline-block;" v-show="item.uid == wechatInfo.tag_uid&&chatShow==item.chatShow"> <i class="el-icon-loading" v-show="jzshow==1"></i> <i class="el-icon-warning" style="color:red" v-show="jzshow==2" @click="resend(item.msn)"></i> </div> </div> <div> <image class="touxiang" :src="item.avatar" /> </div> </div> </div> <div class="bottom"> <textarea name="输入框" id="1" cols="20" rows="5" class="areaBox" v-model="inputValue"></textarea> <button class="fasong" @click="sendOut">发送</button> </div> </div> </div></body><script> new Vue({ el: '#app', data() { return { page: 1, //聊天历史记录分页 chatList: [], //聊天信息 userName: "", //用户名 inputValue: "", //输入内容 scrollTop: 0, //滚动条距离顶部距离 infoList: null, //用户信息 kfInfo: [], //客服信息 wechatInfo: '', //双方用户信息 add_time: '', jzshow: 0, //加载图标icon jzshowtimer: null, //加载图标定时器 chatShow: 2, //加载图标显示 path: "wss://test.123456.com/msg", //websocket链接地址(这里地址都是乱写的,自行修改) ws: null, //建立的连接 lockReconnect: false, //是否真正建立连接 timeout: 10 * 1000, //30秒一次心跳 timeoutObj: null, //心跳心跳倒计时 serverTimeoutObj: null, //心跳倒计时 timeoutnum: null, //断开 重连倒计时 closeType: 1, //断开判断:0代表不重连,1代表重连 }; }, created() { this.closeType = 1 //进入改为1,代表如果断开链接自动重连 let type = sessionStorage.getItem('wechatInfo') //本地如果有值就获取,没有值就微信授权后获取 if (type && type !== 'undefined') { this.wechatInfo = JSON.parse(sessionStorage.getItem('wechatInfo')) //双方用户信息 console.log('用户信息', this.wechatInfo); this.initWebpack(); //ws链接 this.getList() //客服列表 } else { this.oAuth() //微信授权 } }, mounted() { this.$refs.scrollBox.removeEventListener("scroll", this.srTop); }, methods: { //H5授权 oAuth() { // snsapi_userinfo (授权页面) location.href = `https://open.weixin.qq.com/connect/oauth2/authorize?appid=wx3cbfddebd1123021&redirect_uri=https://test.123456.com/model/chat/loading.html&response_type=code&scope=snsapi_userinfo&state=wx3cbfddebd1123021#wechat_redirect`; }, // 初始化websocket链接 initWebpack() { if (typeof WebSocket === "undefined") { alert("您的浏览器不支持socket"); } else { this.ws = new WebSocket(this.path); //实例 this.ws.onopen = this.onopen; //监听链接成功 this.ws.onmessage = this.onmessage; //监听后台返回消息 this.ws.onclose = this.onclose; //监听链接关闭 this.ws.onerror = this.onerror; //监听链接异常 } }, //重新连接 reconnect() { var that = this; //防止重复链接 if (that.lockReconnect) { return; } that.lockReconnect = true; //没连接上会一直重连,设置延迟避免请求过多 that.timeoutnum && clearTimeout(that.timeoutnum); that.timeoutnum = setTimeout(function () { that.initWebpack(); //新连接 that.lockReconnect = false; }, 5000); }, //重置心跳 reset() { var that = this; clearTimeout(that.timeoutObj); //清除心跳倒计时 clearTimeout(that.serverTimeoutObj); //清除超时关闭倒计时 that.start(); //重启心跳 }, //开启心跳 start() { var self = this; self.timeoutObj && clearTimeout(self.timeoutObj); //心跳倒计时如果有值就清除掉,防止重复 self.serverTimeoutObj && clearTimeout(self.serverTimeoutObj); //超时关闭倒计时如果有值就清除掉,防止重复 self.timeoutObj = setTimeout(function () { if (self.ws.readyState == 1) { self.ws.send(JSON.stringify({ type: "ping" })); } else { self.reconnect(); } //如果超时了就关闭连接 self.serverTimeoutObj = setTimeout(function () { self.ws.close(); }, self.timeout); }, self.timeout); }, //连接成功 onopen() { let that = this console.log("连接成功"); if (that.ws.readyState == 1) { that.ws.send(JSON.stringify({ //发送消息到后台,和send一样,这是微信的写法 type: "login", data: { token: this.wechatInfo.token, id: this.wechatInfo.id, channel_type: 'wechat', uid: this.wechatInfo.uid, openid: this.wechatInfo.openid } })) that.ws.send(JSON.stringify({ type: "online", data: { online: 1, user_type: 'user', is_tourist: this.wechatInfo.uid ? 0 : 1 } })) } this.start(); //链接成功后开启心跳 }, //接受后台信息回调 onmessage(res) { let type = JSON.parse(res.data) //后台返回消息,通过type字段判断是不是别人发送给我的消息 if (type.type == 'chat') { clearTimeout(this.jzshowtimer); this.chatShow = 1 //this.chatList.push(type.data) //把消息添加到信息列表渲染 this.jzshow = 0 //隐藏加载icon this.$nextTick(() => { // 一定要用nextTick this.setPageScrollTo(); //页面滚动条距离顶部高度等于这个盒子的高度 this.$refs.scrollBox.scrollTop = this.$refs.scrollBox.scrollHeight; }) console.log("收到后台信息:", JSON.parse(res.data)); } else if (type.type == 'reply') { this.chatList.push(type.data) } this.reset(); //收到服务器信息,心跳重置 }, //关闭连接回调 onclose(e) { console.log("连接关闭"); //断开链接时判断 if (this.closeType == 0) { return } this.reconnect(); //重连 }, //连接异常回调 onerror(e) { console.log("出现错误"); this.reconnect(); //重连 }, // 重新发送 resend(msn) { this.inputValue = msn this.jzshow = 1 let parms = { msn: this.inputValue, to_uid: this.kfInfo[0].kf_id, type: 1, form_type: 'wechat', is_tourist: 0 } //通过websocket发送信息到后台 this.ws.send(JSON.stringify({ type: "chat", data: parms })) this.jzshowtimer = setTimeout((res) => { this.jzshow = 2 }, 3000); this.inputValue = '' //点击发送后清空输入框 }, //客服列表信息 getList() { axios.post('/gzh/crmebchat/chatUserList', { type: 'user', tag_uid: this.wechatInfo.tag_uid || 0, wechat_user_id: this.wechatInfo.id || 0, avatar: this.wechatInfo.headimgurl, nickname: this.wechatInfo.nickname }).then(res => { // console.log('客服信息:', res); this.kfInfo = res.data.data //客服信息 this.ws.send(JSON.stringify({ type: "to_chat", data: { id: this.kfInfo } })); this.getlishiList() }).catch(error => { console.log(error, '请求失败'); }) }, //获取历史记录 getlishiList(type) { axios.post('/gzh/crmebchat/chatMessageList', { to_uid: this.kfInfo, uid: this.wechatInfo.tag_uid, page: this.page, limit: 10, }).then(res => { // console.log('历史记录:', res); this.add_time = res.data.data[0]._add_time || '-' let a = res.data.data this.chatList = a.concat(this.chatList) //用拿到的数据合并现有的数据,这样当加载第二页历史记录时,顺序不会乱 if (type == 1) { //滚动到顶部触发方法会传入1,此时不需要调用滚动到最底部的方法 return } this.$nextTick(() => { // 一定要用nextTick this.setPageScrollTo(); //页面滚动条距离顶部高度等于这个盒子的高度 this.$refs.scrollBox.scrollTop = this.$refs.scrollBox.scrollHeight; }) }).catch(error => { console.log(error, '请求失败'); }) }, //发送 sendOut() { this.chatList.push({ msn: this.inputValue, uid: this.wechatInfo.tag_uid, avatar: this.wechatInfo.headimgurl, nickname: this.wechatInfo.nickname, chatShow: 2 }) this.jzshow = 1 let parms = { msn: this.inputValue, to_uid: this.kfInfo, type: 1, form_type: 'wechat', is_tourist: 0 } //通过websocket发送信息到后台 this.ws.send(JSON.stringify({ type: "chat", data: parms })) this.jzshowtimer = setTimeout((res) => { this.jzshow = 2 }, 3000); this.inputValue = '' //点击发送后清空输入框 console.log('发送成功', this.inputValue); // 页面滚动到底部 this.$nextTick(() => { // 一定要用nextTick this.setPageScrollTo(); //页面滚动条距离顶部高度等于这个盒子的高度 this.$refs.scrollBox.scrollTop = this.$refs.scrollBox.scrollHeight; }) }, //滚动条默认滚动到最底部 setPageScrollTo(s, c) { //获取中间内容盒子的可见区域高度 this.scrollTop = document.querySelector("#box").offsetHeight; setTimeout((res) => { //加个定时器,防止上面高度没获取到,再获取一遍。 if (this.scrollTop != this.$refs.scrollBox.offsetHeight) { this.scrollTop = document.querySelector("#box").offsetHeight; } }, 100); console.log('滚动', this.scrollTop); //scrollTop:滚动条距离顶部的距离。 //把上面获取到的高度座位距离,把滚动条顶到最底部 this.$refs.scrollBox.scrollTop = this.scrollTop; //判断是否有滚动条,有滚动条就创建一个监听滚动事件,滚动到顶部触发srTop方法 if (this.$refs.scrollBox.scrollTop > 0) { this.$refs.scrollBox.addEventListener("scroll", this.srTop); } }, //滚动条到达顶部 srTop() { //判断:当滚动条距离顶部为0时代表滚动到顶部了 if (this.$refs.scrollBox.scrollTop == 0) { this.page++ this.getlishiList(1) } } }, })</script><style scoped> * { margin: 0; padding: 0; } /* 防止闪烁 */ [v-cloak] { display: none; } .wrap { height: 100%; width: 100%; position: relative; } .touxiang { width: 50px; height: 50px; border-radius: 50%; } .areaBox { height: 30px; width: 80%; border: none; resize: none; outline: none; padding: 5px; } .title { height: 40px; width: 100%; background-color: #eaeaea; display: flex; justify-content: center; align-items: center; } .bottom { min-height: 40px; width: 100%; border-top: 1px solid #eaeaea; background-color: #F1F1F1; position: fixed; bottom: 0; display: flex; justify-content: space-between; align-items: center; padding: 0 5px; border-radius: 10px; } .fasong { height: 30px; padding: 2px 7px; border-radius: 5px; text-align: center; color: #58df4d; background-color: #eaeaea; font-size: 14px; line-height: 30px; border: none; resize: none; outline: none; margin-right: 15px; } .content_box { height: calc(100% - 95px); overflow: auto; padding: 10px 10px 20px 10px; } .timer { text-align: center; color: #c2c2c2; } .userbox { width: 100%; display: flex; margin-bottom: 10px; } .nameInfo { /* 用flex:1把盒子撑开 */ flex: 1; margin-right: 10px; /* 用align-items把元素靠右对齐 */ display: flex; align-items: baseline; flex-direction: row-reverse; } .contentText { background-color: #9eea6a; display: inline-block; /* 这四句是圆角 */ border-top-left-radius: 10px; border-top-right-radius: 0px; border-bottom-right-radius: 10px; border-bottom-left-radius: 10px; /* 最大宽度限定内容输入到百分61换行 */ max-width: 61%; padding: 5px 10px; /* 忽略多余的空白,只保留一个空白 */ white-space: normal; /* 换行显示全部字符 */ word-break: break-all; margin-top: 3px; font-size: 14px; margin-left: 10px; margin-top: 15px; } .userbox2 { width: 100%; display: flex; flex-direction: row-reverse; margin-bottom: 10px; } .nameInfo2 { /* 用flex:1把盒子撑开 */ flex: 1; margin-left: 10px; } .contentText2 { background-color: #9eea6a; display: inline-block; /* 这四句是圆角 */ border-top-left-radius: 0px; border-top-right-radius: 10px; border-bottom-right-radius: 10px; border-bottom-left-radius: 10px; /* 最大宽度限定内容输入到百分61换行 */ max-width: 61%; padding: 5px 10px; /* 忽略多余的空白,只保留一个空白 */ white-space: normal; /* 换行显示全部字符 */ word-break: break-all; margin-top: 3px; font-size: 14px; margin-right: 10px; margin-top: 15px; }</style></html>
本文链接地址:https://www.jiuchutong.com/zhishi/282785.html 转载请保留说明!

上一篇:DVDRegionFree.exe进程是安全程序吗 DVDRegionFree进程查询(dvd.rom)

下一篇:win10待机设置(win10设置待机时间长怎么在哪里设置)

  • 爱奇艺会员怎么不让别人用(爱奇艺会员怎么关闭自动续费)

    爱奇艺会员怎么不让别人用(爱奇艺会员怎么关闭自动续费)

  • 淘宝pc版卖家页面怎么进入(淘宝pc版卖家页面在哪里)

    淘宝pc版卖家页面怎么进入(淘宝pc版卖家页面在哪里)

  • 电池多久换一次(石英表电池多久换一次)

    电池多久换一次(石英表电池多久换一次)

  • qq消息漫游设置在哪里(qq设置消息漫游是什么意思)

    qq消息漫游设置在哪里(qq设置消息漫游是什么意思)

  • 微博拉黑后可以私信吗(微博拉黑后可以搜到我吗)

    微博拉黑后可以私信吗(微博拉黑后可以搜到我吗)

  • 修补工具快捷键(修补工具快捷键设置)

    修补工具快捷键(修补工具快捷键设置)

  • icloud云盘关还是不关(icloud云盘关闭后果)

    icloud云盘关还是不关(icloud云盘关闭后果)

  • 小米手环深睡眠和浅睡眠怎么判断的(小米手环深睡眠一小时正常吗)

    小米手环深睡眠和浅睡眠怎么判断的(小米手环深睡眠一小时正常吗)

  • 怎么在幻灯片中加一个线条(怎么在幻灯片中添加开始动作按钮)

    怎么在幻灯片中加一个线条(怎么在幻灯片中添加开始动作按钮)

  • 淘宝退款花呗红包会退吗(淘宝申请退款退回花呗的钱去哪里了)

    淘宝退款花呗红包会退吗(淘宝申请退款退回花呗的钱去哪里了)

  • 苹果手机网络显示1x(苹果手机网络显示CHN-CT)

    苹果手机网络显示1x(苹果手机网络显示CHN-CT)

  • 快手怎么保存别人视频(快手怎么保存别人的图片)

    快手怎么保存别人视频(快手怎么保存别人的图片)

  • ios13 取消三指长按功能(iphone三指)

    ios13 取消三指长按功能(iphone三指)

  • 探探封号封多久能恢复(探探封号了怎么办)

    探探封号封多久能恢复(探探封号了怎么办)

  • nce-al00是什么型号(nce-al00参数)

    nce-al00是什么型号(nce-al00参数)

  • 小米8费电快怎么回事(小米八太耗电了)

    小米8费电快怎么回事(小米八太耗电了)

  • 苹果x怎么改蓝牙名称(苹果x怎么改蓝牙耳机名字)

    苹果x怎么改蓝牙名称(苹果x怎么改蓝牙耳机名字)

  • 拼多多上买东西的步骤(拼多多买东西不让别人看到关闭哪里)

    拼多多上买东西的步骤(拼多多买东西不让别人看到关闭哪里)

  • 窗口与对话框的区别(窗口与对话框的不同点和相同点)

    窗口与对话框的区别(窗口与对话框的不同点和相同点)

  • 发到朋友圈的信息如何删(发到朋友圈的信息多长时间可以删除)

    发到朋友圈的信息如何删(发到朋友圈的信息多长时间可以删除)

  • service启动的正确姿势(service的启动方式及生命周期)

    service启动的正确姿势(service的启动方式及生命周期)

  • Anaconda D2L 虚拟环境安装配置(anaconda虚拟机)

    Anaconda D2L 虚拟环境安装配置(anaconda虚拟机)

  • Vue中的Pinia状态管理工具 | 一篇文章教会你全部使用细节(vue pending)

    Vue中的Pinia状态管理工具 | 一篇文章教会你全部使用细节(vue pending)

  • 赔偿给客户的货财务怎么处理
  • 完税证明可以重复打印吗
  • 个体户一定要自己经营吗
  • 年平均资金占用额计算公式
  • 如何做好服务 服务行业
  • 公司租车要交什么费用
  • 减免的所得税额怎么入账
  • 个税父母赡养抵扣3000
  • 转账支票的用途怎么写
  • 4s店的赠品
  • 以前年度记错的费用怎么调整?
  • 车辆商业险和交强险可以分开买吗
  • 期货交易所手续费2023
  • 个人公司转让协议怎么写
  • 含税金是什么意思
  • 旅行社代订机票可以入差旅费报销吗
  • 待转销项税额会计分录
  • 劳务发票个人所得税计算器
  • 我公司去年职工工资多少
  • 股票价格变化的原因
  • 一般纳税人所得税优惠政策
  • 企业微信收款的钱怎么提取出来
  • 个体工商户交企业所得
  • 第三方要求
  • 收到场地租赁费入什么科目
  • 苹果7plus续航
  • 以太网连接网络
  • PHP:xml_set_processing_instruction_handler()的用法_XML解析器函数
  • 如何取消windows启动管理器
  • 房产公司财务工作内容
  • 商贸企业税收优惠政策
  • php curd
  • php入门课程
  • redis设置内存淘汰策略
  • 企业非流动资产占比多说明什么
  • 以前年度的销售退回,冲减哪年的
  • chkconfig命令参数
  • bat 进入当前文件夹
  • 科技型中小企业查询
  • 小规模附加税减免性质代码如何选
  • 所有者权益变动表怎么填 实例
  • 基本户提取备用金需要带什么资料
  • 职工探亲如何报差旅费
  • 房屋维修费属于什么税收分类编码
  • zabbix安装部署
  • 在建工程会计科目明细
  • 出口货物离岸价差异原因说明表在电子税务局的位置
  • 小规模纳税人季度不超30万免增值税
  • 减值准备的会计科目
  • 购买理财计入现金流量表什么科目
  • 转租收入如何入账
  • 个人怎么缴纳五险一金
  • 公司自建房要交房产税吗
  • 付给农民的土地使用费
  • 企业的未分配利润属于什么科目
  • 事业单位打款多久到账
  • 公司电子发票报销
  • win2000 xp
  • 如何配置samba配置文件
  • centos 安装
  • open bsd
  • windows8whql
  • windows10周年更新
  • windows8.1家庭版安装密钥
  • 场景切换方式
  • nodejs爬取数据
  • css教程推荐
  • android图片库
  • python清除运行结果
  • python日历查询系统
  • python中的
  • python中的命名规范
  • javascript数据结构与算法第三版
  • jquery弹出提示框
  • python中创建自定义函数
  • 江苏差旅费报销管理规定2021
  • 小规模纳税人利润如何缴税
  • 浙江国税咨询电话12306
  • 怎样查询退休审核表
  • 近亲房屋赠与免税费
  • 免责声明:网站部分图片文字素材来源于网络,如有侵权,请及时告知,我们会第一时间删除,谢谢! 邮箱:opceo@qq.com

    鄂ICP备2023003026号

    网站地图: 企业信息 工商信息 财税知识 网络常识 编程技术

    友情链接: 武汉网站建设