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 相关文章推荐
最常用的12种设计模式小结
Aug 09 Javascript
判断对象是否Window的实现代码
Jan 10 Javascript
jquery ajax例子返回值详解
Sep 11 Javascript
JavaScript设置IFrame高度自适应(兼容各主流浏览器)
Jun 05 Javascript
jQuery常用操作方法及常用函数总结
Jun 19 Javascript
vue中引入第三方字体文件的方法示例
Dec 17 Javascript
深入理解Puppeteer的入门教程和实践
Mar 05 Javascript
详解js创建对象的几种方法及继承
Apr 12 Javascript
javascript数组的定义及操作实例
Nov 10 Javascript
js消除图片小游戏代码
Dec 11 Javascript
Echarts.js无法引入问题解决方案
Oct 30 Javascript
Vue 401配合Vuex防止多次弹框的案例
Nov 11 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
用文本文件实现的动态实时发布新闻的程序
2006/10/09 PHP
php设计模式 Chain Of Responsibility (职责链模式)
2011/06/26 PHP
Windows下部署Apache+PHP+MySQL运行环境实战
2012/08/31 PHP
PHP rawurlencode与urlencode函数的深入分析
2013/06/08 PHP
Zend Framework处理Json数据方法详解
2016/12/09 PHP
PHP使用ActiveMQ实例
2018/02/05 PHP
laravel 如何实现引入自己的函数或类库
2019/10/15 PHP
javascript dom 操作详解 js加强
2009/07/13 Javascript
初试jQuery EasyUI 使用介绍
2010/04/01 Javascript
原生javascript模仿win8等待提示圆圈进度条
2014/04/24 Javascript
如何正确使用javascript 来进行我们的程序开发
2014/06/23 Javascript
node.js中的fs.readlink方法使用说明
2014/12/17 Javascript
JavaScript中创建字典对象(dictionary)实例
2015/03/31 Javascript
jQuery解析与处理服务器端返回xml格式数据的方法详解
2016/07/04 Javascript
CentOS 安装NodeJS V8.0.0的方法
2017/06/15 NodeJs
20170918 前端开发周报之JS前端开发必看
2017/09/18 Javascript
Vue elementui字体图标显示问题解决方案
2020/08/18 Javascript
JavaScript实现简易计算器小功能
2020/10/22 Javascript
python使用cookie库操保存cookie详解
2014/03/03 Python
python开发利器之ulipad的使用实践
2017/03/16 Python
Selenium 模拟浏览器动态加载页面的实现方法
2018/05/16 Python
Python使用指定字符长度切分数据示例
2019/12/05 Python
python 如何用urllib与服务端交互(发送和接收数据)
2021/03/04 Python
Raffaello Network德国:意大利拉斐尔时尚购物网
2019/05/01 全球购物
龟牌英国商店:Turtle Wax Brand Store UK
2019/07/02 全球购物
巴西24小时在线药房:Drogasil
2020/06/20 全球购物
Java面试题:请问一下代码输出是什么
2015/05/27 面试题
药学职务聘任书
2014/03/29 职场文书
小学毕业寄语大全
2014/04/03 职场文书
篮球比赛拉拉队口号
2014/06/10 职场文书
万能检讨书2000字
2014/10/17 职场文书
考勤制度通知
2015/04/25 职场文书
责任书范本大全
2015/05/11 职场文书
position:sticky 粘性定位的几种巧妙应用详解
2021/04/24 HTML / CSS
golang中字符串MD5生成方式总结
2021/07/04 Golang
opencv深入浅出了解机器学习和深度学习
2022/03/17 Python