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

来源:https://www.cnblogs.com/xiaoyan2017/archive/2019/10/10/11645467.html
-Advertisement-
Play Games

一、介紹 運用UniApp+Vue+Vuex+swiper+uniPop等技術開發的仿微信原生App聊天室|仿微信聊天界面實例項目uniapp-chatroom,實現了發送圖文消息、表情(gif圖),圖片預覽、地圖位置、長按菜單、紅包/錢包、仿微信朋友圈等功能。 二、測試效果 H5 + 小程式 + ...


一、介紹

運用UniApp+Vue+Vuex+swiper+uniPop等技術開發的仿微信原生App聊天室|仿微信聊天界面實例項目uniapp-chatroom,實現了發送圖文消息、表情(gif圖),圖片預覽、地圖位置、長按菜單、紅包/錢包、仿微信朋友圈等功能。

二、測試效果

H5 + 小程式 + App端測試效果如下,實測多端效果均為一致。(後續大圖統一展示App端)

二、技術選型

  • 編輯器:HBuilder X
  • 技術框架:uni-app + vue
  • 狀態管理:Vuex
  • iconfont圖標:阿裡字體圖標庫
  • 自定義導航欄 + 底部Tabbar
  • 彈窗組件:uniPop(基於uni-app封裝模態彈窗)
  • 測試環境:H5端 + 小程式 + App端(三端均相容)
  • 高德地圖:vue-amap

◆ 頂部導航欄headerBar

頂部導航欄採用的是自定義模式,具體可參看這篇文章:uni-app自定義導航欄按鈕|uniapp仿微信頂部導航條

在pages.json裡面配置globalStyle,將navigationStyle設為custom時,原生頂部導航欄不顯示,這時就能自定義導航欄

 "globalStyle": {"navigationStyle": "custom"} 

◆ 引入公共樣式/組件及全局彈窗

import Vue from 'vue'
import App from './App'

// >>>引入css
import './assets/fonts/iconfont.css'
import './assets/css/reset.css'
import './assets/css/layout.css'

// >>>引入狀態管理
import store from './store'
Vue.prototype.$store = store

// >>>引入公共組件
import headerBar from './components/header/header.vue'
import tabBar from './components/tabbar/tabbar.vue'
import popupWindow from './components/popupWindow.vue'
Vue.component('header-bar', headerBar)
Vue.component('tab-bar', tabBar)
Vue.component('popup-window', popupWindow)

// >>>引入uniPop彈窗組件
import uniPop from './components/uniPop/uniPop.vue'
Vue.component('uni-pop', uniPop)

Vue.config.productionTip = false
App.mpType = 'app'

const app = new Vue({
    ...App
})
app.$mount()

◆ Vuex + uniapp登錄驗證

import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex)

export default new Vuex.Store({
    state: {
        user: uni.getStorageSync('user'),
        token: uni.getStorageSync('token'),
    },
    mutations: {
        // 存儲token
        SET_TOKEN(state, data) {
            state.token = data
            uni.setStorageSync('token', data)
        },
        // 存儲用戶名
        SET_USER(state, data) {
            state.user = data
            uni.setStorageSync('user', data)
        },
        ...
    },
})
<script>
    import { mapState, mapMutations } from 'vuex'
    import util from '../../utils/util.js'
    
    export default {
        data() {
            return {
                formObj: {},
            }
        },
        computed: {
            ...mapState(['user', 'token'])
        },
        mounted() {
            // 判斷是否有登錄
            if(this.user){
                uni.redirectTo({url: '/pages/index/index'})
            }
        },
        methods: {
            // 提交表單
            handleSubmit(e) {
                ...
            }
        }
    }
</script>

◆ 仿微信朋友圈透明導航欄

通過onPageScroll函數實現自定義導航上下滑動自動調整導航欄的透明度,滑動到距離頂部200 效果如下圖二

  

/**
 * @tpl 朋友圈模板
 */

<template>
    <view class="flexbox flex_col">
        <header-bar :isBack="true" title="朋友圈" :bgColor="{background: headerBarBackground}" transparent>
            <text slot="back" class="uni_btnIco iconfont icon-arrL"></text>
            <text slot="iconfont" class="uni_btnIco iconfont icon-publish mr_5" @tap="handlePublish"></text>
        </header-bar>
        
        <view class="uni__scrollview flex1">
            <view class="uni-friendZone">
                ...
            </view>
        </view>
    </view>
</template>

<script>
    export default {
        data() {
            return {
                headerBarBackground: 'transparent'
            }
        },
        onPageScroll : function(e) {
            // console.log("滾動距離為:" + e.scrollTop);
            this.headerBarBackground = 'rgba(65,168,99,'+e.scrollTop / 200+')'
        },
        methods: {
            ...
        }
    }
</script>

<style scoped>

</style>

◆ uniapp實現聊天頁面滾動至底部

在h5端將聊天頁面滾動到底部很好實現,小程式中通過設置scroll-view屬性scroll-into-view的值也能實現,可是在uni-app裡面怎麼將聊天信息滾動至底部呢?

uni-app通過判斷聊天內容高度和scroll-view高度的大小設置滾動距離

<scroll-view id="scrollview" scroll-y="true" :scroll-top="scrollTop" style="height: 100%;">
    <view class="uni-chatMsgCnt" id="msglistview">
        <view class="msgitem">xxx</view>
        <view class="msgitem">xxx</view>
        <view class="msgitem">xxx</view>
        ...
    </view>
</scroll-view>
export default {
    data() {
        return {
            scrollTop: 0,
            ...
        }
    },
    mounted() {
        this.scrollToBottom()
    },
    updated() {
        this.scrollToBottom()
    },
    methods: {
        // 滾動至聊天底部
        scrollToBottom(t) {
            let that = this
            let query = uni.createSelectorQuery()
            query.select('#scrollview').boundingClientRect()
            query.select('#msglistview').boundingClientRect()
            query.exec((res) => {
                // console.log(res)
                if(res[1].height > res[0].height){
                    that.scrollTop = res[1].height - res[0].height
                }
            })
        },
        ...
    }
}

◆ uniapp聊天代碼片段

<script>
    const emotionJson = require('./mock-emotion.js')
    const messageJson = require('./mock-chat.js')
    
    export default {
        data() {
            return {
                scrollTop: 0,
                
                showFootToolbar: false,
                showEmotionChoose: false,
                
                editorText: '',
                editorLastCursor: null,
                
                // 表情json
                emotionList: emotionJson,
                
                // 消息記錄
                messageList: messageJson,
                
                // 預覽圖片臨時數組
                previewImgArray: [],
            }
        },
        mounted() {
            this.scrollToBottom()
        },
        updated() {
            this.scrollToBottom()
        },
        methods: {
            // 滾動至聊天底部
            scrollToBottom(t) {
                let that = this
                let query = uni.createSelectorQuery()
                query.select('#scrollview').boundingClientRect()
                query.select('#msglistview').boundingClientRect()
                query.exec((res) => {
                    // console.log(res)
                    if(res[1].height > res[0].height){
                        that.scrollTop = res[1].height - res[0].height
                    }
                })
            },
            
            // 點擊聊天消息區域
            msgPanelTaped() {
                if(!this.showFootToolbar) return
                this.showFootToolbar = false
            },
            
            // 表情、選擇區切換
            swtEmotionChooseView(bool) {
                this.showFootToolbar = true
                this.showEmotionChoose = bool
            },
            
            ...
            
            // 點擊表情
            handleEmotionTaped(emoj) {
                if(emoj == 'del') return
                // 在游標處插入表情
                let startStr = this.editorText.substr(0, this.editorLastCursor)
                let endStr = this.editorText.substr(this.editorLastCursor)
                this.editorText = startStr + `${emoj}` + endStr
            },
            
            
            // >>> 【選擇區功能模塊】------------------------------------------
            // 選擇圖片
            handleLaunchImage() {
                let that = this
                let msglist = this.messageList
                let len = msglist.length
                // 消息隊列
                let data = {
                    id: `msg${++len}`,
                    msgtype: 5,
                    isme: true,
                    avator: '/static/uimg/u__chat_img1.jpg',
                    author: 'King',
                    msg: '',
                    imgsrc: '',
                    videosrc: ''
                }
                
                uni.chooseImage({
                    count: 1,
                    sourceType: ['album'],
                    success: function(res){
                        // console.log(res)
                        // console.log(res.tempFilePaths)
                        data.imgsrc = res.tempFilePaths.toString()
                        msglist = msglist.concat(data)
                        that.messageList = msglist
                    }
                })
            },
            
            ...
            
            // 位置
            handleChooseLocation() {
                let that = this
                let msglist = this.messageList
                let len = msglist.length
                // 消息隊列
                let data = {
                    id: `msg${++len}`,
                    msgtype: 8,
                    isme: true,
                    avator: '/static/uimg/u__chat_img1.jpg',
                    author: 'King',
                    msg: '',
                    imgsrc: '',
                    videosrc: ''
                }
                
                uni.chooseLocation({
                    success: (res) => {
                        console.log(res)
                        // 插入消息
                        data.msg = {
                            name: res.name,
                            address: res.address,
                            latitude: res.latitude,
                            longitude: res.longitude
                        }
                        msglist = msglist.concat(data)
                        that.messageList = msglist
                    }
                })
            },
            
        }
    }
</script>

以上就是基於uniapp開發仿微信聊天室的介紹,希望大家能喜歡

您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • Mysql常用命令行大全 1、連接Mysql 格式: mysql -h主機地址 -u用戶名 -p用戶密碼1、連接到本機上的MYSQL。首先打開DOS視窗,然後進入目錄mysql\bin,再鍵入命令mysql -u root -p,回車後提示你輸密碼.註意用戶名前可以有空格也可以沒有空格,但是密碼前必 ...
  • 此題相較於 做了一些改進: 創建 ; 需要判斷傳入參數的合理性. 因此,對代碼改動如下所示: mysql CREATE FUNCTION getNthHighestSalary(N INT) RETURNS INT BEGIN DECLARE P INT DEFAULT N 1; IF (P ...
  • //OBJC_ASSOCIATION_ASSIGN類似於我們常用的assign,assign策略的特點就是在對象釋放以後,不會主動將應用的對象置為nil,這樣會有訪問僵屍對象導致應用崩潰的風險。為瞭解決這個問題:我們可以創建一個替身對象,以OBJC_ASSOCIATION_RETAIN_NONATO ...
  • 一、isa指針結構 分析: 1.我們知道,實例對象的isa指針指向該對象所屬類的類對象;類對象的isa指向其元類對象; 2.真機為arm64架構,模擬器和mac電腦為x86架架構,以下以arm64為例講解; 3.在64位系統下,指針所占位元組為8個即64位; 4.在arm64之前,isa就是一個普通的 ...
  • 前段時間因為一個bug,研究了一下android binder的大概流程,方便自己理解畫了一個框圖。 粗點線箭頭是繼承關係,細實線箭頭是調用關係。 ...
  • 最近需要實現導航功能,其中路線規劃和導航場景如下圖所示: 上面的截圖中,路線上面都繪製出了路名,方便用戶查看自己選擇的路線都經過了哪些道路。這裡用到的地圖的能力即為 騰訊地圖 Android SDK v4.2.7 已經開放了實現此功能的能力。 主要涉及介面如下: 介面名稱 | 功能概述 : | : ...
  • axios的除了初始化配置外,其它有用的應該就是攔截器了,攔截器分為請求攔截器和響應攔截器兩種: 請求攔截器 ;在請求發送前進行一些操作,例如在每個請求體裡加上token,統一做了處理如果以後要改也非常容易。 響應攔截器 ;是在接收到響應後進行一些操作,例如在伺服器返回登錄狀態失效,需要重新登錄的時 ...
  • XML Schema XSD (XML Schema Definition)是W3C於2001年5月發佈的推薦標準,指出如何形式描述XML文檔的元素。XSD是許多XML Schema 語言中的一支。XSD是首先分離於XML本身的schema語言,故獲取W3C的推薦地位。 像所有XML Schema ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...