東偉練 發表於 2019-10-10 02:22:00

uni-app聊天室|vue+uniapp仿微信聊天实例|uniapp仿微信App界面

<h3 id="一项目简介">一、介绍</h3>
<p><span style="font-size: 12px; font-family: &quot;comic sans ms&quot;, sans-serif; background-color: rgba(204, 255, 204, 1)">运用UniApp+Vue+Vuex+swiper+uniPop等技术开发的仿微信原生App聊天室|仿微信聊天界面实例项目uniapp-chatroom,实现了发送图文消息、表情(gif图),图片预览、地图位置、长按菜单、红包/钱包、仿微信朋友圈等功能。</span></p>
<h3>二、测试效果</h3>
<p><span style="font-size: 12px; font-family: &quot;comic sans ms&quot;, sans-serif">H5 + 小程序 + App端测试效果如下,实测多端效果均为一致。(<em>后续大图统一展示App端</em>)<br></span></p>
<p><span style="font-size: 12px; font-family: &quot;comic sans ms&quot;, sans-serif"><img src="https://img2018.cnblogs.com/blog/1289798/201910/1289798-20191010003758483-1629155986.png"></span></p>
<h3 id="三技术栈">二、技术选型</h3>
<ul>
<li><span style="font-size: 12px; font-family: &quot;comic sans ms&quot;, sans-serif">编辑器:HBuilder X</span></li>
<li><span style="font-size: 12px; font-family: &quot;comic sans ms&quot;, sans-serif">技术框架:uni-app + vue</span></li>
<li><span style="font-size: 12px; font-family: &quot;comic sans ms&quot;, sans-serif">状态管理:Vuex</span></li>
<li><span style="font-size: 12px; font-family: &quot;comic sans ms&quot;, sans-serif">iconfont图标:阿里字体图标库</span></li>
<li><span style="font-size: 12px; font-family: &quot;comic sans ms&quot;, sans-serif">自定义导航栏 + 底部Tabbar</span></li>
<li><span style="font-size: 12px; font-family: &quot;comic sans ms&quot;, sans-serif">弹窗组件:uniPop(基于uni-app封装模态弹窗)</span></li>
<li><span style="font-size: 12px; font-family: &quot;comic sans ms&quot;, sans-serif">测试环境:H5端 + 小程序 + App端(三端均兼容)</span></li>
<li><span style="font-size: 12px; font-family: &quot;comic sans ms&quot;, sans-serif">高德地图:vue-amap</span></li>



</ul>
<p><img src="https://img2018.cnblogs.com/blog/1289798/201910/1289798-20191010004218438-1400632737.png"></p>
<p><img src="https://img2018.cnblogs.com/blog/1289798/201910/1289798-20191010004303809-489794493.png"></p>
<p><img src="https://img2018.cnblogs.com/blog/1289798/201910/1289798-20191010004349771-120474864.png"></p>
<p><img src="https://img2018.cnblogs.com/blog/1289798/201910/1289798-20191010004402254-429063375.png"></p>
<p><img src="https://img2018.cnblogs.com/blog/1289798/201910/1289798-20191010004425786-511791844.png"></p>
<p><img src="https://img2018.cnblogs.com/blog/1289798/201910/1289798-20191010004514789-174277741.png"></p>
<p><img src="https://img2018.cnblogs.com/blog/1289798/201910/1289798-20191010004554495-65117077.png"></p>
<p><img src="https://img2018.cnblogs.com/blog/1289798/201910/1289798-20191010004606680-627436560.png"></p>
<p><img src="https://img2018.cnblogs.com/blog/1289798/201910/1289798-20191010004649694-1329302841.png"></p>
<p><img src="https://img2018.cnblogs.com/blog/1289798/201910/1289798-20191010004811400-1984924237.png"></p>
<p><img src="https://img2018.cnblogs.com/blog/1289798/201910/1289798-20191010004951752-1301321460.png"></p>
<p><img src="https://img2018.cnblogs.com/blog/1289798/201910/1289798-20191010005024855-1157545928.png"></p>
<p><img src="https://img2018.cnblogs.com/blog/1289798/201910/1289798-20191010005159974-788593951.png"></p>
<p><img src="https://img2018.cnblogs.com/blog/1289798/201910/1289798-20191010005215710-2038068021.png"></p>
<p><img src="https://img2018.cnblogs.com/blog/1289798/201910/1289798-20191010005246613-796423085.png"></p>
<p><strong>◆ 顶部导航栏headerBar</strong></p>
<p><span style="font-size: 12px">顶部导航栏采用的是自定义模式,具体可参看这篇文章:uni-app自定义导航栏按钮|uniapp仿微信顶部导航条</span></p>
<p><span style="font-size: 12px">在pages.json里面配置globalStyle,将navigationStyle设为custom时,原生顶部导航栏不显示,这时就能自定义导航栏</span></p>
<p><span style="font-size: 12px">&nbsp;<span class="cnblogs_code">"globalStyle": {"navigationStyle": "custom"}</span>&nbsp;</span></p>
<p><strong>◆ 引入公共样式/组件及全局弹窗</strong></p>
<div class="cnblogs_code">
<pre>import Vue from 'vue'<span style="color: rgba(0, 0, 0, 1)">
import App from </span>'./App'

<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> &gt;&gt;&gt;引入css</span>
import './assets/fonts/iconfont.css'<span style="color: rgba(0, 0, 0, 1)">
import </span>'./assets/css/reset.css'<span style="color: rgba(0, 0, 0, 1)">
import </span>'./assets/css/layout.css'

<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> &gt;&gt;&gt;引入状态管理</span>
import store from './store'<span style="color: rgba(0, 0, 0, 1)">
Vue.prototype.$store </span>=<span style="color: rgba(0, 0, 0, 1)"> store

</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> &gt;&gt;&gt;引入公共组件</span>
import headerBar from './components/header/header.vue'<span style="color: rgba(0, 0, 0, 1)">
import tabBar from </span>'./components/tabbar/tabbar.vue'<span style="color: rgba(0, 0, 0, 1)">
import popupWindow from </span>'./components/popupWindow.vue'<span style="color: rgba(0, 0, 0, 1)">
Vue.component(</span>'header-bar'<span style="color: rgba(0, 0, 0, 1)">, headerBar)
Vue.component(</span>'tab-bar'<span style="color: rgba(0, 0, 0, 1)">, tabBar)
Vue.component(</span>'popup-window'<span style="color: rgba(0, 0, 0, 1)">, popupWindow)

</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> &gt;&gt;&gt;引入uniPop弹窗组件</span>
import uniPop from './components/uniPop/uniPop.vue'<span style="color: rgba(0, 0, 0, 1)">
Vue.component(</span>'uni-pop'<span style="color: rgba(0, 0, 0, 1)">, uniPop)

Vue.config.productionTip </span>= <span style="color: rgba(0, 0, 255, 1)">false</span><span style="color: rgba(0, 0, 0, 1)">
App.mpType </span>= 'app'<span style="color: rgba(0, 0, 0, 1)">

const app </span>= <span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> Vue({
    ...App
})
app.$mount()</span></pre>
</div>
<p><span style="font-size: 18px; font-family: 宋体, &quot;Songti SC&quot;; background-color: rgba(0, 255, 255, 1)">uniapp自定义Navbar+Tabbar组件已经发布到了插件市场,免费下载使用。</span></p>
<p><span style="font-size: 12px">https://ext.dcloud.net.cn/plugin?id=5592</span><br><span style="font-size: 12px">https://ext.dcloud.net.cn/plugin?id=5593</span></p>
<p>&nbsp;</p>
<p><strong>◆ Vuex + uniapp登录验证</strong></p>
<div class="cnblogs_code">
<pre>import Vue from 'vue'<span style="color: rgba(0, 0, 0, 1)">
import Vuex from </span>'vuex'<span style="color: rgba(0, 0, 0, 1)">

Vue.use(Vuex)

export </span><span style="color: rgba(0, 0, 255, 1)">default</span> <span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> Vuex.Store({
    state: {
      user: uni.getStorageSync(</span>'user'<span style="color: rgba(0, 0, 0, 1)">),
      token: uni.getStorageSync(</span>'token'<span style="color: rgba(0, 0, 0, 1)">),
    },
    mutations: {
      </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 存储token</span>
<span style="color: rgba(0, 0, 0, 1)">      SET_TOKEN(state, data) {
            state.token </span>=<span style="color: rgba(0, 0, 0, 1)"> data
            uni.setStorageSync(</span>'token'<span style="color: rgba(0, 0, 0, 1)">, data)
      },
      </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 存储用户名</span>
<span style="color: rgba(0, 0, 0, 1)">      SET_USER(state, data) {
            state.user </span>=<span style="color: rgba(0, 0, 0, 1)"> data
            uni.setStorageSync(</span>'user'<span style="color: rgba(0, 0, 0, 1)">, data)
      },
      ...
    },
})</span></pre>
</div>
<div class="cnblogs_code">
<pre>&lt;script&gt;<span style="color: rgba(0, 0, 0, 1)">
    import { mapState, mapMutations } from </span>'vuex'<span style="color: rgba(0, 0, 0, 1)">
    import util from </span>'../../utils/util.js'<span style="color: rgba(0, 0, 0, 1)">
   
    export </span><span style="color: rgba(0, 0, 255, 1)">default</span><span style="color: rgba(0, 0, 0, 1)"> {
      data() {
            </span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> {
                formObj: {},
            }
      },
      computed: {
            ...mapState([</span>'user', 'token'<span style="color: rgba(0, 0, 0, 1)">])
      },
      mounted() {
            </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 判断是否有登录</span>
            <span style="color: rgba(0, 0, 255, 1)">if</span>(<span style="color: rgba(0, 0, 255, 1)">this</span><span style="color: rgba(0, 0, 0, 1)">.user){
                uni.redirectTo({url: </span>'/pages/index/index'<span style="color: rgba(0, 0, 0, 1)">})
            }
      },
      methods: {
            </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 提交表单</span>
<span style="color: rgba(0, 0, 0, 1)">            handleSubmit(e) {
                ...
            }
      }
    }
</span>&lt;/script&gt;</pre>
</div>
<p><strong>◆ 仿微信朋友圈透明导航栏</strong></p>
<p><span style="font-size: 12px; font-family: &quot;comic sans ms&quot;, sans-serif">通过onPageScroll函数实现自定义导航上下滑动自动调整导航栏的透明度,滑动到距离顶部200 效果如下图二</span></p>
<p><span style="font-size: 12px; font-family: &quot;comic sans ms&quot;, sans-serif"><img src="https://img2018.cnblogs.com/blog/1289798/201910/1289798-20191010014210885-1098056404.png">&nbsp;&nbsp;<img src="https://img2018.cnblogs.com/blog/1289798/201910/1289798-20191010014219056-766472638.png"></span></p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 128, 0, 1)">/*</span><span style="color: rgba(0, 128, 0, 1)">*
* @tpl 朋友圈模板
</span><span style="color: rgba(0, 128, 0, 1)">*/</span>

&lt;template&gt;
    &lt;view class="flexbox flex_col"&gt;
      &lt;header-bar :isBack="true" title="朋友圈" :bgColor="{background: headerBarBackground}" transparent&gt;
            &lt;text slot="back" class="uni_btnIco iconfont icon-arrL"&gt;&lt;/text&gt;
            &lt;text slot="iconfont" class="uni_btnIco iconfont icon-publish mr_5" @tap="handlePublish"&gt;&lt;/text&gt;
      &lt;/header-bar&gt;
      
      &lt;view class="uni__scrollview flex1"&gt;
            &lt;view class="uni-friendZone"&gt;<span style="color: rgba(0, 0, 0, 1)">
                ...
            </span>&lt;/view&gt;
      &lt;/view&gt;
    &lt;/view&gt;
&lt;/template&gt;

&lt;script&gt;<span style="color: rgba(0, 0, 0, 1)">
    export </span><span style="color: rgba(0, 0, 255, 1)">default</span><span style="color: rgba(0, 0, 0, 1)"> {
      data() {
            </span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> {
                headerBarBackground: </span>'transparent'<span style="color: rgba(0, 0, 0, 1)">
            }
      },
      onPageScroll : </span><span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)">(e) {
            </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> console.log("滚动距离为:" + e.scrollTop);</span>
            <span style="color: rgba(0, 0, 255, 1)">this</span>.headerBarBackground = 'rgba(65,168,99,'+e.scrollTop / 200+')'<span style="color: rgba(0, 0, 0, 1)">
      },
      methods: {
            ...
      }
    }
</span>&lt;/script&gt;

&lt;style scoped&gt;

&lt;/style&gt;</pre>
</div>
<p><strong>◆ uniapp实现聊天页面滚动至底部</strong></p>
<p><span style="font-size: 12px; font-family: &quot;comic sans ms&quot;, sans-serif">在h5端将聊天页面滚动到底部很好实现,小程序中通过设置scroll-view属性scroll-into-view的值也能实现,可是在uni-app里面怎么将聊天信息滚动至底部呢?</span></p>
<p><span style="font-size: 12px; font-family: &quot;comic sans ms&quot;, sans-serif"><img src="https://img2018.cnblogs.com/blog/1289798/201910/1289798-20191010020642218-886677506.png"></span></p>
<p><span style="font-size: 12px; font-family: &quot;comic sans ms&quot;, sans-serif; background-color: rgba(230, 229, 228, 1)">uni-app通过判断聊天内容高度和scroll-view高度的大小设置滚动距离</span></p>
<div class="cnblogs_code">
<pre>&lt;scroll-view id="scrollview" scroll-y="true" :scroll-top="scrollTop" style="height: 100%;"&gt;
    &lt;view class="uni-chatMsgCnt" id="msglistview"&gt;
      &lt;view class="msgitem"&gt;xxx&lt;/view&gt;
      &lt;view class="msgitem"&gt;xxx&lt;/view&gt;
      &lt;view class="msgitem"&gt;xxx&lt;/view&gt;
<span style="color: rgba(0, 0, 0, 1)">      ...
    </span>&lt;/view&gt;
&lt;/scroll-view&gt;</pre>
</div>
<div class="cnblogs_code">
<pre>export <span style="color: rgba(0, 0, 255, 1)">default</span><span style="color: rgba(0, 0, 0, 1)"> {
    data() {
      </span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> {
            scrollTop: </span>0<span style="color: rgba(0, 0, 0, 1)">,
            ...
      }
    },
    mounted() {
      </span><span style="color: rgba(0, 0, 255, 1)">this</span><span style="color: rgba(0, 0, 0, 1)">.scrollToBottom()
    },
    updated() {
      </span><span style="color: rgba(0, 0, 255, 1)">this</span><span style="color: rgba(0, 0, 0, 1)">.scrollToBottom()
    },
    methods: {
      </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 滚动至聊天底部</span>
<span style="color: rgba(0, 0, 0, 1)">      scrollToBottom(t) {
            let that </span>= <span style="color: rgba(0, 0, 255, 1)">this</span><span style="color: rgba(0, 0, 0, 1)">
            let query </span>=<span style="color: rgba(0, 0, 0, 1)"> uni.createSelectorQuery()
            query.select(</span>'#scrollview'<span style="color: rgba(0, 0, 0, 1)">).boundingClientRect()
            query.select(</span>'#msglistview'<span style="color: rgba(0, 0, 0, 1)">).boundingClientRect()
            query.exec((res) </span>=&gt;<span style="color: rgba(0, 0, 0, 1)"> {
                </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> console.log(res)</span>
                <span style="color: rgba(0, 0, 255, 1)">if</span>(res.height &gt; res.height){
                  that.scrollTop </span>= res.height - res.height
                }
            })
      },
      ...
    }
}</span></pre>
</div>
<p><strong>◆ uniapp聊天代码片段</strong></p>
<div class="cnblogs_code">
<pre>&lt;script&gt;<span style="color: rgba(0, 0, 0, 1)">
    const emotionJson </span>= require('./mock-emotion.js'<span style="color: rgba(0, 0, 0, 1)">)
    const messageJson </span>= require('./mock-chat.js'<span style="color: rgba(0, 0, 0, 1)">)
   
    export </span><span style="color: rgba(0, 0, 255, 1)">default</span><span style="color: rgba(0, 0, 0, 1)"> {
      data() {
            </span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> {
                scrollTop: </span>0<span style="color: rgba(0, 0, 0, 1)">,
               
                showFootToolbar: </span><span style="color: rgba(0, 0, 255, 1)">false</span><span style="color: rgba(0, 0, 0, 1)">,
                showEmotionChoose: </span><span style="color: rgba(0, 0, 255, 1)">false</span><span style="color: rgba(0, 0, 0, 1)">,
               
                editorText: </span>''<span style="color: rgba(0, 0, 0, 1)">,
                editorLastCursor: </span><span style="color: rgba(0, 0, 255, 1)">null</span><span style="color: rgba(0, 0, 0, 1)">,
               
                </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 表情json</span>
<span style="color: rgba(0, 0, 0, 1)">                emotionList: emotionJson,
               
                </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 消息记录</span>
<span style="color: rgba(0, 0, 0, 1)">                messageList: messageJson,
               
                </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 预览图片临时数组</span>
<span style="color: rgba(0, 0, 0, 1)">                previewImgArray: [],
            }
      },
      mounted() {
            </span><span style="color: rgba(0, 0, 255, 1)">this</span><span style="color: rgba(0, 0, 0, 1)">.scrollToBottom()
      },
      updated() {
            </span><span style="color: rgba(0, 0, 255, 1)">this</span><span style="color: rgba(0, 0, 0, 1)">.scrollToBottom()
      },
      methods: {
            </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 滚动至聊天底部</span>
<span style="color: rgba(0, 0, 0, 1)">            scrollToBottom(t) {
                let that </span>= <span style="color: rgba(0, 0, 255, 1)">this</span><span style="color: rgba(0, 0, 0, 1)">
                let query </span>=<span style="color: rgba(0, 0, 0, 1)"> uni.createSelectorQuery()
                query.select(</span>'#scrollview'<span style="color: rgba(0, 0, 0, 1)">).boundingClientRect()
                query.select(</span>'#msglistview'<span style="color: rgba(0, 0, 0, 1)">).boundingClientRect()
                query.exec((res) </span>=&gt;<span style="color: rgba(0, 0, 0, 1)"> {
                  </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> console.log(res)</span>
                  <span style="color: rgba(0, 0, 255, 1)">if</span>(res.height &gt; res.height){
                        that.scrollTop </span>= res.height - res.height
                  }
                })
            },
            
            </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 点击聊天消息区域</span>
<span style="color: rgba(0, 0, 0, 1)">            msgPanelTaped() {
                </span><span style="color: rgba(0, 0, 255, 1)">if</span>(!<span style="color: rgba(0, 0, 255, 1)">this</span>.showFootToolbar) <span style="color: rgba(0, 0, 255, 1)">return</span>
                <span style="color: rgba(0, 0, 255, 1)">this</span>.showFootToolbar = <span style="color: rgba(0, 0, 255, 1)">false</span><span style="color: rgba(0, 0, 0, 1)">
            },
            
            </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 表情、选择区切换</span>
<span style="color: rgba(0, 0, 0, 1)">            swtEmotionChooseView(bool) {
                </span><span style="color: rgba(0, 0, 255, 1)">this</span>.showFootToolbar = <span style="color: rgba(0, 0, 255, 1)">true</span>
                <span style="color: rgba(0, 0, 255, 1)">this</span>.showEmotionChoose =<span style="color: rgba(0, 0, 0, 1)"> bool
            },
            
            ...
            
            </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 点击表情</span>
<span style="color: rgba(0, 0, 0, 1)">            handleEmotionTaped(emoj) {
                </span><span style="color: rgba(0, 0, 255, 1)">if</span>(emoj == 'del') <span style="color: rgba(0, 0, 255, 1)">return</span>
                <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 在光标处插入表情</span>
                let startStr = <span style="color: rgba(0, 0, 255, 1)">this</span>.editorText.substr(0, <span style="color: rgba(0, 0, 255, 1)">this</span><span style="color: rgba(0, 0, 0, 1)">.editorLastCursor)
                let endStr </span>= <span style="color: rgba(0, 0, 255, 1)">this</span>.editorText.substr(<span style="color: rgba(0, 0, 255, 1)">this</span><span style="color: rgba(0, 0, 0, 1)">.editorLastCursor)
                </span><span style="color: rgba(0, 0, 255, 1)">this</span>.editorText = startStr + `${emoj}` +<span style="color: rgba(0, 0, 0, 1)"> endStr
            },
            
            
            </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> &gt;&gt;&gt; 【选择区功能模块】------------------------------------------</span>
            <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 选择图片</span>
<span style="color: rgba(0, 0, 0, 1)">            handleLaunchImage() {
                let that </span>= <span style="color: rgba(0, 0, 255, 1)">this</span><span style="color: rgba(0, 0, 0, 1)">
                let msglist </span>= <span style="color: rgba(0, 0, 255, 1)">this</span><span style="color: rgba(0, 0, 0, 1)">.messageList
                let len </span>=<span style="color: rgba(0, 0, 0, 1)"> msglist.length
                </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 消息队列</span>
                let data =<span style="color: rgba(0, 0, 0, 1)"> {
                  id: `msg${</span>++<span style="color: rgba(0, 0, 0, 1)">len}`,
                  msgtype: </span>5<span style="color: rgba(0, 0, 0, 1)">,
                  isme: </span><span style="color: rgba(0, 0, 255, 1)">true</span><span style="color: rgba(0, 0, 0, 1)">,
                  avator: </span>'/static/uimg/u__chat_img1.jpg'<span style="color: rgba(0, 0, 0, 1)">,
                  author: </span>'King'<span style="color: rgba(0, 0, 0, 1)">,
                  msg: </span>''<span style="color: rgba(0, 0, 0, 1)">,
                  imgsrc: </span>''<span style="color: rgba(0, 0, 0, 1)">,
                  videosrc: </span>''<span style="color: rgba(0, 0, 0, 1)">
                }
               
                uni.chooseImage({
                  count: </span>1<span style="color: rgba(0, 0, 0, 1)">,
                  sourceType: [</span>'album'<span style="color: rgba(0, 0, 0, 1)">],
                  success: </span><span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)">(res){
                        </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> console.log(res)</span>
                        <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> console.log(res.tempFilePaths)</span>
                        data.imgsrc =<span style="color: rgba(0, 0, 0, 1)"> res.tempFilePaths.toString()
                        msglist </span>=<span style="color: rgba(0, 0, 0, 1)"> msglist.concat(data)
                        that.messageList </span>=<span style="color: rgba(0, 0, 0, 1)"> msglist
                  }
                })
            },
            
            ...
            
            </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 位置</span>
<span style="color: rgba(0, 0, 0, 1)">            handleChooseLocation() {
                let that </span>= <span style="color: rgba(0, 0, 255, 1)">this</span><span style="color: rgba(0, 0, 0, 1)">
                let msglist </span>= <span style="color: rgba(0, 0, 255, 1)">this</span><span style="color: rgba(0, 0, 0, 1)">.messageList
                let len </span>=<span style="color: rgba(0, 0, 0, 1)"> msglist.length
                </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 消息队列</span>
                let data =<span style="color: rgba(0, 0, 0, 1)"> {
                  id: `msg${</span>++<span style="color: rgba(0, 0, 0, 1)">len}`,
                  msgtype: </span>8<span style="color: rgba(0, 0, 0, 1)">,
                  isme: </span><span style="color: rgba(0, 0, 255, 1)">true</span><span style="color: rgba(0, 0, 0, 1)">,
                  avator: </span>'/static/uimg/u__chat_img1.jpg'<span style="color: rgba(0, 0, 0, 1)">,
                  author: </span>'King'<span style="color: rgba(0, 0, 0, 1)">,
                  msg: </span>''<span style="color: rgba(0, 0, 0, 1)">,
                  imgsrc: </span>''<span style="color: rgba(0, 0, 0, 1)">,
                  videosrc: </span>''<span style="color: rgba(0, 0, 0, 1)">
                }
               
                uni.chooseLocation({
                  success: (res) </span>=&gt;<span style="color: rgba(0, 0, 0, 1)"> {
                        console.log(res)
                        </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 插入消息</span>
                        data.msg =<span style="color: rgba(0, 0, 0, 1)"> {
                            name: res.name,
                            address: res.address,
                            latitude: res.latitude,
                            longitude: res.longitude
                        }
                        msglist </span>=<span style="color: rgba(0, 0, 0, 1)"> msglist.concat(data)
                        that.messageList </span>=<span style="color: rgba(0, 0, 0, 1)"> msglist
                  }
                })
            },
            
      }
    }
</span>&lt;/script&gt;</pre>
</div>
<p><span style="font-size: 12px">以上就是基于uniapp开发仿微信聊天室的介绍,希望大家能喜欢💪💪~~</span></p>
<p><span style="font-size: 12px"><strong>附上几个最新原创研发的实例项目</strong></span></p>
<blockquote>
<p><span style="font-size: 12px">uniapp+vue3聊天室|uni-app+vite4+uv-ui跨端仿微信app聊天语音/朋友圈</span></p>
<p><span style="font-size: 12px">uniapp-vue3-oadmin手机后台实例|vite5.x+uniapp多端仿ios管理系统</span></p>
<p><span style="font-size: 12px">uniapp-welive仿微信/抖音直播带货|uni-app+vue3+pinia短视频直播商城</span></p>
<p><span style="font-size: 12px">Vite5+Electron聊天室|electron31跨平台仿微信EXE客户端|vue3聊天程序</span></p>
<p><span style="font-size: 12px">Electron31-Vue3Admin管理系统|vite5+electron+pinia桌面端后台Exe</span></p>
<p><span style="font-size: 12px">Electron32-ViteOS桌面版os系统|vue3+electron+arco客户端OS管理模板</span></p>
</blockquote>
<p>&nbsp;</p>

</div>
<div id="MySignature" role="contentinfo">
    本文为博主原创文章,未经博主允许不得转载,欢迎大家一起交流 QQ(282310962) wx(xy190310)<br><br>
来源:https://www.cnblogs.com/xiaoyan2017/p/11645467.html
頁: [1]
查看完整版本: uni-app聊天室|vue+uniapp仿微信聊天实例|uniapp仿微信App界面