前提:需求需要利用websocket进行前后端传讯
请注意:向服务器发送消息方法待校验
一些特殊事项
- 在vuex使用this,需要在调用actions 时传入this指针
this.connectWebsocket(this)
在actions 中重新赋值
connectWebsocket({ commit, rootState }, _this) {
...
// 赋值this
state._this = _this
}
- 在vuex内调用其他模块的state
connectWebsocket({ commit, rootState }, _this) {
...
// 获取vuex另一个模块的state
const userInfo = rootState.user.userInfo
}
Vuex封装websocket
后端返回的数据格式
data='{msgType: xxx', data: {...}}'
文件夹内
|- store
|----modules
|-------websocket.js
|----index.js
|----getters.js
websocket.js
const state = {
url: 'http://127.0.0.1:80/websocket/', //后端提供的链接路径
ws: null,
wsMessage: null,
_this: null
}
const mutations = {
CONNECT_WEBSOCKET: (state, data) => {
state.wsMessage = data.includes('msgType') ? JSON.parse(data) : data
}
}
const actions = {
connectWebsocket({ commit, rootState }, _this) {
// 赋值this
state._this = _this
if (!('WebSocket' in window)) {
_this.msgError('您的浏览器不支持WebSocket');
return;
}
// 获取vuex另一个模块的state
const userInfo = rootState.user.userInfo
// 将http协议名替换为 ws://
state.url = state.url.replace('http', 'ws')
state.ws = new WebSocket(state.url + '?userId=' + userInfo.userId);
state.ws.onopen = function(event) {
console.log('**********************连接开始**********************')
};
state.ws.onmessage = function(event) {
commit('CONNECT_WEBSOCKET', event.data)
console.log('**********************连接接收**********************')
};
state.ws.onclose = function(event) {
console.log('**********************连接关闭**********************')
};
state.ws.onerror = function(event) {
console.log('**********************连接异常**********************')
_this.msgError('连接异常!')
};
},
// 关闭websocket连接
closeWebsocket({ commit }, userId) {
if (state.ws) {
state.ws.close();
state.ws = null;
}
},
// 向服务器发送消息
sendWebsocket({ commit }, message) {
if (!state.ws || state.ws.readyState !== 1) {
state._this.msgError('未连接到服务器');
return;
}
if (!message) {
state._this.msgError('请输入发送内容');
return;
}
state.ws.send(message);
}
}
export default {
namespaced: true,
state,
mutations,
actions
}
getters.js
const getters = {
wsMessage: state => state.websocket.wsMessage
}
export default getters
index.js
import Vue from 'vue'
import Vuex from 'vuex'
import getters from './getters'
import websocket from '@/store/modules/websocket'
Vue.use(Vuex)
const store = new Vuex.Store({
modules: {
websocket
},
getters
})
export default store
main.js
import store from './store';
文件内调用
...
computed: {
...mapState({
wsMessage: state => state.websocket.wsMessage
})
},
watch: {
// 监听websocket返回的数据
wsMessage: {
deep: true,
handler(val) {
if (val && val.msgType == 'excelTask') {
this.msgError('文件导出中……')
const data = val.data
if (data.status == 3) {
this.msgError('文件导出失败!')
} else {
downloadFileUrl(data.fileUrl, data.fileName).then(() => {
this.msgSuccess('文件导出成功!')
});
}
// 调用关闭连接
this.closeWebsocket();
}
}
}
},
methods: {
// 获取vuex actions
...mapActions({
connectWebsocket: 'websocket/connectWebsocket',
closeWebsocket: 'websocket/closeWebsocket'
}),
// 导出
handleExport() {
// 连接websocket 并传入this指针
this.connectWebsocket(this)
this.$confirm('确认导出?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'primary'
}).then(() => {
export({}).catch(() => {
this.msgError('导出失败!')
})
}).catch(() => {
this.closeWebsocket();
}
}
}
...