微信小程序实现即时通信聊天功能的实例代码

项目背景:小程序中实现实时聊天功能

一、服务器域名配置

配置流程

配置参考URL:https://developers.weixin.qq.com/miniprogram/dev/api/api-network.html

二、nginx中配置反向代理加密websocket(wss)

?


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

upstream websocket{

 hash $remote_addr consistent;

 server 127.0.0.1:9090 weight=5 max_fails=3 fail_timeout=30s;

}

server {

 listen 80;

 server_name www.xxxx.cn;

 rewrite ^(.*)$ https://$host$1 permanent;

}

server

 {

 listen 443;

  server_name www.xxxx.cn;

  ssl on;

  root /home/wwwroot/yzcp;

  index index.php index.html index.htm;

  ssl_certificate /usr/local/nginx/conf/cert/1526060965511.pem;#这里是服务端证书路径

  ssl_certificate_key /usr/local/nginx/conf/cert/1526060965511.key;#这里是密钥路径

  ssl_session_timeout 5m;

  ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4;

  ssl_protocols TLSv1 TLSv1.1 TLSv1.2;

  ssl_prefer_server_ciphers on;

  ssl_verify_client off;

 #隐藏index.php

  location / {

 #index index.php;

 deny 127.0.0.1;

   if (!-e $request_filename) {

    #一级目录

    rewrite ^(.*)$ /index.php?s=$1 last;

    break;

   }

   #wss配置

   client_max_body_size 100m;

   proxy_redirect off;

   proxy_pass http://websocket;#反向代理转发地址

   proxy_set_header Host $host;# http请求的主机域名

   proxy_set_header X-Real-IP $remote_addr;# 远程真实IP地址

   proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;#反向代理之后转发之前的IP地址

   proxy_read_timeout 604800s;#websocket心跳时间,默认是60s

   proxy_http_version 1.1;

   proxy_set_header Upgrade $http_upgrade;

   proxy_set_header Connection "Upgrade";

  }

  location ~ .+\.php {

   fastcgi_pass unix:/tmp/php-cgi.sock;

   fastcgi_index index.php;

   include fastcgi_params;

   set $path_info "";

   set $real_script_name $fastcgi_script_name;

    if ($fastcgi_script_name ~ "^(.+?\.php)(/.+)$") {

    set $real_script_name $1;

    set $path_info $2;

   }

   fastcgi_param SCRIPT_FILENAME $document_root$real_script_name;

   fastcgi_param SCRIPT_NAME $real_script_name;

   fastcgi_param PATH_INFO $path_info;

  }

 

  #防盗链开始

  location ~ .*\.(gif|jpg|jpeg|png|bmp|swf)$

 {

 expires  30d;

 }

 location ~ .*\.(js|css)?$

 {

 expires  12h;

 }

 access_log /home/wwwlogs/www1537ucn.log;

 }

三、安装swoole

编译安装:

?


1

2

3

4

5

6

7

8

9

10

wget http://pecl.php.net/get/swoole-1.9.3.tgz  //下载swoole

tar -zvxf swoole-1.9.3.tgz  //解压swoole

cd swoole-1.9.3/;  //进入swoole

/usr/local/php54/bin/phpize;  //生成configure

./configure --with-php-config=/usr/local/php/bin/php-config

make && make install   //安装

cd /phpstudy/server/php/lib/php/extensions/no-debug-non-zts-20121212 //查看是否安转上了swoole.so (注意:此文件下边都是你安装的拓展)

vim /phpstudy/server/php/etc/php.ini  //在php.ini添加extension=swoole.so加入到文件最后一行

lnmp restart; //重启nginx

php -m; //查看phpinfo,这时候swoole拓展已经装上了

四、服务器端运行程序

1、创建server.php放到项目的根目录即可

?


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

<?php

//实例化一个swoole的websocket服务监听本机的9501端口

$server = new swoole_websocket_server("服务器IP", 9090);

//只需要绑定要监听的ip和端口。如果ip指定为127.0.0.1,则表示客户端只能位于本机才能连接,其他计算机无法连接。

//端口这里指定为9090,可以通过netstat查看下该端口是否被占用。如果该端口被占用,可更改为其他端口,如9502,9503等。

$server->on(‘open‘, function (swoole_websocket_server $server, $request) {

 echo "你好连接成功{$request->fd}\n";

});

$server->on(‘message‘, function (swoole_websocket_server $server, $frame) {

 foreach($server->connections as $key => $fd) {

  $user_message = $frame->data;

  $server->push($fd, $user_message);

 }

});

$server->on(‘close‘, function ($ser, $fd) {

 echo "client {$fd} closed\n";

});

$server->start();

?>

2、由于swoole_server只能运行在CLI模式下,所以不要试图通过浏览器进行访问,这样是无效的,我们在命令行下面执行,注意一定要找到php的绝对路径php  server.php  (这行代码的意思是,把程序在服务器跑起来)

注意:php server.php命令运行后,下面的黑框关闭后将无法聊天。所以一般使用命令:nohup php server.php &

五、客户端

1、网页代码

?


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

<!DOCTYPE html>

<html>

<head>

 <meta charset="utf-8">

 <title>聊天</title>

 <style type="text/css">

  #show{

   width: 600px;

   height: 300px;

   overflow-y: scroll;

  }

  .my-message{

   background-color: rgba(105, 105, 105, 0.64);

   color: #9e0505;

   width: 200px;

   float: right;

   padding: 10px;

  }

  .other-message{

   background-color: rgba(105, 105, 105, 0.64);

   color: #9e0505;

   width: 200px;

   float: left;

   padding: 10px;

  }

 </style>

</head>

<body>

 <div id="show"></div>

 <div class="panel">

  内容:<textarea id="content"></textarea>

  收信人:<input type="text" id="touser">

  <input type="button" id="send-btn" value="发送">

  <input type="button" id="close-btn" value="关闭">

 </div>

</body>

<script src="__PUBLIC__/js/jquery-1.10.2.min.js" charset="utf-8"></script>

<script type="text/javascript">

 var socket = new WebSocket("wss://域名");

 $("#close-btn").click(function () {

  socket.close();

 })

 $("#send-btn").click(function () {

  var touser = $("#touser").val();

  var content = $("#content").val();

  var htmlstr = "<div><p class=‘my-message‘>我:"+content+"</p></div>";

  $("#show").append(htmlstr);

  socket.send(content+"@"+touser);

 })

 socket.onmessage = function (p1) {

  var htmlstr = "<div><p class=‘other-message‘>"+p1.data+"</p></div>";

  $("#show").append(htmlstr);

 }

</script>

</html>

2、小程序端的代码

Uitls/websocket.js:

?


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

var url = wss://www.xxx.cn;//服务器地址

function connect(user, func) {

 wx.connectSocket({

 url: url,

 header: { ‘content-type‘: ‘application/json‘ },

 success: function () {

  console.log(‘websocket连接成功~‘)

 },

 fail: function () {

  console.log(‘websocket连接失败~‘)

 }

 })

 wx.onSocketOpen(function (res) {

 wx.showToast({

  title: ‘websocket已开通~‘,

  icon: "success",

  duration: 2000

 })

 //接受服务器消息

 wx.onSocketMessage(func);//func回调可以拿到服务器返回的数据

 });

 wx.onSocketError(function (res) {

 wx.showToast({

  title: ‘websocket连接失败,请检查!‘,

  icon: "none",

  duration: 2000

 })

 })

}

//发送消息

function send(msg) {

 wx.sendSocketMessage({

 data: msg

 });

}

module.exports = {

 connect: connect,

 send: send

}

JS:

?


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

// pages/socks/socks.js

const app = getApp()

var websocket = require(‘../../utils/websocket.js‘);

var utils = require(‘../../utils/util.js‘);

Page({

 /**

 * 页面的初始数据

 */

 data: {

 newslist: [],

 userInfo: {},

 scrollTop: 0,

 increase: false,//图片添加区域隐藏

 aniStyle: true,//动画效果

 message: "",

 previewImgList: []

 },

 /**

 * 生命周期函数--监听页面加载

 */

 onLoad: function () {

 var that = this

 if (app.globalData.userInfo) {

  this.setData({

  userInfo: app.globalData.userInfo

  })

 }

 //调通接口

 websocket.connect(this.data.userInfo, function (res) {

  // console.log(JSON.parse(res.data))

  var list = []

  list = that.data.newslist

  list.push(JSON.parse(res.data))

  that.setData({

  newslist: list

  })

 })

 },

 // 页面卸载

 onUnload() {

 wx.closeSocket();

 wx.showToast({

  title: ‘连接已断开~‘,

  icon: "none",

  duration: 2000

 })

 },

 //事件处理函数

 send: function () {

 var flag = this

 if (this.data.message.trim() == "") {

  wx.showToast({

  title: ‘消息不能为空哦~‘,

  icon: "none",

  duration: 2000

  })

 } else {

  setTimeout(function () {

  flag.setData({

   increase: false

  })

  }, 500)

  websocket.send(‘{ "content": "‘ + this.data.message + ‘", "date": "‘ + utils.formatTime(new Date()) + ‘","type":"text", "nickName": "‘ + this.data.userInfo.nickName + ‘", "avatarUrl": "‘ + this.data.userInfo.avatarUrl + ‘" }‘)

  this.bottom()

 }

 },

 //监听input值的改变

 bindChange(res) {

 this.setData({

  message: res.detail.value

 })

 },

 cleanInput() {

 //button会自动清空,所以不能再次清空而是应该给他设置目前的input值

 this.setData({

  message: this.data.message

 })

 },

 increase() {

 this.setData({

  increase: true,

  aniStyle: true

 })

 },

 //点击空白隐藏message下选框

 outbtn() {

 this.setData({

  increase: false,

  aniStyle: true

 })

 },

 //发送图片

 chooseImage() {

 var that = this

 wx.chooseImage({

  count: 1, // 默认9

  sizeType: [‘original‘, ‘compressed‘], // 可以指定是原图还是压缩图,默认二者都有

  sourceType: [‘album‘, ‘camera‘], // 可以指定来源是相册还是相机,默认二者都有

  success: function (res) {

  // 返回选定照片的本地文件路径列表,tempFilePath可以作为img标签的src属性显示图片

  var tempFilePaths = res.tempFilePaths

  // console.log(tempFilePaths)

  wx.uploadFile({

   url: wss://www.xxx.cn, //服务器地址

   filePath: tempFilePaths[0],

   name: ‘file‘,

   headers: {

   ‘Content-Type‘: ‘form-data‘

   },

   success: function (res) {

   if (res.data) {

    that.setData({

    increase: false

    })

    websocket.send(‘{"images":"‘ + res.data + ‘","date":"‘ + utils.formatTime(new Date()) + ‘","type":"image","nickName":"‘ + that.data.userInfo.nickName + ‘","avatarUrl":"‘ + that.data.userInfo.avatarUrl + ‘"}‘)

    that.bottom()

   }

   }

  })

  }

 })

 },

 //图片预览

 previewImg(e) {

 var that = this

 //必须给对应的wxml的image标签设置data-set=“图片路径”,否则接收不到

 var res = e.target.dataset.src

 var list = this.data.previewImgList //页面的图片集合数组

 //判断res在数组中是否存在,不存在则push到数组中, -1表示res不存在

 if (list.indexOf(res) == -1) {

  this.data.previewImgList.push(res)

 }

 wx.previewImage({

  current: res, // 当前显示图片的http链接

  urls: that.data.previewImgList // 需要预览的图片http链接列表

 })

 },

 //聊天消息始终显示最底端

 bottom: function () {

 var query = wx.createSelectorQuery()

 query.select(‘#flag‘).boundingClientRect()

 query.selectViewport().scrollOffset()

 query.exec(function (res) {

  wx.pageScrollTo({

  scrollTop: res[0].bottom // #the-id节点的下边界坐标

  })

  res[1].scrollTop // 显示区域的竖直滚动位置

 })

 },

})

WXML:

?


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

<!--pages/socks/socks.wxml-->

<view class="news" bindtap=‘outbtn‘>

<view class="chat-notice" wx:if="{{userInfo}}">系统消息: 欢迎 {{ userInfo.nickName }} 加入聊天室</view>

<view class="historycon">

<scroll-view scroll-y="true" class="history" scroll-top="{{scrollTop}}">

<block wx:for="{{newslist}}" wx:key>

 <!-- 历史消息 -->

<!-- <view class="chat-news">

<view style="text-align: left;padding-left: 20rpx;">

<image class=‘new_img‘ src="{{item.avatarUrl? item.avatarUrl:‘images/avator.png‘}}"></image>

<text class="name">{{ item.nickName }}{{item.date}}</text>

</view>

<view class=‘you_left‘>

<block wx:if="{{item.type==‘text‘}}">

<view class=‘new_txt‘>{{item.content}}</view>

</block>

<block wx:if="{{item.type==‘image‘}}">

<image class="selectImg" src="{{item.images}}"></image>

</block>

</view>

</view> -->

<view>{{item.date}}</view>

<!--自己的消息 -->

<view class="chat-news" wx:if="{{item.nickName == userInfo.nickName}}">

<view style="text-align: right;padding-right: 20rpx;">

<text class="name">{{ item.nickName }}</text>

<image class=‘new_img‘ src="{{userInfo.avatarUrl}}"></image>

</view>

<view class=‘my_right‘>

<block wx:if="{{item.type==‘text‘}}">

<view class=‘new_txt‘>{{item.content}}</view>

</block>

<block wx:if="{{item.type==‘image‘}}">

<image class="selectImg" src="{{item.images}}" data-src="{{item.images}}" lazy-load="true" bindtap="previewImg"></image>

</block>

</view>

</view>

<!-- 别人的消息 -->

<view class="chat-news" wx:else>

<view style="text-align: left;padding-left: 20rpx;">

<image class=‘new_img‘ src="{{item.avatarUrl? item.avatarUrl:‘images/avator.png‘}}"></image>

<text class="name">{{ item.nickName }}</text>

</view>

<view class=‘you_left‘>

<block wx:if="{{item.type==‘text‘}}">

<view class=‘new_txt‘>{{item.content}}</view>

</block>

<block wx:if="{{item.type==‘image‘}}">

<image class="selectImg" src="{{item.images}}" data-src="{{item.images}}" lazy-load="true" bindtap="previewImg"></image>

</block>

</view>

</view>

</block>

</scroll-view>

</view>

</view>

<view id="flag"></view>

<!-- 聊天输入 -->

<view class="message">

<form bindreset="cleanInput" class="sendMessage">

<input type="text" placeholder="请输入聊天内容.." value="{{massage}}" bindinput=‘bindChange‘></input>

<view class="add" bindtap=‘increase‘>+</view>

<button type="primary" bindtap=‘send‘ formType="reset" size="small" button-hover="blue">发送</button>

</form>

<view class=‘increased {{aniStyle?"slideup":"slidedown"}}‘ wx:if="{{increase}}">

<view class="image" bindtap=‘chooseImage‘>相册 </view>

</view>

</view>

WXSS:

?


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153

154

155

156

157

158

159

160

161

162

163

164

165

166

167

168

169

170

171

172

173

174

175

176

177

178

179

180

181

/* pages/socks/socks.wxss */

page {

background-color: #f7f7f7;

height: 100%;

}

/* 聊天内容 */

.news {

padding-top: 30rpx;

text-align: center;

/* height:100%; */

box-sizing:border-box;

}

#flag{

margin-bottom: 100rpx;

height: 30rpx;

}

.chat-notice{

text-align: center;

font-size: 30rpx;

padding: 10rpx 0;

color: #666;

}

.historycon {

height: 100%;

width: 100%;

/* flex-direction: column; */

display: flex;

border-top: 0px;

}

/* 聊天 */

.chat-news{

width: 100%;

overflow: hidden;

}

.chat-news .my_right {

float: right;

/* right: 40rpx; */

padding: 10rpx 10rpx;

}

.chat-news .name{

margin-right: 10rpx;

}

.chat-news .you_left {

float: left;

/* left: 5rpx; */

padding: 10rpx 10rpx;

}

.selectImg{

display: inline-block;

width: 150rpx;

height: 150rpx;

margin-left: 50rpx;

}

.my_right .selectImg{

margin-right: 80rpx;

}

.new_img {

width: 60rpx;

height: 60rpx;

border-radius: 50%;

vertical-align: middle;

margin-right: 10rpx;

}

.new_txt {

max-width: 300rpx;

display: inline-block;

border-radius: 6rpx;

line-height: 60rpx;

background-color: #95d4ff;

padding: 5rpx 20rpx;

margin: 0 10rpx;

margin-left: 50rpx;

}

.my_right .new_txt{

margin-right:60rpx;

}

.you{

background-color: lightgreen;

}

.my {

border-color: transparent transparent transparent #95d4ff;

}

.you {

border-color: transparent #95d4ff transparent transparent;

}

.hei{

margin-top: 50px;

height: 20rpx;

}

.history {

height: 100%;

margin-top: 15px;

padding: 10rpx;

font-size: 14px;

line-height: 40px;

word-break: break-all;

}

::-webkit-scrollbar {

width: 0;

height: 0;

color: transparent;

z-index: -1;

}

/* 信息输入区域 */

.message{

position: fixed;

bottom:0;

width: 100%;

}

.sendMessage{

display: block;

height: 80rpx;

padding: 10rpx 10rpx;

background-color: #fff;

border-top: 2rpx solid #eee;

border-bottom: 2rpx solid #eee;

z-index:3;

}

.sendMessage input{

float:left;

width: 66%;

height: 100%;

line-height: 80rpx;

border-bottom: 1rpx solid #ccc;

padding:0 10rpx;

font-size: 35rpx;

color: #666;

}

.sendMessage view{

display: inline-block;

width: 80rpx;

height: 80rpx;

line-height: 80rpx;

font-size: 60rpx;

text-align: center;

color: #999;

border: 1rpx solid #ccc;

border-radius: 50%;

margin-left: 10rpx;

}

.sendMessage button {

float: right;

font-size: 35rpx;

}

.increased{

width:100%;

/* height: 150rpx; */

padding: 40rpx 30rpx;

background-color: #fff;

}

.increased .image{

width: 100rpx;

height: 100rpx;

border: 3rpx solid #ccc;

line-height: 100rpx;

text-align: center;

border-radius: 8rpx;

font-size:35rpx;

}

@keyframes slidedown {

from {

transform: translateY(0);

}

to {

transform: translateY(100%);

}

}

.slidedown {

animation: slidedown 0.5s linear ;

}

.slideup {

animation: slideup 0.5s linear ;

}

@keyframes slideup {

from {

transform: translateY(100%);

}

to {

transform: translateY(0);

}

}

转载:https://www.jb51.net/article/145846.htm

原文地址:https://www.cnblogs.com/behindman/p/9522589.html

时间: 2024-11-09 19:18:50

微信小程序实现即时通信聊天功能的实例代码的相关文章

记录使用微信小程序的NFC和蓝牙功能读取15693芯片的开发历程

开发目标: (1) 对于Android手机,直接通过微信小程序调用手机的NFC功能,对15693协议的芯片进行读写操作: (2)对于苹果手机(及没有NFC模块的手机),通过微信小程序的蓝牙功能连接到蓝牙/NFC读写器,然后通过蓝牙发送指令操作读写器对15693协议的芯片进行读写操作. DAY #1 上午开了半天会,下午开始开发. 先开发简单的:直接通过Android手机的NFC模块读写芯片.开发思路如下: 1. 首先调用 wx.getHCEState(OBJECT), 判断设备是否支持NFC,如

微信小程序学习Course 7 定时器功能

微信小程序学习Course 7 定时器功能 微信小程序中有一个定时器API函数,其提供了四个API接口 7.1.number setTimeout(function callback, number delay, any rest) 设定一个定时器,在定时到期以后执行注册的回调函数,值得注意的是本函数只执行一次!!!! setTimeout(this.DaoJiShi, 1000);//时间到达一秒执行一次DaoJiShi函数 如果我们想实现一个不停调用的函数,怎末实现呢?以下函数利用递归实现了

微信小程序开发—你期待的分享功能来了,微信小程序序新增5大功能

微信小程序在12月21日发布了新版本的开发工具,并在官网公布新增分享.模板消息.客服消息.扫一扫.带参数二维码功能. 有了分享功能,相信会给很多创业者带来了无限的可能性! 下面就来看看这些新功能到底怎么用吧! 1.分享 可以分享小程序的任何一个页面给好友或群聊.注意是分享给好友或群聊,并没有分享到朋友圈.一方面微信在尝试流量分发方式,但同时又不愿意开放最大的流量入口. 开发文档:https://mp.weixin.qq.com/debug/wxadoc/dev/api/share.html?t=

微信小程序之商品发布+编辑功能(多图片上传功能)

小程序的商品发布页面:功能有多图片上传 遇到的问题记录一下: 1.uploadFile成功之后返回的参数是json字符串,一定要用JSON.parse转换为object格式 2.因为商品发布和编辑都是在同一个页面,因为异步的问题,在编辑页获取商品类别经常失败,所以这里在获取类别成功之后再获取商品详情 3.判断两位小数正则:/^\d+(.\d{1,2})?$/ 4.使用picker一些注意的地方: <picker name="category" mode="selecto

微信小程序获取二维码(直接上代码)https://api.weixin.qq.com/cgi-bin/wxaapp/createwxaqrcode?access_token=ACCESS_TOKEN

应为是直接返回二进制数据所有与其他接口些许差别,希望能帮助现在的你! 谢谢!!!    /** * 37.微信二维码生成 */ public String getWeiXinCourseMap() { String courseId = StringUtils.defaultString(getPara("courseId")); String codeUrl = ""; String path = "你的二维码指向路径(可以拼接参数)"; tr

微信小程序-开心大转盘(圆盘指针)代码分析

大转盘是比较常见的抽奖活动 .以前做过h5的大转盘,最近小程序比较火,客户要求做小程序的大转盘.我们就来分析下代码.先上几个图:     界面效果还是很不错的. 做界面还是比较容易的,只要有前端基础没啥难度. 关键是 抽奖的动画,我们就是要小程序本身的动画: 界面加载的时候定义一个动画对象: onLoad(opt) { this.setPlateData(); //执行设置转盘表面的文字 let that = this; let aniData = wx.createAnimation({ //

微信小程序 上传图的功能

首先选择图片,然后循环,再就是在点击发布的时候循环图片地址赋值,包括删除命令 js代码: //选择图片 uploadImgAdd: function(e) { var imgs = this.data.imgs; console.log(imgs) wx.chooseImage({ sizeType: ['original', 'compressed'], sourceType: ['album', 'camera'], success: (res) => { console.log(res)

微信小程序中父子通信

首先父组件 第一步引入 第二步写入 第三步JS 子组件 原文地址:https://www.cnblogs.com/binmengxue/p/12695995.html

分享为小程序添加自动回复消息的5种方法!自动客服功能的微信小程序

如何通过小程序客服消息引导自动关注公众号? 小程序客服自动回复一个图文链接? 小程序客服可以发小程序卡片吗? 小程序客服能像公众号一样设置关键词回复吗? 收到消息时自动回复? 微信小程序新手如何默认自动回复功能 如果你遇到以上问题,请往下看!教大家实现微信小程序客服自动回复消息功能,以帮助我们更好地与客户进行互动. 当我们的小程序接入客服,在小程序前端增加一个客服按钮,用户可以点击按钮主动和我们的客服互动! 但是有个问题,消息那么多,如何才能接待的过来,能否想微信公众号一样自动回复,关键词回复,