Vue 聊天发送图片

1,418 阅读1分钟

小知识,大挑战!本文正在参与“程序员必备小知识”创作活动

Vue 聊天发送图片

上一篇文章讲了发送emoji表情,这一篇就讲讲发送图片 vue聊天发送emoji 表情 文章开始之前,先说说业务:用户点击图片上传按钮会将图片上传到oss上,可能有人对oss不太了解,这里简单说几句

OSS

阿里云对象存储OSS(Object Storage Service)是一款海量、安全、低成本、高可靠的云存储服务,提供99.9999999999%(12个9)的数据持久性,99.995%的数据可用性。多种存储类型供选择,全面优化存储成本。

给出文档 help.aliyun.com/document_de… 这个是收费的,如果你不想花钱,只想模拟一下此功能,随便写个上传接口,上传到服务器也可以.

上传图片

<input type="file"
       @change="uploadFiles"
       ref="fileRef" accept="image/png, image/jpeg, image/gif, image/jpg" style="display: none">

image.png

  1. npm ali-oss
npm install ali-oss -S
  1. 封装 oss 上传方法
import OSS from 'ali-oss'
import Vue from 'vue'

export default class OSSClient {
    static createClient(): OSS {
        return new OSS({
            region: "bucket所在的区域, 默认oss-cn-hangzhou",
            accessKeyId: "通过阿里云控制台创建的AccessKey",
            accessKeySecret: "通过阿里云控制台创建的AccessSecret",
            bucket: "通过控制台或PutBucket创建的bucket",
        })
    }

    static multipartUpload(client: OSS, ossFilePath: string, newFile: File) {
        return new Promise((resolve, reject) => {
            client.multipartUpload(ossFilePath, newFile,
                {
                    contentType: 'application/x-www-form-urlencoded',
                }).then((res:any) => {
                resolve(res);
            }).catch((err:any)=>{
                reject(err);
            })
        })
    }
}
  1. 完善uploadFiles方法
uploadFiles(e: any) {
    let executFile = e.target.files[0];
    var index = executFile.name.lastIndexOf('.')
    var ext = executFile.name.substr(index + 1)
    let newFile = new File([executFile], new Date().getTime() + '.' + ext)
    //上传文件
    let ossFilePath = "rtc_chat_image/";
    //地址是由 bucketName 和 endPoint 拼接的
    let ossBaseSrc = "http://lw-oss-develop.oss-cn-beijing.aliyuncs.com/";
    let client = OSSClient.createClient();
    // eslint-disable-next-line @typescript-eslint/no-this-alias
    let _this = this;
    OSSClient.multipartUpload(client, ossFilePath, newFile).then((res: any) => {
        _this.txt = ossBaseSrc + ossFilePath;
    })
}

文章最后,发现表情,和上传图片样式太丑

<template>
    <div class="home">
        <div class="home-txt">
            {{txt}}
        </div>
        <div class="home-tool">
            <div class="tool-face" @click.stop="emojiShow"></div>
            <div class="emoji-container" v-show="emojihowVisible">
                <Emoji @chooseEmojiDefault="chooseEmojiDefault"></Emoji>
            </div>
            <div class="tool-pic" @click="uploadShow"></div>
            <input type="file"
                   @change="uploadFiles"
                   ref="fileRef" accept="image/png, image/jpeg, image/gif, image/jpg" style="display: none">
        </div>


    </div>
</template>

<script lang="ts">
import {Component, Ref, Vue} from "vue-property-decorator";
import Emoji from "@/views/emoji.vue";
import OSSClient from "@/views/OssClient";

@Component({
    components: {Emoji},
})
export default class Home extends Vue {
    txt = ""
    emojihowVisible = false;
    @Ref() readonly fileRef;
    mounted(): void {
        document.documentElement.addEventListener('click', this.OnClick);
    }


    OnClick() {
        this.emojihowVisible = false;
    }

    chooseEmojiDefault(e: string) {
        this.txt = e;
    }

    emojiShow() {
        this.emojihowVisible = !this.emojihowVisible;
    }
    uploadShow() {
        this.fileRef.dispatchEvent(new MouseEvent('click'))
    }
    uploadFiles(e: any) {
        let executFile = e.target.files[0];
        var index = executFile.name.lastIndexOf('.')
        var ext = executFile.name.substr(index + 1)
        let newFile = new File([executFile], new Date().getTime() + '.' + ext)
        //上传文件
        let ossFilePath = "rtc_chat_image/";
        //地址是由 bucketName 和 endPoint 拼接的
        let ossBaseSrc = "http://lw-oss-develop.oss-cn-beijing.aliyuncs.com/";

        let client = OSSClient.createClient();
        // eslint-disable-next-line @typescript-eslint/no-this-alias
        let _this = this;
        OSSClient.multipartUpload(client, ossFilePath, newFile).then((res: any) => {
            _this.txt = ossBaseSrc + ossFilePath;
        })
    }
}
</script>
<style lang="scss" scoped>
.home {
    margin: 200px;
    width: 600px;
    text-align: left;
    background: #eeeeee;
    height: 600px;

    .home-txt {
        min-height: 500px;
        width: 100%;
        border-bottom: 1px solid #CECACA;
    }


    .home-tool {
        width: 100%;
        height: 100px;
        display: flex;

        .tool-face, .tool-pic {
            width: 30px;
            height: 30px;
            cursor: pointer;
            // 禁止元素的文字被选中
            -moz-user-select: none;
            -webkit-user-select: none;
            -ms-user-select: none;
        }

        .tool-face {
            background: url("./../assets/images/chat.png") no-repeat -404px -398px;
            background-size: 487px 462px;
        }

        .tool-pic {
            background: url("./../assets/images/chat.png") no-repeat -119px -432px;
            background-size: 487px 462px;
        }

        position: relative;

        .emoji-container {
            width: 400px;
            height: 300px;
            position: absolute;
            bottom: 110px;
            left: 0px;
            z-index: 10;
            transition: all 0.2s;
        }
    }
}
</style>

效果图

感觉还可以

image.png