15

Next.js+React聊天室|Next仿微信桌面端|next.js聊天实例

 3 years ago
source link: http://www.cnblogs.com/xiaoyan2017/p/14195483.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

一、项目介绍

next-webchat 基于Next.js+React.js+Redux+Antd+RScroll+RLayer等技术构建的PC桌面端仿微信聊天项目。实现了消息/表情发送、图片/视频预览、拖拽/粘贴图片发送、红包/朋友圈等功能。

JFbIJrQ.gif!mobile

qEnqymb.gif!mobile

二、技术实现

  • 技术框架:next.js+react.js+redux+react-redux
  • UI组件库:Antd (蚂蚁金服pc端react组件库)
  • 字体图标:阿里iconfont图标库
  • 弹窗组件:RLayer(基于react.js封装自定义弹窗)
  • 虚拟滚动:RScroll(基于react.js自定义美化滚动条)

7RFnEzn.png!mobile

JnmI3ui.png!mobile

6jAVR3n.png!mobile

UVbeUj3.png!mobile

vQfUnmb.png!mobile

eiUzuqI.png!mobile

BRRRJbU.png!mobile

e6nQbii.png!mobile

uIVjiuv.png!mobile

baEJN3V.png!mobile

BRfEBjY.png!mobile

QjEfqmA.png!mobile

Yvyqm2U.png!mobile

◆ Next.js简述

next.js 是一个基于react.js构建的服务器端SSR框架, star高达59K+ 。让你的网页拥有 SEO 功能。

iuyaMvy.png!mobile

https://www.nextjs.cn/

https://github.com/vercel/next.js

◆ 目录结构

bEvUv2a.png!mobile

◆ next.js/react自定义弹窗组件

项目中没有使用Antd的Dialog弹框,而是自己造了一个react.js桌面端弹窗组件RLayer。

JJnQZrV.png!mobile

如果感兴趣的话,可以看看下面这篇分享文章。

https://www.cnblogs.com/xiaoyan2017/p/14085142.html

◆ next.js/react自定义虚拟滚动条组件

如下图:项目中的滚动条均是自己开发的PC端美化滚动条组件RScroll。

3EfUBb7.gif!mobile

Rscroll支持 原生滚动条、是否自动隐藏、滚动条尺寸/层级/颜色 等功能。

QfuAZbf.gif!mobile

N3AVbq.gif!mobile

◆ next公共布局

next.js自定义公共模板,管理页面入口。新建layouts/index.js页面。

function Layout(props) {
    const router = useRouter()

    // 拦截验证
    useEffect(() => {
        // ...
    }, [])

    return (
    <>
        {/* 配置公共head信息 */}
        <Head>
            <title>Next.js聊天室</title>
            <link rel="icon" href="/favicon.ico" />
            <meta name="keywords" content="Next.js|React.js|Next.js聊天室|Next.js仿微信|React聊天实例"></meta>
            <meta name="description" content="Next-WebChat 基于Next.js+React+Redux构建的服务端渲染聊天应用程序"></meta>
        </Head>

        <div className="next__container flexbox flex-alignc flex-justifyc">
            <div className={utils.classNames('next__wrapper')} style={{ backgroundImage: `url(${props.skin})` }}>
                <div className="next__board flexbox">
                    {/* 右上角按钮 */}
                    <WinBar {...props} />

                    {/* 侧边栏 */}
                    <Sidebar {...props} />

                    {/* 中间栏 */}
                    <Middle />

                    {/* 主体布局 */}
                    <div className="nt__mainbox flex1 flexbox flex-col">
                        {props.children}
                    </div>
                </div>
            </div>
        </div>
    </>
    )
}

Head组件可以配置一些页面 SEO 信息,如: 标题title、关键词keyword、描述description及图标icon 等信息。

◆ next聊天模块

RNNZRji.gif!mobile

聊天编辑框单独分离出了一个editor.js组件,在react中实现div可编辑器 contenteditable 属性处理 聊天输入、表情、光标处插入内容、粘贴截图 等功能。

// react中实现div的contenteditable属性
return (
    <div 
        ref={editorRef}
        className="editor"
        contentEditable="true"
        dangerouslySetInnerHTML={{__html: state.editorText}}
        onClick={handleClicked}
        onInput={handleInput}
        onFocus={handleFocus}
        onBlur={handleBlur}
        style={{userSelect: 'text', WebkitUserSelect: 'text'}}>
    </div>
)

vAnMBfm.gif!mobile

基于RLayer弹窗实现的视频播放功能。

handlePlayVideo = (item, e) => {
    rlayer({
        content: (
            <div className="flexbox flex-col" style={{height: '100%'}}>
                <div className="ntDrag__head"><i className="iconfont icon-bofang"></i> 视频预览</div>
                <div className="ntMain__cont flex1 flexbox flex-col">
                    {/* 视频video */}
                    <video className="vplayer" src={item.videosrc} poster={item.imgsrc} autoPlay preload="auto" controls
                        x5-video-player-fullscreen="true"
                        webkit-playsinline="true"
                        x-webkit-airplay="true"
                        playsInline
                        x5-playsinline="true"
                        style={{height: '100%', width: '100%', objectFit: 'contain', outline: 'none'}}
                    />
                </div>
            </div>
        ),
        layerStyle: {background: '#f6f5ef'},
        opacity: .2,
        area: ['550px', '450px'],
        drag: '.ntDrag__head',
        resize: true,
        maximize: true,
    })
}

编辑框支持拖拽发送图片功能。通过 onDragEnter、onDragOver、onDrop 事件处理拖拽。

handleDragEnter = (e) => {
    e.stopPropagation()
    e.preventDefault()
}
handleDragOver = (e) => {
    e.stopPropagation()
    e.preventDefault()
}
handleDrop = (e) => {
    e.stopPropagation()
    e.preventDefault()
    console.log(e.dataTransfer)

    this.handleFileList(e.dataTransfer)
}
// 获取拖拽文件列表
handleFileList = (filelist) => {
    let files = filelist.files
    if(files.length >= 2) {
        rlayer.message({icon: 'error', content: '暂时支持拖拽一张图片'})
        return false
    }
    for(let i = 0; i < files.length; i++) {
        if(files[i].type != '') {
            this.handleFileAdd(files[i])
        }else {
            rlayer.message({icon: 'error', content: '目前不支持文件夹拖拽功能'})
        }
    }
}
handleFileAdd = (file) => {
    if(file.type.indexOf('image') == -1) {
        rlayer.message({icon: 'error', content: '目前不支持非图片拖拽功能'})
    }else {
        let reader = new FileReader()
        reader.readAsDataURL(file)
        reader.onload = function() {
            let img = this.result

            console.log(img)
        }
    }
}

好了,基于next.js+react实现pc端聊天就分享到这里了。希望大家能喜欢哈~~ :muscle::muscle:

最后附上一个Taro、Nuxt.js+Vue聊天项目

https://www.cnblogs.com/xiaoyan2017/p/13823195.html

https://www.cnblogs.com/xiaoyan2017/p/12039544.html

rY7jUrZ.gif!mobile


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK