解决“类型‘Vue’上不存在属性”错误

问题描述 投票:0回答:14

我正在使用 Typescript 和 Vuejs 来构建应用程序。我有几个独立组件 (.vue) 文件,我正在将它们导入到 Typescript (.ts) 文件中。在 Typescript 文件中,我从 npm Vue 库导入 Vue,然后创建一个新的 Vue 来显示我的组件。我看到的错误是:

“Vue”类型上不存在属性 x

我的构建系统是带有 tsc 的 Webpack。为什么我会收到此错误以及如何解决它?

main.ts

import Vue from 'vue';
import Competency from '../components/competency.vue';

new Vue({
  el: "#app",
  components: {
    'competency': Competency
  },
  data:{
    count: 0
  },
  methods:{
    initialize: function(){
      this.count = count + 1; // Errors here with Property count does not exist on type vue
    }
  }
})

tsconfig

{
  "compilerOptions": {
    // "allowJs": true,
    "allowSyntheticDefaultImports": true,
    "experimentalDecorators": true,
    "lib": [
      "es2015",
      "dom",
      "es2015.promise"
    ],
    "module": "es2015",
    "moduleResolution": "node",
    "noEmitOnError": true,
    "noImplicitAny": false,
    //"outDir": "./build/",
    "removeComments": false,
    "sourceMap": true,
    "target": "es5"

  },
  "exclude": [
    "./node_modules",
    "wwwroot",
    "./Model"
  ],
  "include": [
    "./CCSEQ",
    "./WebResources"
  ]
}

webpack.config.js

const path = require('path');
const webpack = require('webpack');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const CleanWebpackPlugin = require('clean-webpack-plugin');

module.exports = {
    entry: {
        Evaluations: './WebResources/js/main.ts'
    },
    devServer: {
        contentBase: './dist'
    },
    module: {
        rules: [{
                test: /\.ts$/,
                exclude: /node_modules|vue\/src/,
                loader: 'ts-loader',
                exclude: /node_modules/,
                options: {
                    appendTsSuffixTo: [/\.vue$/]
                }
            },
            {
                test: /\.vue$/,
                loader: 'vue-loader',
                options: {
                    esModule: true
                }
            },
            {
                test: /\.css$/,
                use: [
                    'style-loader',
                    'css-loader'
                ]
            },
            {
                test: /\.(png|svg|jpg|gif)$/,
                use: [
                    'file-loader'
                ]
            },
        ]
    },
    resolve: {
        extensions: [".tsx", ".ts", ".js"],
        alias: {
            'vue$': 'vue/dist/vue.esm.js'
        }
    },
    plugins: [
        new CleanWebpackPlugin(['dist']),
        new HtmlWebpackPlugin({
            filename: 'Evaluations.html',
            template: './WebResources/html/Evaluations.html'
        }), new HtmlWebpackPlugin({
            filename: 'ExpenseUpload.html',
            template: './WebResources/html/ExpenseUpload.html'
        }), new webpack.optimize.CommonsChunkPlugin({
            name: 'WebAPI'
        })
    ],
    output: {
        filename: '[name].bundle.js',
        path: path.resolve(__dirname, 'dist')
    }
}
typescript webpack vue.js vuejs2 vue-component
14个回答
29
投票

我遇到了同样的问题,但是导出组件。 一些 VS 代码片段创建的模板没有必要的类型,如下所示

export default {
  data() {
    return {
      x: "something",
    };
  },
  methods: {
    rename(name: string) {
      this.x = name;
    },
    
  },
};

问题是我没有添加

defineComponent()
来导出默认值。应该是这样


import { defineComponent } from "vue";

export default defineComponent({
  data() {
    return {
      x: "something",
    };
  },
  methods: {
    rename(name: string) {
      this.x = name;
    },
    
  },
});

确保您使用

defineComponent()
函数导出组件。


10
投票

添加另一个答案以汇集您可能需要解决的几个问题。

确保在导入的文件名中包含“.vue”扩展名

同时

import Competency from '../components/competency';

import Competency from '../components/competency.vue';

可能会编译成功,第二个将有助于避免在某些IDE(例如VS Code)中出现错误。

添加垫片类型文件

正如 @May 上面指出的,您需要一个导入和重新导出“Vue”类型的文件。在@May的回答中,它被命名为

vue-file-import.d.ts
,但在互联网上的其他地方,它通常被称为
vue-shim.d.ts
。无论名称如何,所需的内容都是相同的:

// vue-file-import.d.ts

declare module "*.vue" {
   import Vue from "vue";
   export default Vue;
}

尝试不同的垫片文件位置

本来我把它放在

/src
。我发现这有一个奇怪的效果。有时它会起作用,即 VS Code 错误消息消失了;有时却没有出现,它们又出现了。当我在项目中移动编辑不同的文件时,这种情况会动态发生。

我后来找到了内容相同的填充文件的建议,但放置在

/typings
中。我尝试过这个并且它一直有效。其他人似乎对
/src
的位置很满意。


9
投票

您应该声明导入 *.vue 文件。

如:

vue-文件导入.d.ts

declare module "*.vue" {
   import Vue from "vue";
   export default Vue;
}

8
投票

有同样的问题。 解决方案是为每个计算变量添加返回类型。

从此代码发出,没有返回类型。

      computed: {
containerClass() {
    return this.isLastChild
  }

添加返回类型String。

  computed: {
containerClass(): String {
    return this.isLastChild
  }

6
投票

@sherwin water 的回答对我帮助很大。我意识到,一旦添加

computed
字段,就会出现错误。解决方案很简单:为计算字段添加返回类型。

// wrong
computed: {
  someThing() {
    const { a, b } = this;
    return a + b;
  }
}

// correct
computed: {
  someThing(): number {
    const { a, b } = this;
    return a + b;
  }
}

2
投票

我试图关注此页面https://v2.vuejs.org/v2/guide/routing.html并且遇到相同的TypeScript错误,我通过将Vue实例强制转换为类似这样的类型来修复它

    new Vue({
        el: '#app',
        data: {
            currentRoute: window.location.pathname
        },
        computed: {
            ViewComponent() {
                return routes[(this as any).currentRoute] || routes['/']
            }
        },
        render (h) { return h((this as any).ViewComponent) }
    })

1
投票

我建议在使用 TypeScript 时使用基于类的组件(查看“使用 Vue.js 和 TypeScript 编写基于类的组件”)。这是获得类型安全代码并使用 IDE 的自动完成功能的唯一方法

您需要安装vue-property-decorator

这是基于类的组件的示例:

import { Component, Vue, Watch } from 'vue-property-decorator'

@Component({
  props: {
    prop1: { type: Number }
  }
})
export default class MyComponent extends Vue {
  // This is how you define computed
  get myComputedRoute() {
     return this.$route.params;
  }

  @Watch('myComputedRoute')
  onPropertyChanged(value: string, oldValue: string) {
    // Do stuff with the watcher here.
  }
}

1
投票

如果您使用的是 typescript 和 vue2,您应该使用

Vue.component
Vue.extend
来定义组件。

import Vue from 'vue'
const Component = Vue.extend({
  ...
})


0
投票

我遇到了类似的问题(尤其是在 .vue 文件中)。不过,我确实发现这似乎解决了问题。无论您在何处导入 .vue 文件,请将 ES6 样式“import”更改为“require”。

因此,在您的示例中,更改:

import Competency from '../components/competency.vue';

到...

declare var require: any;
var Competency = require("../components/competency.vue").default;

0
投票

我在 vue 2.8.2 和 Typescript 2.5.3 中遇到了同样的错误。我通过将 Vue 实例保存在变量中然后给它一个类型来修复它。这确保当您使用选项对象实例化 TS 时,TS 将了解所有 Vue 属性。

var VueApp: any = Vue;

var App = new VueApp({
  el: "#app",
  data() {
     return {
        count: 0
     }
  },
  methods:{
    initialize() {
      this.count = count + 1; // Should work now
    }
  }
})


0
投票

请勿使用任何

使用

Object.assign(vm, source);
代替

喜欢

const source= {count: this.count }
Object.assign(this, source);

0
投票

我在使用 VS Code 编辑器时遇到此错误。

我在 vs code 上安装了 Vetur 插件,Vetur 将 vue 文件处理为 typescript 文件,所以我将其修复为编辑 settings.json 文件

请在项目根目录下的 VS 编辑器中找到此文件,然后进行如下设置更改

"vetur.experimental.templateInterpolationService": false

它对我有用


0
投票

在 VSCode 中,我通过完全退出 VSCode 并再次打开它来解决这个问题。


-1
投票

尝试使用 Typescript 的泛型。请参阅https://www.typescriptlang.org/docs/handbook/generics.html

new Vue<{ count: number }, { initialize: () => void }, {}, {}>({

  //...

  data:{
    count: 0
  },

  methods:{
    initialize: function() {
      this.count = count + 1;
    },
  }
});
© www.soinside.com 2019 - 2024. All rights reserved.