Nuxt 插件属性在“CombinedVueInstance”类型上不存在
Posted
技术标签:
【中文标题】Nuxt 插件属性在“CombinedVueInstance”类型上不存在【英文标题】:Nuxt plugin property does not exist on type 'CombinedVueInstance 【发布时间】:2022-01-03 18:15:57 【问题描述】:我创建了一个插件并想在我的一个组件中使用它。
位于~/plugins/socket.client.ts
下的插件代码:
import io from 'socket.io-client'
import Plugin from '@nuxt/types'
const socketIOPlugin: Plugin = (_, inject) =>
const socketUrl: string | undefined = process.env.socket_url
if (!socketUrl || socketUrl.length <= 0)
throw new Error('socketUrl is undefined.')
const socket = io(socketUrl)
inject('socket', socket)
export default socketIOPlugin
在 nuxt.config.js 中注册。
plugins: ['~/plugins/socket.client']
我在我的组件中这样使用它:
import Vue from 'vue'
export default Vue.extend(
mounted()
this.$socket.on("example:hello", (data: any) =>
console.log(data);
);
,
)
但是,当我启动 nuxt 时,我收到以下错误:
Property '$socket' does not exist on type 'CombinedVueInstance<Vue, unknown, unknown, unknown, Readonly<Record<never, any>>>'.
我已经尝试添加一个 vue-shim.d.ts 文件,但仍然没有任何变化。
declare module "*.vue"
import Vue from 'vue'
export default Vue
declare module "vue/types/vue"
import Socket from "socket.io-client";
interface Vue
$socket: Socket;
我似乎找不到解决这个问题的方法。谁能帮帮我?
【问题讨论】:
【参考方案1】:declare module "vue/types/vue"
是一个module augmentation - 为了使扩充功能正常工作,它需要放在包含至少 一个 ***导入/导出的 TS 文件中(更多详细信息 @987654322 @)
所以我的建议是将代码从 vue-shim.d.ts
直接移动到 socket.client.ts
【讨论】:
我已将声明模块部分放在我的 const socketIOPlugin... 代码之上,但我仍然收到相同的错误消息。【参考方案2】:我终于通过稍微重构我的代码让它工作了。
免责声明;这个解决方案对我有用,因为它允许我以另一种方式使用插件。这不是问题的具体答案。这个问题的答案可以通过使用下面的插件代码并稍微更改 index.d.ts 来实现,以便在 vue 组件中也可以访问 $socket。阅读更多关于此here 的信息。
~/plugins/socket.client.ts
import Plugin from '@nuxt/types'
import io, Socket from 'socket.io-client'
function getSocketConnection(): Socket
const socketUrl: string | undefined = process.env.socket_url
if (!socketUrl || socketUrl.length <= 0)
throw new Error('socketUrl is undefined.')
return io(socketUrl)
const socketIOPlugin: Plugin = (_, inject) =>
inject('socket', getSocketConnection())
export default socketIOPlugin
export const socket = getSocketConnection()
我还将 vue-shim.d.ts
重命名为 index.d.ts
并添加了以下几行:
import accessorType from '~/store'
import socket from '~/plugins/socket.client'
declare module 'vuex/types/index'
// eslint-disable-next-line @typescript-eslint/no-unused-vars
interface Store<S>
$socket: typeof socket
declare module 'vue/types/vue'
interface Vue
$accessor: typeof accessorType
declare module '@nuxt/types'
interface NuxtAppOptions
$accessor: typeof accessorType
我没有在我的组件中使用 socket.io 插件,而是创建了一个存储 ~/store/index.ts
来处理所有套接字事件。
import type ActionTree, GetterTree, MutationTree from 'vuex'
import getAccessorType from 'typed-vuex'
export const state = () => (
posts: [] as any[],
)
export type RootState = ReturnType<typeof state>
export const getters: GetterTree<RootState, RootState> =
posts: (state) => state.posts,
export const mutations: MutationTree<RootState> =
SET_POSTS: (state: RootState, posts: any[]) => (state.posts = posts),
export const actions: ActionTree<RootState, RootState> =
fetchPosts( commit )
this.$socket.emit('example:getPosts')
this.$socket.once('example:posts', (data: any) =>
commit('SET_POSTS', data)
)
,
export const accessorType = getAccessorType(
state,
getters,
mutations,
actions,
modules: ,
)
现在使用起来容易多了,一切都更新了使用 vuex 的方式。
~/pages/index.vue
<script lang='ts'>
import Component, Vue from 'nuxt-property-decorator'
@Component
export default class Index extends Vue
get posts()
return this.$accessor.posts
fetchPosts()
this.$accessor.fetchPosts()
</script>
要让一切正常工作,您需要安装以下 npm 包:
@nuxt/types typed-vuex vue-class-component nuxt-property-decorator nuxt-typed-vuex(不要忘记将此添加到您的 nuxt.config.ts buildModules)【讨论】:
以上是关于Nuxt 插件属性在“CombinedVueInstance”类型上不存在的主要内容,如果未能解决你的问题,请参考以下文章