多维表格
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

99 lines
2.2 KiB

import { defineNuxtPlugin } from 'nuxt/app'
import io from 'socket.io-client'
// todo: ignore init if tele disabled
export default defineNuxtPlugin(async (nuxtApp) => {
const router = useRouter()
const route = useRoute()
const { user } = useUser()
let socket
const init = async (token) => {
try {
if (socket)
socket.disconnect()
// todo: extract base url
const url = 'http://localhost:8080' // new URL($axios.defaults.baseURL, window.location.href.split(/[?#]/)[0]).href
socket = io(url, {
extraHeaders: { 'xc-auth': token },
})
socket.on('connect_error', () => {
socket.disconnect()
socket = null
})
}
catch {
}
}
router.afterEach((to, from) => {
if (!socket || (to.path === from.path && (to.query && to.query.type) === (from.query && from.query.type)))
return
socket.emit('page', {
path: to.matched[0].path + (to.query && to.query.type ? `?type=${to.query.type}` : ''),
})
})
if (socket) {
socket.emit('page', {
path: route.matched[0].path + (route.query && route.query.type ? `?type=${route.query.type}` : ''),
})
}
const tele = {
emit(evt, data) {
// debugger
if (socket) {
socket.emit('event', {
event: evt,
...(data || {}),
path: route?.matched?.[0]?.path,
})
}
},
}
inject('tele', tele)
inject('e', tele.emit)
nuxtApp.vueApp.directive('t', {
created(el, binding, vnode) {
if (vnode.el)
vnode.el.addEventListener('click', getListener(binding))
else
el.addEventListener('click', getListener(binding))
},
})
function getListener(binding) {
return function () {
if (!socket)
return
const event = binding.value && binding.value[0]
const data = binding.value && binding.value[1]
const extra = binding.value && binding.value.slice(2)
tele.emit(event,
{
data,
extra,
})
}
}
if (user.token)
init(user.token)
watch(() => user.token, (newToken, oldToken) => {
if (newToken !== oldToken) {
init(newToken)
}
else if (!newToken) {
socket.disconnect()
socket = null
}
})
})