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

1、介紹

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

2、測試效果

H5 + 小程序 + App端測試效果以下,實測多端效果均爲一致。(後續大圖統一展現App端)
html

2、技術選型

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

◆ 頂部導航欄headerBarvue

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

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

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

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

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 效果以下圖二app

  

/**
 * @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開發仿微信聊天室的介紹,但願你們能喜歡💪💪~~

◆ 最後附上基於uni-app開發的自定義導航欄及Modal對話框

uniapp自定義導航欄:http://www.javashuo.com/article/p-olinhpvy-dk.html

uniapp模態彈窗組件:http://www.javashuo.com/article/p-dvddrcmu-cq.html

相關文章
相關標籤/搜索