Nuxt 插件 属性 在类型 'CombinedVueInstance 上不存在
Nuxt plugin property does not exist on type 'CombinedVueInstance
我创建了一个插件并想在我的一个组件中使用它。
来自位于 ~/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;
}
}
我似乎找不到解决这个问题的方法。谁能帮帮我?
declare module "vue/types/vue"
是一个 module augmentation - for augmentation to work correctly, it needs to be placed inside the TS file that contains at least one top-level import/export (more details )
所以我的建议是将该代码从 vue-shim.d.ts
直接移动到 socket.client.ts
通过稍微重构我的代码,我终于让它工作了。
免责声明;这个解决方案对我有用,因为它让我以另一种方式使用插件。这不是具体问题的答案。这个问题的答案可以通过使用下面的插件代码并稍微更改 index.d.ts 来实现,这样 $socket 也可以在 vue 组件内部访问。详细了解 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)
我创建了一个插件并想在我的一个组件中使用它。
来自位于 ~/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;
}
}
我似乎找不到解决这个问题的方法。谁能帮帮我?
declare module "vue/types/vue"
是一个 module augmentation - for augmentation to work correctly, it needs to be placed inside the TS file that contains at least one top-level import/export (more details
所以我的建议是将该代码从 vue-shim.d.ts
直接移动到 socket.client.ts
通过稍微重构我的代码,我终于让它工作了。
免责声明;这个解决方案对我有用,因为它让我以另一种方式使用插件。这不是具体问题的答案。这个问题的答案可以通过使用下面的插件代码并稍微更改 index.d.ts 来实现,这样 $socket 也可以在 vue 组件内部访问。详细了解 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)