Vue Cli 3项目使用融云IM实现聊天功能的方法


Posted in Javascript onApril 19, 2019

介绍:前台使用vue开发的单页面,后台使用ant design pro单页面,实现手机端和后台聊天功能。

效果如图(PC+移动):

Vue Cli 3项目使用融云IM实现聊天功能的方法

Vue Cli 3项目使用融云IM实现聊天功能的方法

一、申请融云账号(token、appKey)

建议先看教程:sdk使用介绍

过一遍教程,接下来开始写

二、引入融云IM

如图:

Vue Cli 3项目使用融云IM实现聊天功能的方法

位置:public/index.html,引入

<script src="https://cdn.ronghub.com/RongIMLib-2.3.5.min.js"></script>

三、可以正常使用RongIMLib其自带方法了

app.vue 不是全代码(因为只是连接)

created () { //生命周期函数-可发起求
 let that = this
 //融云初始化
 RongIMLib.RongIMClient.init('4z3hrv4ovrt'); //------------------------------重要填写appkey
 that.beforeIm() //设置监听,必须先设置监听,再连接
 that.nowIm() //连接融云
 },
 methods: {
 ...mapMutations({ //读取最新消息列表,并设置----------------------------重要
  getAnswer:'getAnswer'
 }),
 beforeIm(){
  let that = this
  // 连接状态监听器
  RongIMClient.setConnectionStatusListener({
   onChanged: function (status) {
    // status 标识当前连接状态
    switch (status) {
     case RongIMLib.ConnectionStatus.CONNECTED:
      console.log('链接成功');
      break;
     case RongIMLib.ConnectionStatus.CONNECTING:
      console.log('正在链接');
      break;
     case RongIMLib.ConnectionStatus.DISCONNECTED:
      console.log('断开连接');
      break;
     case RongIMLib.ConnectionStatus.KICKED_OFFLINE_BY_OTHER_CLIENT:
      console.log('其他设备登录');
      break;
     case RongIMLib.ConnectionStatus.DOMAIN_INCORRECT:
      console.log('域名不正确');
      break;
     case RongIMLib.ConnectionStatus.NETWORK_UNAVAILABLE:
      console.log('网络不可用');
      break;
    }
   }
  });

  // 消息监听器
  RongIMClient.setOnReceiveMessageListener({
   // 接收到的消息
   onReceived: function (message) {
    // 判断消息类型
    switch(message.messageType){
     case RongIMClient.MessageType.TextMessage:
      // message.content.content => 文字内容
      //----------------------------重要-------把获取的消息存放在store中,全局公用homeIm.vue要使用
      console.log('8080',message,message.content.content)
      that.getAnswer(message.content)
      break;
     case RongIMClient.MessageType.VoiceMessage:
      // message.content.content => 格式为 AMR 的音频 base64
      break;
     case RongIMClient.MessageType.ImageMessage:
      // message.content.content => 图片缩略图 base64
      // message.content.imageUri => 原图 URL
      break;
     case RongIMClient.MessageType.LocationMessage:
      // message.content.latiude => 纬度
      // message.content.longitude => 经度
      // message.content.content => 位置图片 base64
      break;
     case RongIMClient.MessageType.RichContentMessage:
      // message.content.content => 文本消息内容
      // message.content.imageUri => 图片 base64
      // message.content.url => 原图 URL
      break;
     case RongIMClient.MessageType.InformationNotificationMessage:
      // do something
      break;
     case RongIMClient.MessageType.ContactNotificationMessage:
      // do something
      break;
     case RongIMClient.MessageType.ProfileNotificationMessage:
      // do something
      break;
     case RongIMClient.MessageType.CommandNotificationMessage:
      // do something
      break;
     case RongIMClient.MessageType.CommandMessage:
      // do something
      break;
     case RongIMClient.MessageType.UnknownMessage:
      // do something
      break;
     default:
      // do something
    }
   }
  });
 },
 nowIm(){
 //自己的token------从接口获取,写到缓存
  var token = JSON.parse(localStorage.getItem('userInfo')).IMUser.token//"WzrthC5f4UfuiI7dIwCQ5fwtGfqCdobpowIZkcQnj8PQOQuAJb/nIi1ayzGFwJguvbQZxbJH3x0=";
  RongIMClient.connect(token, {
   onSuccess: function(userId) {
    console.log('Connect successfully. ' + userId);
   },
   onTokenIncorrect: function() {
    console.log('token 无效');
   },
   onError: function(errorCode){
    var info = '';
    switch (errorCode) {
     case RongIMLib.ErrorCode.TIMEOUT:
      info = '超时';
      break;
     case RongIMLib.ConnectionState.UNACCEPTABLE_PAROTOCOL_VERSION:
      info = '不可接受的协议版本';
      break;
     case RongIMLib.ConnectionState.IDENTIFIER_REJECTED:
      info = 'appkey不正确';
      break;
     case RongIMLib.ConnectionState.SERVER_UNAVAILABLE:
      info = '服务器不可用';
      break;
    }
    console.log(info);
   }
  });
 }
 },

main.js 代码

import Vue from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'
import './assets/style.css' // 外部static样式 ------重要
import './assets/js/rem.js' //rem适配 ------重要
import my from './assets/js/lbc.js' //------不重要 ---自定义全局方法

import HomeNews from './components/HomeNews.vue' //自定义组件 ------重要
Vue.component('HomeNews',HomeNews)

Vue.prototype.$my=my //------不重要 ---自定义全局方法 使用 this.$my.xxx
Vue.config.productionTip = false

new Vue({
 router,
 store,
 render: h => h(App)
}).$mount('#app')

store.js 全代码

import Vue from 'vue'
import Vuex from 'vuex'
import axios from 'axios'
const API_PROXY = 'https://bird.ioliu.cn/v1/?url='; //代理

Vue.use(Vuex)
export default new Vuex.Store({
 state: {
 answer:[]
 },
 getters: {
 },
 mutations: {
 getAnswer (state, playload) {//--------------重要
  let say ={ //自定义消息组件所需参数
   type:1,
   css:'left',
   txt:playload.content,
   date:'',
   headImg:playload.extra
  }
  state.answer.push(say)
  console.log(playload)
 },
 },
 actions: {
 }
})

homeIm.vue

//一如以往,不废话,直接代码
<template>
 <div class="homeIm" id='homeIm'>
 //----------------------------------------------------重要-------------------自定义消息组件,下面会贴码
 <home-news v-for="(item ,index) in answer" :key='index' :item='item' :data='item'></home-news>

 <div class="posFix bottom0 left0 flex justsa alic w100 bgf " style="min-height:.6rem;">
  <img src="../assets/images/mike.png" class="mike pl10 pr10"/>
  <van-field v-model="say" placeholder="请输入" class="flex1 border borRad" />
  <van-button size="large " @click="send" type='info' class="button borRad ml10 mr10" :disabled ='say?false:true'>确定</van-button>
 </div>
 
 </div>
</template>

<script>
import Vue from "vue";
import { Field ,Button } from "vant";
import router from "../router.js";
import axios from "axios";
import {mapState,mapGetters,mapActions,mapMutations} from 'vuex'


const arr = [ Field ,Button];
arr.map(e => {
 //动态生成组件
 Vue.use(e);
});

export default {
 data() {
 return { 
  say:'小仙女,你好鸭'
 };
 },
 name: "homeIm",
 props: {
 msg: String
 },
 created() {
 //this.getChatRecord() //获取聊天记录,要钱
 this.$nextTick(() => {//------------------------重要-------有消息就滚动到底部-----------------------
  let list = document.getElementById('homeIm')
  document.documentElement.scrollTop = list.scrollHeight
  //如不行,请尝试-> list.scrollTop = list.scrollHeight
  })
 },
 computed:{
 ...mapState({
  answer:"answer",
 }),

 },
 watch: { //------------------------重要-------有消息就滚动到底部-----------------------
 answer() {
  this.$nextTick(() => {
  let list = document.getElementById('homeIm')
  document.documentElement.scrollTop = list.scrollHeight
  //如不行,请尝试-> list.scrollTop = list.scrollHeight
  })
 }
 },
 methods: {
 send() {
  let that = this
  let msg = new RongIMLib.TextMessage({ content: that.say, extra: 'https://img.52z.com/upload/news/image/20171120/20171120080335_21404.jpg' });
  let conversationType = RongIMLib.ConversationType.PRIVATE; // 单聊, 其他会话选择相应的消息类型即可
  let targetId = JSON.parse(localStorage.getItem('userInfo')).IMUser.assistantId; // 目标 Id

  RongIMClient.getInstance().sendMessage(conversationType, targetId, msg, {
   onSuccess: function (message) {
    // message 为发送的消息对象并且包含服务器返回的消息唯一 Id 和发送消息时间戳
    console.log('Send successfully',message,message.content.content);
    let say = {
     type:1,
     css:'right',
     txt:message.content.content,
     headImg:'https://img.52z.com/upload/news/image/20171120/20171120080335_21404.jpg'
    }
    that.answer.push(say)
    that.say = ''
   },
   onError: function (errorCode, message) {
    let info = '';
    switch (errorCode) {
     case RongIMLib.ErrorCode.TIMEOUT:
      info = '超时';
      break;
     case RongIMLib.ErrorCode.UNKNOWN:
      info = '未知错误';
      break;
     case RongIMLib.ErrorCode.REJECTED_BY_BLACKLIST:
      info = '在黑名单中,无法向对方发送消息';
      break;
     case RongIMLib.ErrorCode.NOT_IN_DISCUSSION:
      info = '不在讨论组中';
      break;
     case RongIMLib.ErrorCode.NOT_IN_GROUP:
      info = '不在群组中';
      break;
     case RongIMLib.ErrorCode.NOT_IN_CHATROOM:
      info = '不在聊天室中';
      break;
    }
    console.log('发送失败: ' + info + errorCode);
   }
  });
 },
 getChatRecord(){
  let conversationType = RongIMLib.ConversationType.PRIVATE; //单聊, 其他会话选择相应的消息类型即可
  let targetId = '2'; // 想获取自己和谁的历史消息,targetId 赋值为对方的 Id
  let timestrap = null; // 默认传 null,若从头开始获取历史消息,请赋值为 0, timestrap = 0;
  let count = 20; // 每次获取的历史消息条数,范围 0-20 条,可以多次获取
  RongIMLib.RongIMClient.getInstance().getHistoryMessages(conversationType, targetId, timestrap, count, {
   onSuccess: function(list, hasMsg) {
    // list => Message 数组。
    // hasMsg => 是否还有历史消息可以获取。
    console.log('历史纪录',list, hasMsg)
   },
   onError: function(error) {
    console.log('GetHistoryMessages, errorcode:' + error);
   }
  });
 }
 },
};
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
.mike{
 width: .3rem;height: .3rem;
}
.border{border:1px solid #ccc;}
.button{
 width: .8rem;height: .46rem;
}
.homeIm{padding-bottom: .7rem;}
</style>

homeNews.vue 全代码

<template>
 <div class="homeNews">
  <!-- 1:文字,2:红包,3:文章 ,css:类型 -->
  <div v-if="data.type == 1&&data.css == 'left'">
   <div class="colora1 fz12 lh40 pt10">{{data.date}}</div>
   <div class="flex pl20 pr20 borBox">
   <img :src="data.headImg" class="head borRad">
   <div class="frame borRad bgf lh24 fz16 tl color3 pl10 pr10 pt10 pb10 borBox w250 ml15 posRel">
    {{data.txt}}
   </div>
   </div>
  </div>
  <router-link to="/homeRedBag" v-else-if="data.type == 2&&data.css == 'left'">
   <div class="colora1 fz12 lh40 pt10">{{data.date}}</div>
   <div class="flex pl20 pr20 borBox">
   <img :src="data.headImg" class="head borRad">
   <div class="frame borRad bgf9 lh24 fz16 tl colorF w200 ml15 posRel redFrame">
    <div class="flex alic pl10 pr10 pt10 pb10 borBox">
    <img src="../assets/images/redTabs.png" class="redTabs"/>
    <span class="pl10">{{data.title}}</span>
    </div>
    <div class="fz12 color6 bgf pl15 borBox txt">{{data.txt}}</div>
   </div>
   </div>
  </router-link>
  <router-link to="/homeArticle" v-else-if="data.type == 3&&data.css == 'left'">
   <div class="colora1 fz12 lh40 pt10">{{data.date}}</div>
   <div class="flex pl20 pr20 borBox">
   <img :src="data.headImg" class="head borRad">
   <div class="frame borRad bgf fz16 tl color3 pl10 pr10 pt10 pb10 borBox w250 ml15 posRel">
    <div class="fz20 txt2 mb10 lh30">{{data.title}}</div>
    <div class="flex justsa alic">
    <div class="colora1 txt2 flex1 lh20">{{data.txt}}</div>
    <img :src="data.banner" class="banner"/>
    </div>
   </div>
   </div>
  </router-link>
  <div v-if="data.type == 1&&data.css == 'right'">
  <div class="colora1 fz12 lh40 pt10">{{data.date}}</div>
  <div class="flex pl20 pr20 borBox juste">
   <div class="frame-right borRad bgf lh24 fz16 tl color3 pl10 pr10 pt10 pb10 borBox w250 mr15 posRel">
   {{data.txt}}
   </div>
   <img :src="data.headImg" class="head borRad">
  </div>
  </div>

 </div>
</template>
<script>
import Vue from "vue";
import router from "../router.js";
export default {
 name: "homeNews",
 props:['data'],
 data() {
 return {
 };
 },
 created() {
 console.log()
 },
 methods: {
 }
};
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
.head {
 width: 0.36rem;
 height: 0.36rem;
}
.frame::before {
 display: block;
 content: '';
 width: 0px; /* 宽高设置为0,很重要,否则达不到效果 */
 height: 0px;
 border: .10rem solid #fff;
 border-bottom-color: transparent; /* 设置透明背景色 */
 border-top-color: transparent;
 border-left-color: transparent;
 position: absolute;left:-.2rem;top:.1rem;
}
.frame-right::before{
 display: block;
 content: '';
 width: 0px; /* 宽高设置为0,很重要,否则达不到效果 */
 height: 0px;
 border: .10rem solid #fff;
 border-bottom-color: transparent; /* 设置透明背景色 */
 border-top-color: transparent;
 border-right-color: transparent;
 position: absolute;right:-.2rem;top:.1rem;
}
.redFrame::before{
 display: block;
 content: '';
 width: 0px; /* 宽高设置为0,很重要,否则达不到效果 */
 height: 0px;
 border: .10rem solid #F99F3E;
 border-bottom-color: transparent; /* 设置透明背景色 */
 border-top-color: transparent;
 border-left-color: transparent;
 position: absolute;left:-.2rem;top:.1rem;
}
.redFrame-right::before{
 display: block;
 content: '';
 width: 0px; /* 宽高设置为0,很重要,否则达不到效果 */
 height: 0px;
 border: .10rem solid #F99F3E;
 border-bottom-color: transparent; /* 设置透明背景色 */
 border-top-color: transparent;
 border-left-color: transparent;
 position: absolute;right:-.2rem;top:.1rem;
}
.w250{max-width: 2.5rem;}
.w200{max-width: 2rem;}
.redTabs{
 width: .32rem;
 height:.39rem;
}
.txt{
 border-bottom-left-radius: .05rem;
 border-bottom-right-radius: .05rem;
}
.banner{width: .4rem;height: .4rem;}
</style>
style.css 我自己的样式表
@charset "utf-8";
/* CSS Document 刘白超修改于2019/3/10*/
html,body{height: 100%;width: 100%;word-wrap:break-word;}
*{margin: 0;padding: 0;}
.tc{text-align: center}
.tr{text-align: right}
.tl{text-align: left}
.vm{vertical-align: middle;}
.vs{vertical-align: sub;}
.fl{float: left;}
.fr{float: right;}
.fz24{font-size: .24rem;}
.fz20{font-size: .2rem;}
.fz18{font-size: .18rem;}
.fz16{font-size: .16rem;}
.fz14{font-size: .14rem;}
.fz12{font-size: .12rem;}
.fw{font-weight: 600;}
.mr5{margin-right: .05rem}
.mr10{margin-right: .10rem}
.mr15{margin-right: .15rem}
.mr20{margin-right: .20rem}
.ml5{margin-left:.05rem;}
.ml10{margin-left:.10rem;}
.ml15{margin-left:.15rem;}
.ml20{margin-left:.20rem;}
.ml24{margin-left:.24rem;}
.mt40{margin-top:.40rem;}
.mt20{margin-top: .20rem;}
.mt15{margin-top: .15rem;}
.mt10{margin-top: .10rem;}
.mt5{margin-top: .05rem;}
.mb5{margin-bottom: .05rem;}
.mb10{margin-bottom: .10rem;}
.mb15{margin-bottom: .15rem;}
.mb20{margin-bottom: .20rem;}
.pt5{padding-top: .05rem;}
.pt10{padding-top: .10rem;}
.pt15{padding-top: .15rem;}
.pt20{padding-top: .20rem;}
.pt30{padding-top: .30rem;}
.pb5{padding-bottom: .05rem;}
.pb10{padding-bottom: .10rem;}
.pb15{padding-bottom: .15rem;}
.pb20{padding-bottom: .20rem;}
.pl5{padding-left: .05rem;}
.pl10{padding-left: .10rem;}
.pl15{padding-left: .15rem;}
.pl20{padding-left: .20rem;}
.pl30{padding-left: .30rem;}
.pr5{padding-right: .05rem;}
.pr10{padding-right: .10rem;}
.pr15{padding-right: .15rem;}
.pr20{padding-right: .20rem;}
.pr30{padding-right: .30rem;}
.bgef{background: #EFEFEF;}
.bgf{background: #fff;}
.bgf9{background: #F99F3E}
.ee {background: #eee;}
.bg259{background:#259DFF !important}
.colordd{color: #DD4D41}
.colorf9 {color: #ff9800;}
.colore5{color: #e51c23;}
.colorF{color: #fff;}
.color3{color: #333;}
.color6{color: #666;}
.color9{color: #999;}
.colora1{color:#a1a1a1}
.color259{color:#259DFF}
.color005{color:#00559B}
.colorf3{color:#F3665E}
.lh24{line-height: .24rem}
.lh20{line-height: .20rem;}
.lh30{line-height: .30rem;}
.lh40{line-height: .40rem;}
.lh50{line-height: .50rem;}
.lh60{line-height: .60rem;}
.hide{display: none}
.show{display: block}
.inline{display: inline-block;}
.indent2{text-indent: 2em;}
.txt2{
 overflow : hidden;
 text-overflow: ellipsis;
 display: -webkit-box;
 -webkit-line-clamp: 2;
 -webkit-box-orient: vertical;
}
.wn{white-space:nowrap;}
.flex{display: flex;}
.flex1{flex:1;}
.colu{flex-direction: column;}
.justc{justify-content: center;}
.justs{justify-content: space-between}/*两端对齐*/
.justsa{justify-content: space-around}/*分散对齐*/
.juste{justify-content: flex-end;}
.alic{align-items: center}
.wrap{flex-wrap:wrap}
.childEnd{align-self:flex-end;}
.posAbs{position: absolute;}
.posRel{position: relative;}
.posFix{position: fixed;}
.top0{top:0;}
.bottom0{bottom:0;}
.left0{left:0;}
.right0{right: 0;}
.w100{width: 100%}
.h100{height: 100%}
.borBox{box-sizing: border-box;}
.borderte0{border-top:1px solid #e0e0e0; }
.borderbe0{border-bottom:1px solid #e0e0e0; }
.borRad{border-radius:.05rem;}
.over{overflow:hidden;white-space:nowrap;text-overflow:ellipsis;}
.overH{overflow: hidden}
.clear{zoom:1;}
.clear:after{content: "\0020";display: block;height: 0;clear: both;}
.mask{width: 100%;height: 100%;background: rgba(20, 20, 20, 0.5);position: fixed;z-index: 5;top: 0;left: 0;}
.cursor{cursor: pointer;}
.noClick{pointer-events: none;}
li{list-style:none;}
a{text-decoration:none;color:#555;}
a:hover{color:#555;}
img{display:block;vertical-align:middle;}
a img,fieldset{border:0;}
i,em{font-style:normal}
b,strong,th{font-weight:100;}
input,textarea,select{outline:none;}
textarea{resize:none;}
table{border-collapse:collapse;}
.btn{
 width: calc(100% - .54rem);
 background: #259DFF;
 font: .2rem/.5rem "";
 text-align: center;
 color: #fff;
 border-radius: 5px;
 margin-left: .27rem;
}
rem.js rem自适应单位
//例如设计稿为375,最大宽度为750,则为(375,750)
!function(e,t){function n(){var n=l.getBoundingClientRect().width;t=t||540,n>t&&(n=t);var i=100*n/e;r.innerHTML="html{font-size:"+i+"px;}"}var i,d=document,o=window,l=d.documentElement,r=document.createElement("style");if(l.firstElementChild)l.firstElementChild.appendChild(r);else{var a=d.createElement("div");a.appendChild(r),d.write(a.innerHTML),a=null}n(),o.addEventListener("resize",function(){clearTimeout(i),i=setTimeout(n,300)},!1),o.addEventListener("pageshow",function(e){e.persisted&&(clearTimeout(i),i=setTimeout(n,300))},!1),"complete"===d.readyState?d.body.style.fontSize="16px":d.addEventListener("DOMContentLoaded",function(e){d.body.style.fontSize="16px"},!1)}(375,640);

完了,okk,文中所需icon,请自行到阿里icon下载

结尾:项目中需要配置rem。

总结

以上所述是小编给大家介绍的Vue Cli 3项目使用融云IM实现聊天功能的方法,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对三水点靠木网站的支持!
如果你觉得本文对你有帮助,欢迎转载,烦请注明出处,谢谢!

Javascript 相关文章推荐
用javascript实现画板的代码
Sep 05 Javascript
理解Javascript_01_理解内存分配原理分析
Oct 11 Javascript
50款非常棒的 jQuery 插件分享
Mar 29 Javascript
jquery ajax例子返回值详解
Sep 11 Javascript
jquery中的$(document).ready()使用小结
Feb 14 Javascript
javascript复制粘贴与clipboardData的使用
Oct 16 Javascript
推荐6款基于jQuery实现图片效果插件
Dec 07 Javascript
ECMAScript 6即将带给我们新的数组操作方法前瞻
Jan 06 Javascript
微信小程序 蓝牙的实现实例代码
Jun 27 Javascript
vue二级路由设置方法
Feb 09 Javascript
浅谈Vue网络请求之interceptors实际应用
Feb 28 Javascript
Angular7中创建组件/自定义指令/管道的方法实例详解
Apr 02 Javascript
详解vue-cli+es6引入es5写的js(两种方法)
Apr 19 #Javascript
vue中使用vue-cli接入融云实现即时通信
Apr 19 #Javascript
浅谈Javascript中的对象和继承
Apr 19 #Javascript
详解如何在Vue项目中导出Excel
Apr 19 #Javascript
vue cli使用融云实现聊天功能的实例代码
Apr 19 #Javascript
详解vue中使用微信jssdk
Apr 19 #Javascript
vue router导航守卫(router.beforeEach())的使用详解
Apr 19 #Javascript
You might like
小偷PHP+Html+缓存
2006/12/20 PHP
在php中判断一个请求是ajax请求还是普通请求的方法
2011/06/28 PHP
探讨GDFONTPATH能否被winxp下的php支持
2013/06/21 PHP
那些年我们错过的魔术方法(Magic Methods)
2014/01/14 PHP
浅谈PHP拦截器之__set()与__get()的理解与使用方法
2016/10/18 PHP
再论Javascript的类继承
2011/03/05 Javascript
js中设置元素class的三种方法小结
2011/08/28 Javascript
JavaScript中OnLoad几种使用方法
2012/12/15 Javascript
使用ImageMagick进行图片缩放、合成与裁剪(js+python)
2013/09/16 Javascript
JavaScript采用递归算法计算阶乘实例
2015/08/04 Javascript
JS折半插入排序算法实例
2015/12/02 Javascript
jQuery移动端日期(datedropper)和时间(timedropper)选择器附源码下载
2016/04/19 Javascript
JS仿JQuery选择器功能
2017/03/08 Javascript
nodejs个人博客开发第三步 载入页面
2017/04/12 NodeJs
利用Vue实现一个markdown编辑器实例代码
2019/05/19 Javascript
Vuex实现数据增加和删除功能
2019/11/11 Javascript
浅谈vue-props的default写不写有什么区别
2020/08/09 Javascript
[09:31]2016国际邀请赛中国区预选赛Yao赛后采访 答题送礼
2016/06/27 DOTA
用python代码将tiff图片存储到jpg的方法
2018/12/04 Python
Python求一批字符串的最长公共前缀算法示例
2019/03/02 Python
Python用Try语句捕获异常的实例方法
2019/06/26 Python
Python数据类型之列表和元组的方法实例详解
2019/07/08 Python
python路径的写法及目录的获取方式
2019/12/26 Python
python安装后的目录在哪里
2020/06/21 Python
python中如何使用虚拟环境
2020/10/14 Python
英国最大的网上药品商店:Chemist Direct
2017/12/16 全球购物
浅谈react路由传参的几种方式
2021/03/23 Javascript
研究生自荐信
2013/10/09 职场文书
自荐信格式
2013/12/01 职场文书
软弱涣散基层党组织整改方案
2014/10/25 职场文书
专业见习报告范文
2014/11/03 职场文书
2015秋学期开学寄语
2015/05/28 职场文书
实用干货:敬酒词大全,帮你应付各种场合
2019/11/21 职场文书
Pytest中conftest.py的用法
2021/06/27 Python
MySQL系列之十三 MySQL的复制
2021/07/02 MySQL
docker compose 部署 golang 的 Athens 私有代理问题
2022/04/28 Servers