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&lt;Vue, unknown, unknown, unknown, Readonly&lt;Record&lt;never, any&gt;&gt;&gt;'.

我已经尝试添加一个 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”类型上不存在的主要内容,如果未能解决你的问题,请参考以下文章

NuxtJS项目——插件

如何使用 Nuxt 和 Jest 在 Vuex 商店测试中访问 this.app 和/或注入插件

如何在 nuxt js 中使用 vuetify 作为插件?

如何从 nuxt 插件发出事件?

如何在nuxt中使用vue插件

如何在 Nuxt 插件中使用错误功能?