diff --git a/README.md b/README.md index b0482de..89d5af0 100644 --- a/README.md +++ b/README.md @@ -51,16 +51,79 @@ npm run dev:mp-weixin 4. 常用的订单组件 5. 信息展示组件 +# 插件的使用 + +#### tab - 页面插件 + +可以通过设置参数中的config.data来实现页面传参 + +| 方法 | 作用 | 参数 | +| ------------ | ------------------------------------------------ | ----------- | +| getData | 可以拿到上个页面通过tab传递的参数 | 无 | +| reLaunch | 关闭所有页面,打开到应用内的某个页面 | url、config | +| switchTab | 跳转到 tabBar 页面,并关闭其他所有非 tabBar 页面 | url、config | +| redirectTo | 关闭当前页面,跳转到应用内的某个页面 | url、config | +| navigateTo | 保留当前页面,跳转到应用内的某个页面 | url、config | +| navigateBack | 关闭当前页面,返回上一页面或多级页面 | config | + +#### auth - 鉴权插件 + +下面所有方法返回值都是布尔值,permission代表权限字符串,role代表角色字符串,复数形式代表数组。 + +| 方法 | 作用 | 参数 | +| ----------- | ------------------------------------------ | ----------- | +| hasPermi | 验证用户是否具备某权限 | permission | +| hasPermiOr | 验证用户是否含有指定权限,只需包含其中一个 | permissions | +| hasPermiAnd | 验证用户是否含有指定权限,必须全部拥有 | permissions | +| hasRole | 验证用户是否具备某角色 | role | +| hasRoleOr | 验证用户是否含有指定角色,只需包含其中一个 | roles | +| hasRoleAnd | roles | roles | + +#### modal - 弹窗插件 + +content是消息内容,option是详细配置。 + +| 方法 | 作用 | 参数 | +| ------------ | ------------------------------ | ------- | +| msg | 消息提示 | content | +| msgError | 错误消息 | content | +| msgSuccess | 成功消息 | content | +| hideMsg | 隐藏消息 | 无 | +| alert | 弹出提示 | content | +| confirm | 确认窗体 | content | +| showToast | 提示信息 | option | +| loading | 打开遮罩层,需要手动关闭遮罩层 | content | +| closeLoading | 关闭遮罩层 | 无 | + +#### bus - 事件插件 + +eventName是事件名称,eventFun是事件处理函数,请尽量避免事件插件的使用,请在组件销毁是解绑素有该组件有关的事件,避免产生bug。 + +| 方法 | 作用 | 参数 | +| ----- | ------------ | ------------------- | +| $on | 绑定一个事件 | eventName、eventFun | +| $off | 解绑一个事件 | eventName | +| $emit | 触发一个事件 | eventName、...args | + +#### socket + +设置项enableUUID,是否启用基于uuid的消息处理机制,要求当发送的消息携带uuid字段时,返回的消息也要携带uuid字段。 + +设置项enableEvent,是否启用基于事件的消息处理机制,要求当希望被事件处理函数处理的消息需要携带event字段。 + +| 方法 | 作用 | 参数 | +| --------- | ----------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------- | +| connect | 连接websocke,当连接成功后触发回调函数 | 最简单的用法就是传入{url:"ws://demo"} | +| send | 发送信息,当uuid不为空且不为false时,当收到
携带相同uuid的消息时触发回调函数,只触发一次。
否则由默认处理函数处理。 | msg消息内容,会被处理成json字符串
uuid唯一标识符,可以手动传入,也可以设置为true
当为true时会自动生成一个uuid并添加到msg中。 | +| close | 关闭连接,会触发回调函数的内容,不会触发默认
关闭事件的处理函数,也不会修改默认关闭事件的
处理函数。 | 无 | +| on | 监听事件,当收到携带event的消息时会调用回调函数。 | event事件的名称 | +| off | 取消监听事件 | | +| onMessage | 定义默认监听事件 | callback 默认监听事件的处理函数 | +| onError | 定义异常事件 | callback 默认异常事件的处理函数 | +| onClose | 定义关闭事件 | callback 默认关闭事件的处理函数 | + # 作者建议 -plugins下面的tab、auth、modal已经打了上详细的注释文档,使用代码提示的时候应该可以直接看到。 - -tab: 用于页面的跳转和页面间通讯 - -auth: 用于鉴权操作 - -modal: 用于弹窗 - ### 对于选项式 ```js diff --git a/src/App.vue b/src/App.vue index 5dc2780..7fdaed2 100644 --- a/src/App.vue +++ b/src/App.vue @@ -2,6 +2,19 @@ export default { onLaunch: function () { console.log('App Launch') + this.$socket.connect({ url: "ws://127.0.0.1:8080/sc" }).then(res => { + console.log("success"); + this.$socket.onMessage(res => { + console.log("onmessage",res); + }) + this.$socket.on("on").then(res=>{ + console.log("on",res); + }) + this.$socket.send({msg:"xxx"},true).then(res=>{ + console.log("callback-uuid",res); + }) + this.$socket.send({event:"on"}) + }) }, onShow: function () { console.log('App Show') diff --git a/src/plugins/index.ts b/src/plugins/index.ts index de429c2..77ac40b 100644 --- a/src/plugins/index.ts +++ b/src/plugins/index.ts @@ -2,6 +2,7 @@ import Tab from './tab' import Auth from './auth' import Modal from './modal' import Bus from './bus'; +import Socket from './socket' import { App } from 'vue'; @@ -9,6 +10,7 @@ export const tab = Tab; export const auth = Auth; export const modal = Modal; export const bus = Bus +export const socket = Socket /** * 在组合式API中可以通过 import { tab, auth, modal } form '@/plugins' 来使用tab、auth、modal @@ -20,5 +22,6 @@ export default { app.config.globalProperties.$auth = auth app.config.globalProperties.$modal = modal app.config.globalProperties.$bus = bus + app.config.globalProperties.$socket = socket } } diff --git a/src/plugins/socket.ts b/src/plugins/socket.ts new file mode 100644 index 0000000..43ed0e0 --- /dev/null +++ b/src/plugins/socket.ts @@ -0,0 +1,131 @@ +import { getToken } from '@/utils/auth' +import { generateUUID } from '@/utils/geek'; +let _socket: UniApp.SocketTask; +let _callback: { [key: string]: (data: any) => void } = {} +const enableUUID = true // 需要接收信息中包含uuid字段,uuid优先级高于event +const enableEvent = true // 需要接收信息中包含event字段 + +interface ConnectSocketOption extends UniApp.ConnectSocketOption { + headers: { + isToken: boolean + } +} + +export default { + /** + * 连接websocket + * 最简单的用法就是传入{url:"ws://demo"} + * 当连接成功后触发回调函数 + */ + connect(options: ConnectSocketOption) { + return new Promise((resolve, reject) => { + const isToken = (options.headers || {}).isToken === false + options.header = options.header || { 'content-type': 'application/json' } + if (getToken() && !isToken) { + options.header['Authorization'] = 'Bearer ' + getToken() + } + _socket = uni.connectSocket({ + url: options.url, + header: options.header, + method: options.method || 'GET', + fail: reject + }); + _socket.onError(reject) + _socket.onOpen(resolve) + _socket.onMessage(res => { + let data = JSON.parse((res || {}).data) + if (enableUUID && (data || {}).uuid !== undefined) { + _callback[data.uuid](data) + } else if (enableEvent && (data || {}).event !== undefined) { + _callback[data.event](data) + } + }) + }) + }, + /** + * 发送信息 + * @param msg 消息,会被处理成json字符串 + * @param uuid 唯一标识,可以传入uuid,也可以传入true自动生成uuid,flase表示该消息不需要单独处理 + * @returns + */ + send(msg: any, uuid: string | boolean = false) { + return new Promise((resolve, reject) => { + if (enableUUID && uuid != undefined && uuid != "" && uuid != false) { + if (uuid == true) { + msg.uuid = generateUUID() + _callback[msg.uuid] = resolve + } else { + _callback[uuid] = resolve + } + } + _socket.send({ + data: JSON.stringify(msg), + fail: reject + }) + }) + }, + /** + * 关闭连接 + * @returns 关闭连接的Promise,回调函数只会运行一次 + */ + close() { + return new Promise((resolve, reject) => { + _socket.close({ + fail: reject + }) + let onclose = _socket.onClose + _socket.onClose(res => { + resolve(res) + _socket.onClose(onclose) + }) + }) + }, + /** + * 监听事件 + * @param event 要监听的事件 + * @returns 在回调函数中处理事件 + */ + on(event: string) { + return new Promise((resolve) => { + _callback[event] = resolve + }) + }, + /** + * 取消监听事件 + * @param event 要取消监听的事件 + */ + off(event: string) { + delete _callback[event] + }, + /** + * 定义默认监听事件 + * @param callback 默认监听事件的处理函数 + */ + onMessage(callback: (data: any) => void) { + _socket.onMessage(res => { + let data = JSON.parse((res || {}).data) + if (enableUUID && (data || {}).uuid !== undefined) { + _callback[data.uuid](res) + delete _callback[data.uuid] + } else if (enableEvent && (data || {}).event !== undefined) { + _callback[data.event](res) + } else { + callback(data) + } + }) + }, + /** + * 定义异常事件 + * @param callback 默认异常事件的处理函数 + */ + onError(callback: (data: any) => void) { + _socket.onError(callback) + }, + /** + * 定义关闭事件 + * @param callback 默认关闭事件的处理函数 + */ + onClose(callback: (data: any) => void) { + _socket.onError(callback) + } +}; \ No newline at end of file diff --git a/src/utils/geek.ts b/src/utils/geek.ts index 53c1eb7..472fa32 100644 --- a/src/utils/geek.ts +++ b/src/utils/geek.ts @@ -55,4 +55,22 @@ export function deepCloneTo(obj: T, result: T) { result[key] = deepClone(value); } return result; -} \ No newline at end of file +} + +/** + * 获取uuid + * @returns 生成的uuid字符串 + */ +export function generateUUID(): string { + let uuid = ''; + const chars = '0123456789abcdef'; + + for (let i = 0; i < 32; i++) { + if (i === 8 || i === 12 || i === 16 || i === 20) { + uuid += '-'; + } + uuid += chars[Math.floor(Math.random() * chars.length)]; + } + + return uuid; + } \ No newline at end of file