当前位置:   article > 正文

uniapp 小程序低功耗蓝牙配网 ble配网 物联网

uniapp 小程序低功耗蓝牙配网 ble配网 物联网

 1.获取蓝牙列表  bleList.vue

  1. <template>
  2. <view>
  3. <button @touchstart="startSearch">获取蓝牙列表</button>
  4. <scroll-view :scroll-top="scrollTop" scroll-y class="content-pop">
  5. <view
  6. class="bluetoothItem"
  7. v-for="(item, index) in bluetoohList"
  8. :key="index"
  9. @click="openControl(item)"
  10. >
  11. <view class="textItem">蓝牙:{{ item.name }}</view>
  12. <view>{{ item.deviceId }}</view>
  13. </view>
  14. </scroll-view>
  15. </view>
  16. </template>
  17. <script>
  18. export default {
  19. data() {
  20. return {
  21. bluetoohList: [],
  22. };
  23. },
  24. onLoad: function (options) {
  25. this.startSearch();
  26. },
  27. methods: {
  28. // 连接蓝牙
  29. startSearch() {
  30. let that = this;
  31. that.$ble.openBluetoothAdapter(
  32. (res) => {
  33. that.$ble.getBluetoothAdapterState((res) => {
  34. if (res.available) {
  35. if (res.discovering) {
  36. that.$ble.stopBluetoothDevicesDiscovery();
  37. } else {
  38. that.getBluetoothDevices();
  39. }
  40. that.checkPemission();
  41. } else {
  42. that.$tip.toast("本机蓝牙不可用");
  43. }
  44. });
  45. },
  46. (err) => {
  47. that.openSetting();
  48. }
  49. );
  50. },
  51. openSetting() {
  52. let params = {
  53. title: "检测到您没打开蓝牙权限,是否去设置打开?",
  54. showCancel: true,
  55. };
  56. this.$tip.showModal(params, (res) => {
  57. if (res.confirm) {
  58. this.$ble.openSetting();
  59. }
  60. });
  61. },
  62. checkPemission() {
  63. //android 6.0以上需授权地理位置权限
  64. var that = this;
  65. const sys = uni.getSystemInfoSync();
  66. if (sys.platform == "ios") {
  67. that.getBluetoothDevices();
  68. } else if (sys.platform == "android") {
  69. console.log(
  70. app
  71. .getSystem()
  72. .substring(
  73. app.getSystem().length - (app.getSystem().length - 8),
  74. app.getSystem().length - (app.getSystem().length - 8) + 1
  75. )
  76. );
  77. if (
  78. app.globalData
  79. .getSystem()
  80. .substring(
  81. app.globalData.getSystem().length -
  82. (app.globalData.getSystem().length - 8),
  83. app.globalData.getSystem().length -
  84. (app.globalData.getSystem().length - 8) +
  85. 1
  86. ) > 5
  87. ) {
  88. uni.getSetting({
  89. success: (res) => {
  90. console.log(res);
  91. if (!res.authSetting["scope.userLocation"]) {
  92. uni.authorize({
  93. scope: "scope.userLocation",
  94. complete: (res) => {
  95. that.getBluetoothDevices();
  96. },
  97. });
  98. } else {
  99. that.getBluetoothDevices();
  100. }
  101. },
  102. });
  103. }
  104. }
  105. },
  106. //获取蓝牙设备信息
  107. getBluetoothDevices() {
  108. that.$tip.loading("蓝牙搜索中");
  109. this.$ble.getBluetoothDevices((res) => {
  110. this.bluetoohList = res;
  111. this.$tip.loaded();
  112. });
  113. },
  114. // 连接蓝牙 跳转到连接页面
  115. openControl(item) {
  116. let params = {
  117. list: this.bluetoohList,
  118. info: item,
  119. };
  120. this.$tip.redirectTo("/pages/ble/ble", params);
  121. },
  122. },
  123. };
  124. </script>
  125. <style scoped>
  126. .content-pop {
  127. width: 100vw;
  128. max-height: 55vh;
  129. padding: 0 30rpx;
  130. }
  131. .bluetoothItem {
  132. padding: 20rpx 0;
  133. font-weight: 400;
  134. font-size: 28rpx;
  135. border-bottom: 1rpx solid #f4f4f4;
  136. text-align: left;
  137. }
  138. .textItem {
  139. display: block;
  140. margin-bottom: 10rpx;
  141. }
  142. </style>

2.选择蓝牙进行连接  ble.vue

  1. <script>
  2. export default {
  3. data() {
  4. return {
  5. bluInfo: {},
  6. services: [],
  7. bleServiceId: "",
  8. serviceId: 0,
  9. writeCharacter: false,
  10. readCharacter: false,
  11. notifyCharacter: false,
  12. BLEInformation: {
  13. serveiceId: "",
  14. config_write_char_id: "",
  15. cmd_write_char_id: "",
  16. config_read_char_id: "",
  17. cmd_read_char_id: "",
  18. },
  19. };
  20. },
  21. onLoad(option) {
  22. // 接收页面传递的数据
  23. this.bluInfo = JSON.parse(decodeURIComponent(option.info));
  24. this.bluetooh(this.bluInfo.info.deviceId);
  25. },
  26. methods: {
  27. bluetooh(deviceId) {
  28. var that = this;
  29. that.$ble.stopBluetoothDevicesDiscovery();
  30. that.$ble.createBLEConnection(
  31. deviceId,
  32. (res) => {
  33. that.getSeviceId(deviceId);
  34. },
  35. (err) => {
  36. console.log(err);
  37. that.bluetoothFail();
  38. }
  39. );
  40. },
  41. // 连接成功后保存连接状态
  42. getSeviceId(deviceId) {
  43. var that = this;
  44. that.$ble.getBLEDeviceServices(
  45. deviceId,
  46. (res) => {
  47. that.services = res.services;
  48. that.bleServiceId = res.services[0].uuid;
  49. this.BLEInformation.serveiceId = res.services[0].uuid;
  50. that.getCharacteristics(deviceId);
  51. },
  52. (err) => {
  53. console.log(err);
  54. that.bluetoothFail();
  55. }
  56. );
  57. },
  58. getCharacteristics(deviceId) {
  59. var that = this;
  60. var list = that.services;
  61. var num = that.serviceId;
  62. var write = that.writeCharacter;
  63. var read = that.readCharacter;
  64. var notify = that.notifyCharacter;
  65. that.$ble.getBLEDeviceCharacteristics(
  66. deviceId,
  67. that.bleServiceId,
  68. (res) => {
  69. for (var i = 0; i < res.characteristics.length; ++i) {
  70. var properties = res.characteristics[i].properties;
  71. if (!notify) {
  72. if (properties.notify) {
  73. notify = true;
  74. }
  75. }
  76. if (!write) {
  77. if (properties.write) {
  78. this.BLEInformation.config_write_char_id =
  79. res.characteristics[2].uuid;
  80. this.BLEInformation.cmd_write_char_id =
  81. res.characteristics[0].uuid;
  82. write = true;
  83. }
  84. }
  85. if (!read) {
  86. if (properties.read) {
  87. this.BLEInformation.config_read_char_id =
  88. res.characteristics[3].uuid;
  89. this.BLEInformation.cmd_read_char_id =
  90. res.characteristics[1].uuid;
  91. read = true;
  92. }
  93. }
  94. }
  95. if (!write || !notify || !read) {
  96. num++;
  97. (that.writeCharacter = write),
  98. (that.readCharacter = read),
  99. (that.notifyCharacter = notify),
  100. (that.serviceId = num);
  101. if (num == list.length) {
  102. // console.log("找不到该读写的特征值")
  103. that.bluetoothFail();
  104. } else {
  105. that.getCharacteristics(deviceId);
  106. }
  107. } else {
  108. that.bluetoothSuccess(res);
  109. }
  110. },
  111. (err) => {
  112. console.log(err);
  113. that.bluetoothFail();
  114. }
  115. );
  116. },
  117. // 蓝牙连接打印机
  118. bluetoothSuccess(res) {
  119. uni.setStorageSync("blefiInfo", this.BLEInformation);
  120. let params = {
  121. title: "连接成功",
  122. confirmText: "继续",
  123. showCancel: false,
  124. };
  125. this.$tip.showModal(params, (res) => {
  126. if (res.confirm) {
  127. // 蓝牙连接成功
  128. this.$tip.redirectTo("/pages/ble/bleWifi");
  129. }
  130. });
  131. },
  132. bluetoothFail() {
  133. // 蓝牙连接失败
  134. this.$tip.redirectTo("/pages/ble/bleFail");
  135. },
  136. },
  137. };
  138. </script>
  139. <style scoped>
  140. .zai-box {
  141. padding: 0;
  142. margin: 0;
  143. height: 100%;
  144. background-color: #fff;
  145. }
  146. .container {
  147. padding: 30rpx;
  148. margin: 0;
  149. font-size: 28rpx;
  150. color: #20212b;
  151. background-color: #fff;
  152. text-align: left;
  153. font-weight: 400;
  154. }
  155. image {
  156. width: 362rpx;
  157. height: 362rpx;
  158. margin-top: 30rpx;
  159. }
  160. .textTitle {
  161. display: block;
  162. font-size: 36rpx;
  163. font-weight: bold;
  164. color: #20212b;
  165. display: block;
  166. margin-bottom: 30rpx;
  167. }
  168. .textItem {
  169. display: block;
  170. font-size: 24rpx;
  171. font-weight: 400;
  172. color: #999999;
  173. line-height: 36rpx;
  174. }
  175. </style>

3. 蓝牙连接WiFi  bleWifi.vue

  1. <template>
  2. <view>
  3. <text>{{ SSID }}</text>
  4. <input type="text" placeholder="请输入密码" v-model="password" />
  5. <button @click="settiing">连接</button>
  6. </view>
  7. </template>
  8. <script>
  9. import APToast from "@/util/APToast.js";
  10. export default {
  11. data() {
  12. return {
  13. SSID: "your SSID",
  14. password: "",
  15. connected: true,
  16. wifiCountDown: 0,
  17. wifiCountInterval: null, // 定时器
  18. blefiInfo: {},
  19. };
  20. },
  21. // 二级页面清除
  22. onUnload() {
  23. this.$ble.offBLEConnectionStateChange();
  24. this.clearIntervalWifi();
  25. },
  26. onLoad(options) {
  27. this.blefiInfo = uni.getStorageSync("blefiInfo");
  28. let sys = uni.getStorageSync("phoneInfo");
  29. if (sys.platform == "android") {
  30. // this.$ble.onBLEMTUChange((res) => {
  31. // console.log(res, "androidMTU");
  32. // });
  33. // this.$ble.getBLEMTU(this.blefiInfo.deviceId, (res) => {
  34. // console.log(res, "mtu");
  35. // });
  36. // 安卓要手动更改MTU值
  37. const mtu = 512;
  38. this.$ble.setBLEMTU(
  39. this.blefiInfo.deviceId,
  40. mtu,
  41. (res) => {
  42. console.log(res);
  43. },
  44. (err) => {
  45. console.log(err);
  46. }
  47. );
  48. }
  49. this.$ble.getBLEDeviceServices(this.blefiInfo.deviceId, (res) => {
  50. this.$ble.getBLEDeviceCharacteristics(
  51. this.blefiInfo.deviceId,
  52. this.blefiInfo.serveiceId,
  53. (res) => {
  54. this.$ble.notifyBLECharacteristicValueChange(
  55. true,
  56. this.blefiInfo.deviceId,
  57. this.blefiInfo.serveiceId,
  58. this.blefiInfo.readCharId,
  59. (res) => {
  60. console.log("启用notify成功");
  61. }
  62. );
  63. }
  64. );
  65. });
  66. this.$ble.onBLEConnectionStateChange((res) => {
  67. this.connected = res.connected;
  68. if (!res.connected) {
  69. this.$tip.loaded();
  70. // 蓝牙连接失败,跳转到失败页面
  71. this.$tip.redirectTo("/pages/ble/bleFail");
  72. }
  73. });
  74. // 接收配网打印机回传的数据
  75. this.$ble.onBLECharacteristicValueChange((res) => {
  76. if (!res || res.value.byteLength == 0) return;
  77. this.clearIntervalWifi();
  78. this.$tip.loaded();
  79. let num = new Int32Array(res.value)[0];
  80. console.log(num, "NUM");
  81. // 失败原因
  82. let tip = APToast.find((item) => item.id == num);
  83. if (num == 0) {
  84. // 连接wifi成功
  85. this.$tip.redirectTo("/pages/ble/WifiSuccess");
  86. } else {
  87. // 连接WiFi失败
  88. this.$tip.redirectTo("/pages/ble/WifiFile",tip);
  89. }
  90. });
  91. },
  92. methods: {
  93. settiing() {
  94. this.startSMSTimer("60");
  95. this.$tip.loading("连接中");
  96. if (this.connected) {
  97. this.sendWifi();
  98. } else {
  99. this.$tip.loaded();
  100. // 蓝牙连接失败,跳转到失败页面
  101. this.$tip.redirectTo("/pages/ble/bleFail");
  102. }
  103. },
  104. // 转UTF-8
  105. sendWifi() {
  106. let msg = {
  107. event: "network",
  108. data: { ssid: this.SSID, password: this.password, authmode: 4 },
  109. };
  110. let buffer = this.stringToUint8Array(JSON.stringify(msg));
  111. this.bleSendWifi(buffer);
  112. },
  113. // json字符串数据转Uint8Array
  114. stringToUint8Array(str) {
  115. // 方法一
  116. // var arr = [];
  117. // for (var i = 0, j = str.length; i < j; ++i) {
  118. // arr.push(str.charCodeAt(i));
  119. // }
  120. // var tmpUint8Array = new Uint8Array(arr);
  121. // return tmpUint8Array.buffer;
  122. // 方法二
  123. let buffer = new ArrayBuffer(str.length);
  124. let dataView = new DataView(buffer);
  125. for (var i = 0; i < str.length; i++) {
  126. dataView.setUint8(i, str.charCodeAt(i));
  127. }
  128. return buffer;
  129. },
  130. bleSendWifi(payload) {
  131. if (this.connected) {
  132. this.$ble.writeBLECharacteristicValueOnce(
  133. this.blefiInfo.deviceId,
  134. this.blefiInfo.serveiceId,
  135. this.blefiInfo.writecharId,
  136. payload
  137. );
  138. if (this.blefiInfo.readCharId) {
  139. this.$ble.readBLECharacteristicValue(
  140. this.blefiInfo.deviceId,
  141. this.blefiInfo.serveiceId,
  142. this.blefiInfo.readCharId
  143. );
  144. }
  145. }
  146. },
  147. startSMSTimer(val) {
  148. this.wifiCountDown = val;
  149. this.wifiCountInterval = setInterval(() => {
  150. this.wifiCountDown--;
  151. // console.log(this.wifiCountDown);
  152. if (this.wifiCountDown <= 0) {
  153. clearInterval(this.wifiCountInterval);
  154. this.wifiCountInterval = null;
  155. this.$tip.loaded();
  156. // 连接WiFi失败
  157. this.$tip.redirectTo("/pages/ble/WifiFile");
  158. }
  159. }, 1000);
  160. },
  161. clearIntervalWifi() {
  162. this.wifiCountDown = 0;
  163. if (this.wifiCountInterval) {
  164. clearInterval(this.wifiCountInterval);
  165. this.wifiCountInterval = null;
  166. }
  167. },
  168. },
  169. };
  170. </script>

4. 手机连接蓝牙失败、蓝牙连接WiFi成功/失败(关闭蓝牙连接)

  1. <script>
  2. export default {
  3. onLoad() {
  4. // 使用完成后在合适的时机断开连接和关闭蓝牙适配器
  5. this.$ble.closeBLEConnection(this.deviceId);
  6. this.$ble.closeBluetoothAdapter();
  7. },
  8. };
  9. </script>

5.ble.js

  1. class ble {
  2. openBluetoothAdapter(success, failure) {
  3. uni.openBluetoothAdapter({
  4. success: (res) => {
  5. success(res);
  6. },
  7. fail: (err) => {
  8. failure(err);
  9. },
  10. });
  11. }
  12. getBluetoothAdapterState(success) {
  13. uni.getBluetoothAdapterState({
  14. success: (res) => {
  15. success(res);
  16. },
  17. });
  18. }
  19. //停止搜寻附近的蓝牙外围设备
  20. stopBluetoothDevicesDiscovery() {
  21. uni.stopBluetoothDevicesDiscovery();
  22. }
  23. //获取蓝牙设备信息
  24. getBluetoothDevices(success) {
  25. // 开始搜寻附近的蓝牙外围设备
  26. uni.startBluetoothDevicesDiscovery({
  27. success: (res) => {
  28. setTimeout(() => {
  29. // 获取搜索到的设备信息
  30. uni.getBluetoothDevices({
  31. success: (res) => {
  32. let bluetoohList = [];
  33. var num = 0;
  34. for (var i = 0; i < res.devices.length; ++i) {
  35. if (res.devices[i].name != "未知设备") {
  36. bluetoohList[num] = res.devices[i];
  37. num++;
  38. }
  39. }
  40. this.stopBluetoothDevicesDiscovery();
  41. success(bluetoohList);
  42. },
  43. });
  44. }, 5000);
  45. // that.onBluetoothDeviceFound();
  46. },
  47. });
  48. }
  49. openSetting() {
  50. uni.openSetting({
  51. //opensetting是调起设置页面的
  52. success: (res) => {
  53. if (res.authSetting == true) {
  54. //判断res.authsetting的值是true还是false
  55. uni.openBluetoothAdapter();
  56. }
  57. },
  58. });
  59. }
  60. //断开与低功耗蓝牙设备的连接
  61. closeBLEConnection(deviceId) {
  62. uni.closeBLEConnection({
  63. deviceId: deviceId,
  64. });
  65. }
  66. offBLEConnectionStateChange() {
  67. wx.offBLEConnectionStateChange();
  68. }
  69. //连接低功耗蓝牙设备
  70. createBLEConnection(deviceId, success, failure) {
  71. uni.createBLEConnection({
  72. deviceId: deviceId,
  73. success: (res) => {
  74. success(res);
  75. },
  76. fail: (err) => {
  77. failure(err);
  78. },
  79. });
  80. }
  81. //获取蓝牙设备所有服务
  82. getBLEDeviceServices(deviceId, success, failure) {
  83. wx.getBLEDeviceServices({
  84. deviceId: deviceId,
  85. success: (res) => {
  86. success(res);
  87. },
  88. fail(err) {
  89. failure(err);
  90. },
  91. });
  92. }
  93. //获取蓝牙设备某个服务中所有特征值
  94. getBLEDeviceCharacteristics(deviceId, serviceId, success, failure) {
  95. wx.getBLEDeviceCharacteristics({
  96. deviceId: deviceId,
  97. serviceId: serviceId,
  98. success: (res) => {
  99. success(res);
  100. },
  101. fail(err) {
  102. failure(err);
  103. },
  104. });
  105. }
  106. notifyBLECharacteristicValueChange(
  107. state,
  108. deviceId,
  109. serviceId,
  110. characteristicId,
  111. success
  112. ) {
  113. wx.notifyBLECharacteristicValueChange({
  114. state: state,
  115. deviceId: deviceId,
  116. serviceId: serviceId,
  117. characteristicId: characteristicId,
  118. success: function (res) {
  119. success(res);
  120. },
  121. });
  122. }
  123. onBLEConnectionStateChange(success) {
  124. wx.onBLEConnectionStateChange((res) => {
  125. success(res);
  126. });
  127. }
  128. // 接收配网打印机回传的数据
  129. onBLECharacteristicValueChange(success) {
  130. wx.onBLECharacteristicValueChange((res) => {
  131. success(res);
  132. });
  133. }
  134. //关闭蓝牙模块
  135. closeBluetoothAdapter() {
  136. wx.closeBluetoothAdapter();
  137. }
  138. // 不分包写入蓝牙
  139. writeBLECharacteristicValueOnce(
  140. deviceId,
  141. serviceId,
  142. characteristicId,
  143. value
  144. ) {
  145. wx.writeBLECharacteristicValue({
  146. deviceId: deviceId,
  147. serviceId: serviceId,
  148. characteristicId: characteristicId,
  149. value: value,
  150. });
  151. }
  152. readBLECharacteristicValue(deviceId, serviceId, characteristicId) {
  153. wx.readBLECharacteristicValue({
  154. deviceId: deviceId,
  155. serviceId: serviceId,
  156. characteristicId: characteristicId,
  157. });
  158. }
  159. getBLEMTU(deviceId, success) {
  160. wx.getBLEMTU({
  161. deviceId: deviceId,
  162. writeType: "write",
  163. success(res) {
  164. success(res.mtu);
  165. },
  166. });
  167. }
  168. onBLEMTUChange(success) {
  169. wx.onBLEMTUChange(function (res) {
  170. success(res.mtu);
  171. });
  172. }
  173. setBLEMTU(deviceId, mtu, success, failure) {
  174. wx.setBLEMTU({
  175. deviceId: deviceId,
  176. mtu: mtu,
  177. success: (res) => {
  178. success(res);
  179. },
  180. fail: (res) => {
  181. failure(res);
  182. },
  183. });
  184. }
  185. }
  186. const bleDevice = new ble();
  187. export default bleDevice;

6.APToast.js

  1. const message = [
  2. {
  3. id:0,
  4. type:"WIFI_REASON_SUCCESS",
  5. message:"打印机连接成功"
  6. },
  7. {
  8. id:2,
  9. type:"WIFI_REASON_AUTH_EXPIRE",
  10. message:"身份验证超时"
  11. },
  12. {
  13. id:3,
  14. type:"WIFI_REASON_AUTH_LEAVE",
  15. message:"连接中断"
  16. },
  17. {
  18. id:8,
  19. type:"WIFI_REASON_ASSOC_LEAVE",
  20. message:"连接中断"
  21. },
  22. {
  23. id:15,
  24. type:"WIFI_REASON_4WAY_HANDSHAKE_TIMEOUT",
  25. message:"密码错误"
  26. },
  27. {
  28. id:201,
  29. type:"WIFI_REASON_NO_AP_FOUND",
  30. message:"未找到可用的网络"
  31. },
  32. {
  33. id:202,
  34. type:"WIFI_REASON_AUTH_FAIL",
  35. message:"密码错误或身份验证超时"
  36. },
  37. {
  38. id:203,
  39. type:"WIFI_REASON_ASSOC_FAIL",
  40. message:"设备无法与WiFi成功关联"
  41. },
  42. {
  43. id:204,
  44. type:"WIFI_REASON_HANDSHAKE_TIMEOUT",
  45. message:"密码错误"
  46. },
  47. {
  48. id:205,
  49. type:"WIFI_REASON_CONNECTION_FAIL",
  50. message:"连接失败"
  51. },
  52. ]
  53. export default message;

7.tip.js

  1. export default class Tips {
  2. /**
  3. * 弹出提示框
  4. */
  5. static success(title, duration = 1000) {
  6. setTimeout(() => {
  7. uni.showToast({
  8. title: title,
  9. icon: "success",
  10. mask: true,
  11. duration: duration,
  12. });
  13. }, 300);
  14. if (duration > 0) {
  15. return new Promise((resolve, reject) => {
  16. setTimeout(() => {
  17. resolve();
  18. }, duration);
  19. });
  20. }
  21. }
  22. /**
  23. * 弹出加载提示
  24. */
  25. static loading(title = "加载中") {
  26. if (Tips.isLoading) {
  27. return;
  28. }
  29. Tips.isLoading = true;
  30. uni.showLoading({
  31. title: title,
  32. mask: true,
  33. });
  34. }
  35. /**
  36. * 加载完毕
  37. */
  38. static loaded() {
  39. if (Tips.isLoading) {
  40. Tips.isLoading = false;
  41. uni.hideLoading();
  42. }
  43. }
  44. /**
  45. * 关闭当前页面,跳转到新页面
  46. */
  47. static redirectTo(urls, item) {
  48. uni.redirectTo({
  49. url: item
  50. ? urls + "?info=" + encodeURIComponent(JSON.stringify(item))
  51. : urls, // JSON.parse(decodeURIComponent(option.info));
  52. });
  53. }
  54. /**
  55. * 弹出确认窗口
  56. */
  57. static showModal(val, success) {
  58. uni.showModal({
  59. title: val.title ? val.title : "",
  60. content: val.content ? val.content : "",
  61. showCancel: val.showCancel,
  62. confirmText: val.confirmText ? val.confirmText : "确定",
  63. cancelText: val.cancelText ? val.cancelText : "取消",
  64. cancelColor: "#999999", //取消按钮颜色
  65. confirmColor: "#00A0E9", //确定按钮颜色
  66. success: (res) => {
  67. success(res);
  68. },
  69. });
  70. }
  71. }
  72. /**
  73. * 静态变量,是否加载中
  74. */
  75. Tips.isLoading = false;

8.main.js

  1. import ble from "./common/util/ble.js";
  2. import tip from "./common/util/tip.js";
  3. // ble
  4. Vue.prototype.$ble = ble;
  5. // tip
  6. Vue.prototype.$tip = tip;

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小蓝xlanll/article/detail/573600
推荐阅读
相关标签
  

闽ICP备14008679号